import React, { useState, useEffect, useMemo } from 'react';
import { AuthSession, RecoverySession, clearAuthActionFromUrl, getRecoverySessionFromUrl, getStoredSession, refreshSession, signOut } from './services/supabaseAuth';
import { fetchGoogleSheetsData, DEFAULT_SPREADSHEET_ID, FetchResult, mergeAuditData } from './services/googleSheets';
import { FilterState, MergedStoreAudit, DashboardKPIs, Store } from './types';
import { extractWeekOptions, isDateInWeek, isItemInWeek } from './utils/dateUtils';

import { Header } from './components/Header';
import { FilterBar } from './components/FilterBar';
import { KPICards } from './components/KPICards';
import { AuditStep1Presencia } from './components/AuditStep1Presencia';
import { AuditStep2Exhibicion } from './components/AuditStep2Exhibicion';
import { AuditStep3Estante } from './components/AuditStep3Estante';
import { AuditStep4Inventario } from './components/AuditStep4Inventario';
import { StoreTable } from './components/StoreTable';
import { StoreAuditModal } from './components/StoreAuditModal';
import { SyncSheetModal } from './components/SyncSheetModal';
import { ClientTutorialModal } from './components/ClientTutorialModal';
import { AuthScreen } from './components/AuthScreen';

import { LayoutDashboard, Eye, MapPin, BarChart3, PackageCheck, Table, AlertCircle, LoaderCircle, Zap } from 'lucide-react';

// Helper to deduplicate stores strictly by Customer Name (Store Name)
function getUniqueStores(stores: Store[]): Store[] {
  const map = new Map<string, Store>();
  stores.forEach(s => {
    if (!s.customer || !s.customer.trim()) return;
    const key = s.customer.trim().toLowerCase();
    if (!map.has(key)) {
      map.set(key, s);
    } else {
      const existing = map.get(key)!;
      if (!existing.assignedDate && s.assignedDate) {
        map.set(key, s);
      }
    }
  });
  return Array.from(map.values());
}

export default function App() {
  const [authSession, setAuthSession] = useState<AuthSession | null>(null);
  const [authLoading, setAuthLoading] = useState(true);
  const [recoverySession, setRecoverySession] = useState<RecoverySession | null>(null);
  const [recoveryError, setRecoveryError] = useState('');
  const [spreadsheetId, setSpreadsheetId] = useState(DEFAULT_SPREADSHEET_ID);
  const [isSyncing, setIsSyncing] = useState(false);

  const [dataResult, setDataResult] = useState<FetchResult | null>(null);
  const [activeTab, setActiveTab] = useState<'overview' | 'step1' | 'step2' | 'step3' | 'step4' | 'table'>('overview');

  const [selectedAuditItem, setSelectedAuditItem] = useState<MergedStoreAudit | null>(null);
  const [isSheetModalOpen, setIsSheetModalOpen] = useState(false);
  const [isTutorialOpen, setIsTutorialOpen] = useState(false);

  // Filters State
  const [filters, setFilters] = useState<FilterState>({
    zone: 'all',
    channel: 'all',
    customer: 'all',
    status: 'all',
    oosStatus: 'all',
    selectedWeek: 'all',
    search: ''
  });

  // Supabase email/password session initialization
  useEffect(() => {
    let mounted = true;

    const initializeAuth = async () => {
      try {
        const recovery = await getRecoverySessionFromUrl();
        if (recovery.session || recovery.error) {
          if (recovery.error) clearAuthActionFromUrl();
          if (mounted) {
            setRecoverySession(recovery.session);
            setRecoveryError(recovery.error);
            setAuthSession(null);
            setAuthLoading(false);
          }
          return;
        }

        const storedSession = await getStoredSession();
        if (mounted) {
          setAuthSession(storedSession);
          setAuthLoading(false);
        }
      } catch (error) {
        console.error('Unable to restore the authentication session:', error);
        if (mounted) {
          setAuthSession(null);
          setRecoverySession(null);
          setRecoveryError('');
          setAuthLoading(false);
        }
      }
    };

    initializeAuth();
    return () => {
      mounted = false;
    };
  }, []);

  const loadData = async (spId: string) => {
    setIsSyncing(true);
    try {
      const res = await fetchGoogleSheetsData(spId, null);
      setDataResult(res);
    } catch (e) {
      console.error('Error loading data:', e);
    } finally {
      setIsSyncing(false);
    }
  };

  useEffect(() => {
    if (authSession && !recoverySession && !dataResult) {
      loadData(spreadsheetId);
    }
  }, [authSession, recoverySession]);

  useEffect(() => {
    if (!authSession) return;

    const refreshIn = Math.max(30_000, (authSession.expires_at * 1000) - Date.now() - 60_000);
    const timer = window.setTimeout(async () => {
      const refreshed = await refreshSession(authSession);
      if (refreshed) {
        setAuthSession(refreshed);
      } else {
        setAuthSession(null);
        setDataResult(null);
      }
    }, refreshIn);

    return () => window.clearTimeout(timer);
  }, [authSession]);

  const handleRefresh = () => {
    loadData(spreadsheetId);
  };

  const handleResetFilters = () => {
    setFilters({
      zone: 'all',
      channel: 'all',
      customer: 'all',
      status: 'all',
      oosStatus: 'all',
      selectedWeek: 'all',
      search: ''
    });
  };

  // Extract week options for Monday - Sunday selection
  const weekOptions = useMemo(() => {
    if (!dataResult) return [];
    return extractWeekOptions(dataResult.stores, dataResult.responses);
  }, [dataResult]);

  // Auto-select initial active week when weekOptions load
  useEffect(() => {
    if (weekOptions.length > 0 && filters.selectedWeek === 'all') {
      const target = weekOptions.find(w => w.key.includes('2026-07-20')) || weekOptions[0];
      setFilters(prev => ({ ...prev, selectedWeek: target.key }));
    }
  }, [weekOptions]);

  // Compute Base Merged Items according to selectedWeek filter
  const baseMergedData = useMemo(() => {
    if (!dataResult) return [];

    const { stores, responses } = dataResult;
    const selectedWeek = filters.selectedWeek || 'all';

    if (selectedWeek !== 'all') {
      // Filter stores by 'week' column or assignedDate falling in selectedWeek
      const weekStores = stores.filter(s => isItemInWeek(s.week, s.assignedDate, selectedWeek));
      const uniqueWeekStores = getUniqueStores(weekStores);

      // Distinct count of stores from 'tiendas' sheet for this week
      const targetStores = uniqueWeekStores.length > 0 ? uniqueWeekStores : getUniqueStores(stores);

      // Filter responses by 'week' column or submissionDate falling in selectedWeek
      const weekResponses = responses.filter(r => isItemInWeek(r.week, r.submissionDate, selectedWeek));

      return mergeAuditData(targetStores, weekResponses);
    } else {
      // All weeks selected: deduplicate stores strictly by Customer name
      const uniqueStores = getUniqueStores(stores);
      return mergeAuditData(uniqueStores, responses);
    }
  }, [dataResult, filters.selectedWeek]);

  // Filtered Merged Items
  const filteredMergedData = useMemo(() => {
    return baseMergedData.filter(item => {
      // Zone
      if (filters.zone !== 'all' && item.store.zone !== filters.zone) return false;
      // Channel
      if (filters.channel !== 'all' && item.store.customerChannel !== filters.channel) return false;
      // Customer
      if (filters.customer !== 'all' && item.store.customer !== filters.customer) return false;
      // Audit Status
      if (filters.status !== 'all' && item.status !== filters.status) return false;
      // OOS Status
      if (filters.oosStatus === 'Available' && item.response?.isAvailable !== 'Yes') return false;
      if (filters.oosStatus === 'OOS' && item.response?.isAvailable !== 'No') return false;

      // Search Query
      if (filters.search.trim()) {
        const q = filters.search.toLowerCase().trim();
        const matchesCode = item.store.customerCode.toLowerCase().includes(q);
        const matchesName = item.store.customer.toLowerCase().includes(q);
        if (!matchesCode && !matchesName) return false;
      }

      return true;
    });
  }, [baseMergedData, filters]);

  // Dashboard KPIs Calculation
  const kpis: DashboardKPIs = useMemo(() => {
    const totalStores = filteredMergedData.length;
    const visitedItems = filteredMergedData.filter(m => m.status === 'Visited');
    const visitedStores = visitedItems.length;
    const pendingStores = totalStores - visitedStores;

    const complianceRate = totalStores > 0 ? (visitedStores / totalStores) * 100 : 0;

    // Total raw response submissions matching the filtered stores in the active week
    const activeResponses = (filters.selectedWeek && filters.selectedWeek !== 'all')
      ? (dataResult?.responses || []).filter(r => r.submissionDate && isDateInWeek(r.submissionDate, filters.selectedWeek))
      : (dataResult?.responses || []);

    let totalResponses = visitedStores;
    if (activeResponses.length > 0) {
      const storeNamesSet = new Set(filteredMergedData.map(m => m.store.customer.toLowerCase().trim()));
      const matchingResponses = activeResponses.filter(r => r.customer && storeNamesSet.has(r.customer.toLowerCase().trim()));
      if (matchingResponses.length > 0) {
        totalResponses = matchingResponses.length;
      }
    }

    // Available and Out of Stock stores in filtered dataset
    const availableStores = visitedItems.filter(m => m.response?.isAvailable === 'Yes').length;
    const oosStores = visitedItems.filter(m => m.response?.isAvailable === 'No').length;

    // Denominator for rates based on visited stores
    const denominator = visitedStores > 0 ? visitedStores : totalStores;
    const oosRate = denominator > 0 ? (oosStores / denominator) * 100 : 0;
    const numericDistribution = denominator > 0 ? (availableStores / denominator) * 100 : 0;

    let totalPhysicalInventory = 0;
    let totalUnitsSoldIn = 0;
    let priceSum = 0;
    let priceCount = 0;
    let facingsSum = 0;
    let totalIceKickFacings = 0;
    let totalLucozadeFacings = 0;
    let totalCategoryFacings = 0;

    const visitedAvailableStores = filteredMergedData.filter(m => m.status === 'Visited' && m.response?.isAvailable === 'Yes');

    filteredMergedData.forEach(item => {
      totalUnitsSoldIn += item.store.unitsSoldIn || 0;
      if (item.response) {
        totalPhysicalInventory += item.response.totalPhysicalInventory || 0;
      }
    });

    visitedAvailableStores.forEach(item => {
      if (item.response) {
        if (item.response.retailPrice && item.response.retailPrice > 0) {
          priceSum += item.response.retailPrice;
          priceCount++;
        }
        facingsSum += item.response.facingsIceKick || 0;
        totalIceKickFacings += item.response.facingsIceKick || 0;
        totalLucozadeFacings += item.response.facingsLucozadeBrand || 0;
        totalCategoryFacings += item.response.facingsCategoryTotal || 0;
      }
    });

    const avgRetailPrice = priceCount > 0 ? priceSum / priceCount : 0;
    const avgIceKickFacings = visitedStores > 0 ? facingsSum / visitedStores : 0;
    const avgBrandShelfShare = totalLucozadeFacings > 0 ? (totalIceKickFacings / totalLucozadeFacings) * 100 : 0;
    const avgCategoryShelfShare = totalCategoryFacings > 0 ? (totalLucozadeFacings / totalCategoryFacings) * 100 : 0;

    // Placement & Additional Exhibition Metrics (Secondary Display & Gondola End)
    let mainShelfStores = 0;
    let secondaryDisplayStores = 0;
    let gondolaEndStores = 0;
    let additionalExhibitionStores = 0;

    visitedItems.forEach(m => {
      const loc = (m.response?.placementLocation || '').toLowerCase();
      const hasMain = loc.includes('main') || loc.includes('shelf') || loc.includes('estante');
      const hasSecondary = loc.includes('secondary') || loc.includes('secundaria') || loc.includes('exhibici') || loc.includes('display');
      const hasGondola = loc.includes('gondola') || loc.includes('góndola') || loc.includes('end') || loc.includes('cabecera') || loc.includes('endcap');

      if (hasMain) mainShelfStores++;
      if (hasSecondary) secondaryDisplayStores++;
      if (hasGondola) gondolaEndStores++;
      if (hasSecondary || hasGondola) additionalExhibitionStores++;
    });

    const mainShelfRate = denominator > 0 ? (mainShelfStores / denominator) * 100 : 0;
    const secondaryDisplayRate = denominator > 0 ? (secondaryDisplayStores / denominator) * 100 : 0;
    const gondolaEndRate = denominator > 0 ? (gondolaEndStores / denominator) * 100 : 0;
    const additionalExhibitionRate = denominator > 0 ? (additionalExhibitionStores / denominator) * 100 : 0;

    let totalSellOutUnits = 0;
    let totalSellOutValue = 0;

    visitedItems.forEach(item => {
      const inv = item.response?.totalPhysicalInventory || 0;
      const price = item.response?.retailPrice || 0;
      const sellIn = item.store.unitsSoldIn || 0;
      const sellOutUnits = Math.max(0, sellIn - inv);
      const valSellOut = sellOutUnits * price;

      totalSellOutUnits += sellOutUnits;
      totalSellOutValue += valSellOut;
    });

    return {
      totalStores,
      totalResponses,
      visitedStores,
      pendingStores,
      complianceRate,
      oosStores,
      availableStores,
      oosRate,
      numericDistribution,
      totalPhysicalInventory,
      totalUnitsSoldIn,
      totalSellOutUnits,
      totalSellOutValue,
      avgRetailPrice,
      avgIceKickFacings,
      avgBrandShelfShare,
      avgCategoryShelfShare,
      mainShelfStores,
      secondaryDisplayStores,
      gondolaEndStores,
      additionalExhibitionStores,
      mainShelfRate,
      secondaryDisplayRate,
      gondolaEndRate,
      additionalExhibitionRate
    };
  }, [filteredMergedData, dataResult]);

  if (authLoading) {
    return (
      <div className="min-h-screen bg-slate-50 flex items-center justify-center">
        <div className="flex flex-col items-center gap-3 text-sky-700">
          <div className="w-12 h-12 rounded-2xl bg-gradient-to-br from-sky-500 to-blue-600 flex items-center justify-center shadow-lg">
            <Zap className="w-5 h-5 fill-amber-300 text-amber-300" />
          </div>
          <LoaderCircle className="w-5 h-5 animate-spin" />
        </div>
      </div>
    );
  }

  if (!authSession || recoverySession || recoveryError) {
    return (
      <AuthScreen
        recoverySession={recoverySession}
        recoveryError={recoveryError}
        onAuthenticated={session => {
          setAuthSession(session);
          setRecoverySession(null);
          setRecoveryError('');
          setDataResult(null);
        }}
        onRecoveryComplete={() => {
          clearAuthActionFromUrl();
          setRecoverySession(null);
          setRecoveryError('');
          setAuthSession(null);
          setDataResult(null);
        }}
      />
    );
  }

  const allStores = dataResult?.stores || [];

  const handleLogout = async () => {
    await signOut(authSession);
    setAuthSession(null);
    setDataResult(null);
    setRecoverySession(null);
    setRecoveryError('');
  };

  return (
    <div className="min-h-screen bg-slate-50 text-slate-800 font-sans flex flex-col">
      
      {/* Header */}
      <Header
        lastSynced={dataResult?.lastSynced || 'Just now'}
        isSyncing={isSyncing}
        onRefresh={handleRefresh}
        onOpenTutorial={() => setIsTutorialOpen(true)}
        userEmail={authSession.user.email || 'Signed in'}
        onLogout={handleLogout}
      />

      <main className="flex-1 max-w-7xl w-full mx-auto px-4 sm:px-6 lg:px-8 py-6 space-y-6">
        
        {/* Error notification if sync fails */}
        {dataResult?.error && (
          <div className="bg-amber-50 border border-amber-200 text-amber-900 px-4 py-3 rounded-2xl text-xs flex items-center justify-between">
            <div className="flex items-center gap-2">
              <AlertCircle className="w-4 h-4 text-amber-600 shrink-0" />
              <span>{dataResult.error}</span>
            </div>
            <button
              onClick={() => setIsSheetModalOpen(true)}
              className="text-xs font-extrabold underline text-amber-800 hover:text-amber-950 cursor-pointer"
            >
              Configure Google Sheet
            </button>
          </div>
        )}

        {/* Global Filter Bar */}
        <FilterBar
          filters={filters}
          stores={allStores}
          weekOptions={weekOptions}
          onChange={setFilters}
          onReset={handleResetFilters}
        />

        {/* KPI Cards Grid */}
        <KPICards kpis={kpis} />

        {/* Audit Step Tabs Navigation */}
        <div className="bg-white/95 backdrop-blur-md rounded-2xl border border-sky-100 p-1.5 flex flex-wrap gap-1.5 shadow-xs sticky top-[172px] sm:top-[175px] z-20">
          
          <button
            onClick={() => setActiveTab('overview')}
            className={`flex-1 sm:flex-none inline-flex items-center justify-center gap-2 px-4 py-2 rounded-xl text-xs font-bold transition-all cursor-pointer ${
              activeTab === 'overview'
                ? 'bg-amber-100 text-amber-950 border border-amber-200/80 shadow-2xs font-figtree'
                : 'text-slate-500 hover:text-slate-900 hover:bg-sky-50'
            }`}
          >
            <LayoutDashboard className="w-3.5 h-3.5 text-amber-800" />
            <span>Overview</span>
          </button>

          <button
            onClick={() => setActiveTab('step1')}
            className={`flex-1 sm:flex-none inline-flex items-center justify-center gap-2 px-4 py-2 rounded-xl text-xs font-bold transition-all cursor-pointer ${
              activeTab === 'step1'
                ? 'bg-amber-100 text-amber-950 border border-amber-200/80 shadow-2xs font-figtree'
                : 'text-slate-500 hover:text-slate-900 hover:bg-sky-50'
            }`}
          >
            <Eye className="w-3.5 h-3.5 text-amber-800" />
            <span>Step 1: Presence (OOS)</span>
            {kpis.oosStores > 0 && (
              <span className="bg-rose-600 text-white text-[10px] font-black px-2 py-0.5 rounded-full">
                {kpis.oosStores}
              </span>
            )}
          </button>

          <button
            onClick={() => setActiveTab('step2')}
            className={`flex-1 sm:flex-none inline-flex items-center justify-center gap-2 px-4 py-2 rounded-xl text-xs font-bold transition-all cursor-pointer ${
              activeTab === 'step2'
                ? 'bg-amber-100 text-amber-950 border border-amber-200/80 shadow-2xs font-figtree'
                : 'text-slate-500 hover:text-slate-900 hover:bg-sky-50'
            }`}
          >
            <MapPin className="w-3.5 h-3.5 text-amber-800" />
            <span>Step 2: Location & POP</span>
          </button>

          <button
            onClick={() => setActiveTab('step3')}
            className={`flex-1 sm:flex-none inline-flex items-center justify-center gap-2 px-4 py-2 rounded-xl text-xs font-bold transition-all cursor-pointer ${
              activeTab === 'step3'
                ? 'bg-amber-100 text-amber-950 border border-amber-200/80 shadow-2xs font-figtree'
                : 'text-slate-500 hover:text-slate-900 hover:bg-sky-50'
            }`}
          >
            <BarChart3 className="w-3.5 h-3.5 text-amber-800" />
            <span>Step 3: Shelf & Share</span>
          </button>

          <button
            onClick={() => setActiveTab('step4')}
            className={`flex-1 sm:flex-none inline-flex items-center justify-center gap-2 px-4 py-2 rounded-xl text-xs font-bold transition-all cursor-pointer ${
              activeTab === 'step4'
                ? 'bg-amber-100 text-amber-950 border border-amber-200/80 shadow-2xs font-figtree'
                : 'text-slate-500 hover:text-slate-900 hover:bg-sky-50'
            }`}
          >
            <PackageCheck className="w-3.5 h-3.5 text-amber-800" />
            <span>Step 4: Inventory & Backroom</span>
          </button>

          <button
            onClick={() => setActiveTab('table')}
            className={`flex-1 sm:flex-none inline-flex items-center justify-center gap-2 px-4 py-2 rounded-xl text-xs font-extrabold transition-all cursor-pointer ${
              activeTab === 'table'
                ? 'bg-sky-100 text-sky-950 shadow-2xs'
                : 'text-slate-500 hover:text-slate-900 hover:bg-sky-50'
            }`}
          >
            <Table className="w-3.5 h-3.5" />
            <span>Store Table</span>
          </button>

        </div>

        {/* Tab Content Display */}
        {activeTab === 'overview' && (
          <div className="space-y-6">
            <AuditStep1Presencia
              mergedData={filteredMergedData}
              onSelectStore={item => setSelectedAuditItem(item)}
            />
            <StoreTable
              mergedData={filteredMergedData}
              onSelectStore={item => setSelectedAuditItem(item)}
            />
          </div>
        )}

        {activeTab === 'step1' && (
          <AuditStep1Presencia
            mergedData={filteredMergedData}
            onSelectStore={item => setSelectedAuditItem(item)}
          />
        )}

        {activeTab === 'step2' && (
          <AuditStep2Exhibicion
            mergedData={filteredMergedData}
            onSelectStore={item => setSelectedAuditItem(item)}
          />
        )}

        {activeTab === 'step3' && (
          <AuditStep3Estante
            mergedData={filteredMergedData}
            onSelectStore={item => setSelectedAuditItem(item)}
          />
        )}

        {activeTab === 'step4' && (
          <AuditStep4Inventario
            mergedData={filteredMergedData}
            onSelectStore={item => setSelectedAuditItem(item)}
          />
        )}

        {activeTab === 'table' && (
          <StoreTable
            mergedData={filteredMergedData}
            onSelectStore={item => setSelectedAuditItem(item)}
          />
        )}

      </main>



      {/* Audit Detail Modal */}
      <StoreAuditModal
        item={selectedAuditItem}
        onClose={() => setSelectedAuditItem(null)}
      />

      {/* Google Sheets Config Modal */}
      <SyncSheetModal
        isOpen={isSheetModalOpen}
        currentSpreadsheetId={spreadsheetId}
        source={dataResult?.source || 'fallback_demo'}
        error={dataResult?.error}
        onClose={() => setIsSheetModalOpen(false)}
        onUpdateSpreadsheetId={newId => {
          setSpreadsheetId(newId);
          loadData(newId);
        }}
      />

      {/* Client PPT Presentation / Tutorial Deck Modal */}
      <ClientTutorialModal
        isOpen={isTutorialOpen}
        onClose={() => setIsTutorialOpen(false)}
      />

    </div>
  );
}
