import React, { useState, useMemo, useEffect } from 'react';
import * as XLSX from 'xlsx';
import { AppState, ExcelRow, COLUMNS } from './types';
import { Sidebar } from './components/Sidebar';
import { TopBar } from './components/TopBar';
import { ProductDescriptions } from './components/ProductDescriptions';
import { DataCompleteness } from './components/DataCompleteness';
import { MatrixView } from './components/MatrixView';
import { UploadReload } from './components/UploadReload';
import { EditPanel } from './components/EditPanel';

export default function App() {
  const [appState, setAppState] = useState<AppState>({
    headers: [],
    data: [],
    fileName: '',
    fileDate: null,
    hasUnsavedChanges: false
  });
  const [activeModule, setActiveModule] = useState<'descriptions' | 'completeness' | 'matrix' | 'upload'>('descriptions');
  const [editingRowIndex, setEditingRowIndex] = useState<number | null>(null);
  const [isLoadingDefault, setIsLoadingDefault] = useState(true);
  const [defaultLoadError, setDefaultLoadError] = useState<string | null>(null);

  useEffect(() => {
    const loadDefaultData = async () => {
      // Use different proxies as fallbacks
      const proxies = [
        (url: string) => `https://api.allorigins.win/raw?url=${encodeURIComponent(url)}`,
        (url: string) => `https://cors-anywhere.herokuapp.com/${url}`, // Often needs manual activation but we'll try
        (url: string) => `https://thingproxy.freeboard.io/fetch/${url}`
      ];

      const dropboxUrl = 'https://dl.dropboxusercontent.com/scl/fi/nkyabkq2jdwfudof2ovrl/Data-Matrix.xlsx?rlkey=1cz5fuabwipqqivihii7sybw0&st=io0g4wvb&dl=1';
      
      setIsLoadingDefault(true);
      setDefaultLoadError(null);

      let lastError = null;

      for (const getProxyUrl of proxies) {
        try {
          const proxyUrl = getProxyUrl(dropboxUrl);
          console.log(`Attempting to fetch via: ${proxyUrl}`);
          
          const response = await fetch(proxyUrl);
          
          if (!response.ok) {
            throw new Error(`Proxy returned status ${response.status}: ${response.statusText}`);
          }
          
          const arrayBuffer = await response.arrayBuffer();
          if (arrayBuffer.byteLength < 100) {
              throw new Error("File too small, possibly empty or error page");
          }

          const wb = XLSX.read(arrayBuffer, { type: 'array' });
          const wsname = wb.SheetNames[0];
          const ws = wb.Sheets[wsname];
          const data = XLSX.utils.sheet_to_json<any[]>(ws, { header: 1 });
          
          if (data.length > 0) {
            setAppState({
              headers: data[0],
              data: data.slice(1),
              fileName: 'Data-Matrix.xlsx (Cloud Sync)',
              fileDate: new Date(),
              hasUnsavedChanges: false
            });
            setActiveModule('descriptions');
            setIsLoadingDefault(false);
            return; // Success!
          }
        } catch (err) {
          console.error(`Failed with proxy:`, err);
          lastError = err;
        }
      }

      // If we reach here, all proxies failed
      setDefaultLoadError(lastError instanceof Error ? lastError.message : 'All connection attempts failed');
      setIsLoadingDefault(false);
    };

    loadDefaultData();
  }, []);

  const handleFileUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;

    if (appState.hasUnsavedChanges) {
      if (!window.confirm('You have unsaved changes. Are you sure you want to load a new file and discard them?')) {
        e.target.value = '';
        return;
      }
    }

    const reader = new FileReader();
    reader.onload = (evt) => {
      const bstr = evt.target?.result;
      const wb = XLSX.read(bstr, { type: 'binary' });
      const wsname = wb.SheetNames[0];
      const ws = wb.Sheets[wsname];
      const data = XLSX.utils.sheet_to_json<any[]>(ws, { header: 1 });
      
      if (data.length > 0) {
        setAppState({
          headers: data[0],
          data: data.slice(1),
          fileName: file.name,
          fileDate: new Date(),
          hasUnsavedChanges: false
        });
        setActiveModule('descriptions');
      }
    };
    reader.readAsBinaryString(file);
  };

  const handleExport = () => {
    if (appState.data.length === 0) return;
    
    const wsData = [appState.headers, ...appState.data];
    const ws = XLSX.utils.aoa_to_sheet(wsData);
    const wb = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, ws, 'Products');
    
    const dateStr = new Date().toISOString().split('T')[0];
    XLSX.writeFile(wb, `CRAZE_Products_Updated_${dateStr}.xlsx`);
    
    setAppState(prev => ({ ...prev, hasUnsavedChanges: false }));
  };

  const handleSaveRow = (rowIndex: number, updatedRow: ExcelRow) => {
    setAppState(prev => {
      const newData = [...prev.data];
      newData[rowIndex] = updatedRow;
      return {
        ...prev,
        data: newData,
        hasUnsavedChanges: true
      };
    });
    setEditingRowIndex(null);
  };

  const stats = useMemo(() => {
    if (appState.data.length === 0) return null;
    let missingDeLong = 0;
    let missingEnLong = 0;
    let missingDeShort = 0;
    let missingEnShort = 0;
    let fullyComplete = 0;

    appState.data.forEach(row => {
      const deLong = row[COLUMNS.LONG_DE];
      const enLong = row[COLUMNS.LONG_EN];
      const deShort = row[COLUMNS.SHORT_DE];
      const enShort = row[COLUMNS.SHORT_EN];

      if (!deLong) missingDeLong++;
      if (!enLong) missingEnLong++;
      if (!deShort) missingDeShort++;
      if (!enShort) missingEnShort++;

      if (deLong && enLong && deShort && enShort) fullyComplete++;
    });

    return {
      total: appState.data.length,
      missingDeLong,
      missingEnLong,
      missingDeShort,
      missingEnShort,
      fullyComplete
    };
  }, [appState.data]);

  return (
    <div className="h-screen bg-slate-900 text-slate-200 flex flex-col font-sans overflow-hidden">
      <TopBar 
        stats={stats} 
        onExport={handleExport} 
        hasData={appState.data.length > 0} 
        hasUnsavedChanges={appState.hasUnsavedChanges}
      />
      <div className="flex flex-1 overflow-hidden">
        <Sidebar activeModule={activeModule} setActiveModule={setActiveModule} />
        <main className="flex-1 overflow-auto relative p-6 bg-slate-950">
          {isLoadingDefault ? (
            <div className="flex flex-col items-center justify-center h-full text-slate-400">
              <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-500 mb-4"></div>
              <p className="text-lg">Loading latest data...</p>
            </div>
          ) : defaultLoadError && appState.data.length === 0 ? (
            <div className="flex flex-col items-center justify-center h-full text-red-400">
              <p className="mb-4 text-lg">Failed to auto-load data: {defaultLoadError}</p>
              <label className="cursor-pointer bg-blue-600 hover:bg-blue-700 text-white px-6 py-3 rounded-lg shadow-lg transition-colors">
                Load Excel File Manually
                <input type="file" accept=".xlsx, .xls" className="hidden" onChange={handleFileUpload} />
              </label>
            </div>
          ) : appState.data.length === 0 && activeModule !== 'upload' ? (
            <div className="flex flex-col items-center justify-center h-full text-slate-400">
              <p className="mb-4 text-lg">No data loaded.</p>
              <label className="cursor-pointer bg-blue-600 hover:bg-blue-700 text-white px-6 py-3 rounded-lg shadow-lg transition-colors">
                Load Excel File
                <input type="file" accept=".xlsx, .xls" className="hidden" onChange={handleFileUpload} />
              </label>
            </div>
          ) : (
            <>
              {activeModule === 'descriptions' && (
                <ProductDescriptions 
                  data={appState.data} 
                  onEdit={(index) => setEditingRowIndex(index)} 
                />
              )}
              {activeModule === 'completeness' && (
                <DataCompleteness data={appState.data} headers={appState.headers} />
              )}
              {activeModule === 'matrix' && (
                <MatrixView data={appState.data} headers={appState.headers} />
              )}
              {activeModule === 'upload' && (
                <UploadReload 
                  appState={appState} 
                  onUpload={handleFileUpload} 
                />
              )}
            </>
          )}
        </main>
      </div>

      {editingRowIndex !== null && (
        <EditPanel 
          row={appState.data[editingRowIndex]} 
          rowIndex={editingRowIndex}
          onSave={handleSaveRow}
          onClose={() => setEditingRowIndex(null)}
        />
      )}
    </div>
  );
}
