
import React, { useState, useMemo, useEffect, useCallback } from 'react';
import FileUpload from './components/FileUpload';
import Dashboard from './components/Dashboard';
import DataGrid from './components/DataGrid';
import TopMovers from './components/TopMovers';
import FilterBar from './components/FilterBar';
import AIChat from './components/AIChat';
import CrazeLogo from './components/CrazeLogo';
import { SalesRecord, FilterState, AggregatedData } from './types';
import { processCSV, filterData, aggregateData, getUniqueValues } from './services/dataProcessor';
import { queryGemini } from './services/geminiService';
import { ChartIcon, TableIcon, UploadIcon, DownloadIcon, CloseIcon, TrendingIcon } from './components/Icons';
import { loadSalesData, saveSalesData, clearSalesData } from './services/storage';

// New Refresh Icon
const RefreshIcon = ({ className }: { className?: string }) => (
  <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className={className || "w-5 h-5"}>
    <path strokeLinecap="round" strokeLinejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0 3.181 3.183a8.25 8.25 0 0 0 13.803-3.7M4.031 9.865a8.25 8.25 0 0 1 13.803-3.7l3.181 3.182m0-4.991v4.99" />
  </svg>
);

// Hardcoded Permanent URL for Auto-Loading
// Using the original share link to leverage Dropbox's redirect for robust fetching.
const PERMANENT_DROPBOX_URL = "https://www.dropbox.com/scl/fi/b9zxn4z5i7sxwfakk5g5y/Amazon-Sell-Out-2023-2025.csv?rlkey=uoto6v0mm99py8nszy8ldtez8&dl=0";

const App: React.FC = () => {
  const [rawData, setRawData] = useState<SalesRecord[]>([]);
  const [loading, setLoading] = useState(true); 
  const [syncing, setSyncing] = useState(false); 
  const [view, setView] = useState<'dashboard' | 'table' | 'movers'>('dashboard');
  const [isChatOpen, setIsChatOpen] = useState(false);
  const [activeUrl, setActiveUrl] = useState<string | null>(() => localStorage.getItem('craze_csv_url') || PERMANENT_DROPBOX_URL);
  const [lastUpdated, setLastUpdated] = useState<string | null>(null);

  // Modal State
  const [isDataModalOpen, setIsDataModalOpen] = useState(false);

  // Filters State
  const [filters, setFilters] = useState<FilterState>({
    customer: [],
    year: [],
    month: [],
    line: [],
    asin: [],
    sku: [],
    title: [],
  });

  // Handle URL Fetch (Auto/Manual)
  const handleUrlFetch = useCallback(async (url: string) => {
      setSyncing(true);
      try {
          let directUrl = url;
          // Create a direct download link for Dropbox if it's a share link.
          if (url.includes('dropbox.com/') && !url.includes('dl.dropboxusercontent.com')) {
              const urlObject = new URL(url);
              urlObject.searchParams.set('dl', '1');
              directUrl = urlObject.toString();
          }

          // Use a CORS proxy to bypass browser's same-origin policy restrictions.
          // This is necessary because Dropbox does not send the required CORS headers
          // for direct client-side fetching from another domain.
          const proxyUrl = `https://corsproxy.io/?${encodeURIComponent(directUrl)}`;

          const response = await fetch(proxyUrl);
          if (!response.ok) throw new Error(`Failed to fetch CSV from URL: ${response.status} ${response.statusText}`);
          
          const csvText = await response.text();
          const data = await processCSV(csvText);
          
          await saveSalesData(data); 
          
          initializeData(data);
          setActiveUrl(url); // Store the original user-facing URL
          const now = new Date().toISOString();
          setLastUpdated(now);
          localStorage.setItem('craze_last_updated', now);
          localStorage.setItem('craze_csv_url', url); 
          setIsDataModalOpen(false); // Close modal on success
      } catch (error) {
          console.error("Failed to fetch/parse CSV from URL", error);
          // Don't alert on auto-fetch to avoid spamming the user on startup if offline
          // alert("Error syncing data. Please check the URL.");
          throw error; // re-throw to be caught by caller
      } finally {
          setSyncing(false);
          setLoading(false);
      }
  }, []);

  const initializeData = (data: SalesRecord[]) => {
      setRawData(data);
      setFilters({
        customer: [],
        year: [],
        month: [],
        line: [],
        asin: [],
        sku: [],
        title: [],
      });
  };

  // 1. Initial Load from Cache (IndexedDB) or Auto-Fetch Permanent URL
  useEffect(() => {
    const initApp = async () => {
        setLoading(true);
        
        const currentStoredUrl = localStorage.getItem('craze_csv_url');
        if (currentStoredUrl !== PERMANENT_DROPBOX_URL) {
            localStorage.setItem('craze_csv_url', PERMANENT_DROPBOX_URL);
            setActiveUrl(PERMANENT_DROPBOX_URL);
        }

        const { data, lastUpdated: date } = await loadSalesData();
        
        if (data && data.length > 0) {
            console.log("Loaded data from cache:", data.length, "rows");
            initializeData(data);
            setLastUpdated(date);
            setLoading(false);
        } else {
            console.log("No cache found. Auto-fetching from Permanent URL...");
            handleUrlFetch(PERMANENT_DROPBOX_URL).catch(e => {
                console.error("Initial fetch failed.");
            });
        }
    };
    initApp();
  }, [handleUrlFetch]);

  // Handle uploaded file (Manual)
  const handleFileUpload = async (file: File) => {
    setSyncing(true);
    try {
      const data = await processCSV(file);
      await saveSalesData(data);
      initializeData(data);
      setLastUpdated(new Date().toISOString());
      setIsDataModalOpen(false);
    } catch (error) {
      console.error("Failed to parse CSV", error);
      alert("Error parsing CSV. Please check the format.");
    } finally {
      setSyncing(false);
    }
  };

  // 2. Schedule Auto-Refresh (Background)
  useEffect(() => {
      const checkAndRefresh = () => {
          const now = new Date();
          const today = now.toISOString().split('T')[0]; // YYYY-MM-DD
          const lastRefreshDate = localStorage.getItem('craze_last_refresh_date');

          // Refresh if it's after 7 AM and we haven't refreshed today
          if (now.getHours() >= 7 && lastRefreshDate !== today) {
              console.log("Triggering daily data refresh...");
              handleUrlFetch(PERMANENT_DROPBOX_URL).then(() => {
                  localStorage.setItem('craze_last_refresh_date', today);
                  console.log("Daily refresh successful.");
              }).catch(err => {
                  console.error("Daily refresh failed, will retry later.", err);
              });
          }
      };
      
      // Check immediately on load in case the user opens the app after 7 AM
      checkAndRefresh();

      // And then check periodically (e.g., every 15 minutes) in case app is left open across midnight
      const interval = setInterval(checkAndRefresh, 15 * 60 * 1000); 

      return () => clearInterval(interval);
  }, [handleUrlFetch]);


  // Derive Data
  const filteredData = useMemo(() => filterData(rawData, filters), [rawData, filters]);
  const aggregatedData = useMemo(() => aggregateData(filteredData), [filteredData]);

  // Derive Context Data (Product Line Context when drilling down)
  const contextAggregatedData = useMemo(() => {
    // Check if we are filtering by specific items (SKU, ASIN, Title)
    const hasItemFilters = filters.sku.length > 0 || filters.asin.length > 0 || filters.title.length > 0;

    if (!hasItemFilters || filteredData.length === 0) {
      return null;
    }

    // 1. Identify the Product Lines associated with the currently filtered items
    const activeLines = Array.from(new Set(filteredData.map(r => r.line)));

    // 2. Create a "broad" filter: Keep Year/Customer/Month, but CLEAR Item filters, and restrict to these Lines
    const contextFilters: FilterState = {
      ...filters,
      line: activeLines, // Force these lines
      sku: [],          // Clear specific item filters
      asin: [],
      title: []
    };

    // 3. Process this broader dataset
    const broadData = filterData(rawData, contextFilters);
    return aggregateData(broadData);

  }, [rawData, filters, filteredData]);


  // Derive Options for Filter Dropdowns
  const filterOptions = useMemo(() => {
    return {
      customer: getUniqueValues(rawData, 'customer'),
      year: getUniqueValues(rawData, 'year'),
      month: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
      line: getUniqueValues(rawData, 'line'),
      asin: getUniqueValues(rawData, 'asin'),
      sku: getUniqueValues(rawData, 'sku'),
      title: getUniqueValues(rawData, 'title'),
    };
  }, [rawData]);

  const handleFilterChange = (key: keyof FilterState, value: string[]) => {
    setFilters(prev => ({ ...prev, [key]: value }));
  };

  const handleAskGemini = async (text: string) => {
    return await queryGemini(text, aggregatedData, filteredData.length);
  };

  const disconnectUrl = async () => {
      // Allow disconnecting to clear data, but the app will likely re-connect on next reload due to "Permanent" requirement
      localStorage.removeItem('craze_csv_url');
      await clearSalesData();
      setActiveUrl(null);
      setRawData([]);
  };

  return (
    <div className="min-h-screen flex flex-col bg-background text-slate-200">
      
      {/* Header */}
      <header className="bg-slate-950/90 backdrop-blur border-b border-border py-4 px-6 relative z-40 shadow-2xl">
        <div className="max-w-7xl mx-auto flex justify-between items-center">
          <div className="flex items-center gap-8">
             {/* Logo Container (Horizontal Box) - Persistent User Image */}
             <div className="h-16 w-64 relative flex-shrink-0">
                 <CrazeLogo />
             </div>

             {/* Title & Status */}
             <div className="hidden lg:block border-l border-slate-700 pl-6">
                 <h1 className="text-xl font-bold tracking-tight text-white text-shadow-sm">Analytics Dashboard</h1>
                 {activeUrl && lastUpdated && (
                     <p className="text-[10px] text-emerald-400 mt-1 flex items-center gap-1 uppercase font-bold tracking-wider">
                         <span className="w-1.5 h-1.5 rounded-full bg-emerald-400 animate-pulse"></span>
                         Live Sync Active
                     </p>
                 )}
             </div>
          </div>
          
          <div className="flex items-center gap-4">
            
            {/* Main Action: Data Source Button */}
            <button 
                onClick={() => setIsDataModalOpen(true)}
                className={`flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-bold shadow-lg transition-all border
                ${activeUrl 
                    ? 'bg-slate-800 text-emerald-400 border-emerald-500/50 hover:bg-slate-700' 
                    : 'bg-indigo-600 text-white border-transparent hover:bg-indigo-500'}`}
            >
                {syncing ? <div className="w-4 h-4 border-2 border-current border-t-transparent rounded-full animate-spin"></div> : <UploadIcon />}
                <span className="hidden md:inline">{activeUrl ? 'Data Settings' : 'Connect Data'}</span>
            </button>

            {/* NEW REFRESH BUTTON */}
            <button
                onClick={() => activeUrl && handleUrlFetch(activeUrl)}
                disabled={syncing}
                title="Refresh Data"
                className="p-3 rounded-lg bg-slate-800 border border-border text-slate-400 hover:text-white hover:bg-slate-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
            >
                <RefreshIcon className={`w-5 h-5 ${syncing ? 'animate-spin' : ''}`} />
            </button>

            {/* View Switcher */}
            <div className="flex bg-slate-900 rounded-lg p-1 border border-border">
                <button 
                  onClick={() => setView('dashboard')}
                  className={`flex items-center gap-2 px-4 py-2 rounded-md text-sm font-medium transition-all
                  ${view === 'dashboard' ? 'bg-slate-800 text-white shadow-sm ring-1 ring-white/10' : 'text-slate-400 hover:text-white hover:bg-slate-800/50'}`}
                >
                  <ChartIcon /> <span className="hidden sm:inline">Dashboard</span>
                </button>
                <button 
                  onClick={() => setView('table')}
                  className={`flex items-center gap-2 px-4 py-2 rounded-md text-sm font-medium transition-all
                  ${view === 'table' ? 'bg-slate-800 text-white shadow-sm ring-1 ring-white/10' : 'text-slate-400 hover:text-white hover:bg-slate-800/50'}`}
                >
                  <TableIcon /> <span className="hidden sm:inline">Data Grid</span>
                </button>
                 <button 
                  onClick={() => setView('movers')}
                  className={`flex items-center gap-2 px-4 py-2 rounded-md text-sm font-medium transition-all
                  ${view === 'movers' ? 'bg-slate-800 text-white shadow-sm ring-1 ring-white/10' : 'text-slate-400 hover:text-white hover:bg-slate-800/50'}`}
                >
                  <TrendingIcon /> <span className="hidden sm:inline">Top Movers</span>
                </button>
            </div>
          </div>
        </div>
      </header>

      {/* Main Content */}
      <main className="flex-1 relative">
        {loading ? (
            // Initial loading spinner
            <div className="flex flex-col items-center justify-center h-[80vh] gap-4">
                <div className="w-16 h-16 border-4 border-indigo-500 border-t-transparent rounded-full animate-spin"></div>
                <h2 className="text-xl font-bold text-slate-300">Loading Dashboard...</h2>
                <p className="text-sm text-slate-500">Syncing with Dropbox...</p>
            </div>
        ) : (
            <>
                <FilterBar filters={filters} onFilterChange={handleFilterChange} options={filterOptions} />
                <div className="mt-6">
                    {view === 'dashboard' && (
                        <Dashboard 
                          data={aggregatedData} 
                          contextData={contextAggregatedData}
                        />
                    )}
                    {view === 'table' && <DataGrid data={filteredData} />}
                    {view === 'movers' && <TopMovers data={filteredData} />}
                </div>
            </>
        )}
      </main>

      {/* Chat Assistant */}
      <AIChat onSendMessage={handleAskGemini} isOpen={isChatOpen} setIsOpen={setIsChatOpen} />

      {/* DATA MODAL */}
      {isDataModalOpen && (
        <div className="fixed inset-0 z-[100] flex items-center justify-center bg-black/70 backdrop-blur-sm animate-fade-in p-4">
            <div className="bg-slate-950 border border-border rounded-2xl shadow-2xl w-full max-w-lg relative overflow-hidden">
                <div className="bg-slate-900 px-6 py-4 border-b border-border flex justify-between items-center">
                    <h2 className="text-lg font-bold text-white">Data Source Settings</h2>
                    <button onClick={() => setIsDataModalOpen(false)} className="text-slate-400 hover:text-white transition-colors">
                        <CloseIcon />
                    </button>
                </div>
                
                <div className="p-6">
                    <FileUpload 
                        onFileUpload={handleFileUpload}
                        onUrlSubmit={handleUrlFetch}
                        isLoading={syncing}
                        activeUrl={activeUrl}
                        onDisconnect={disconnectUrl}
                        lastUpdated={lastUpdated}
                    />
                </div>
            </div>
        </div>
      )}

    </div>
  );
};

export default App;
