/* global React, ReactDOM, I, SEED, fmt, fmt0, statusTone, api,
   LoginScreen, DashboardScreen, UploadScreen, LoaderScreen, ErrorScreen,
   HardwareScreen, PriceSummaryScreen, PricingScreen, CopyEditScreen, DocumentPreviewScreen, ExportScreen, ClientDetailsScreen, NetProfitScreen, MaterialsScreen, LabourScreen, DEFAULT_MATERIAL_ITEMS, DEFAULT_LABOUR_ITEMS,
   IOSDevice, DesignCanvas, DCSection, DCArtboard,
   TweaksPanel, TweakSection, TweakRadio, TweakSelect, useTweaks
*/
const { useState, useEffect, useMemo, useRef, useCallback } = React;

// ─── App router with animated transitions and auth state ────────────────
function App({ initialScreen = 'dashboard', frameless }) {
  // Auth state
  const [currentUser, setCurrentUser] = useState(null);
  const [authLoading, setAuthLoading] = useState(true);
  const [authError, setAuthError] = useState(null);

  // Current quote context
  const [currentQuoteId, setCurrentQuoteId] = useState(null);
  const [quotes, setQuotes] = useState([]);

  // Screen routing
  const [screen, setScreen] = useState(initialScreen);
  const [history, setHistory] = useState([initialScreen]);
  const [direction, setDirection] = useState('forward');
  const [transitioning, setTransitioning] = useState(false);

  // shared state across screens
  const [uploadResult, setUploadResult] = useState(null); // {filename, error}
  const [hardware, setHardware] = useState(SEED.extractedQuote);
  // Compute initial hardware total from seed so docpreview/export work standalone
  const initialHwTotal = SEED.extractedQuote.items.reduce((s, it) => s + (it.qty * it.unit), 0);
  const [hardwareTotal, setHardwareTotal] = useState(initialHwTotal);
  const [multiplier, setMultiplier] = useState(3.5);
  // Default pricing derived from hardware x multiplier so screens that read it never see null
  const defaultPricing = useMemo(() => {
    const final = initialHwTotal * 3.5;
    const remaining = final - initialHwTotal;
    const labourTotal = 16 * 100 * 2; // 16h x $100 x 2 crew
    const materialsTotal = Math.round(remaining * 0.45);
    const profit = Math.max(0, final - initialHwTotal - labourTotal - materialsTotal);
    return { finalPrice: final, materialsTotal, labourTotal, profit, grossMargin: (profit + (final - initialHwTotal - profit - labourTotal - materialsTotal)) / final };
  }, [initialHwTotal]);
  const [pricing, setPricing] = useState(defaultPricing);
  const [copy, setCopy] = useState(SEED.generatedCopy);
  // Material & labour items - lifted so edits persist across navigation
  const [materialItems, setMaterialItems] = useState(window.DEFAULT_MATERIAL_ITEMS || []);
  const [labourItems, setLabourItems] = useState(window.DEFAULT_LABOUR_ITEMS || []);

  // V3 Pricing state - stores allocation and pricing from HardwareScreen sliders
  const [v3Pricing, setV3Pricing] = useState(null);
  const [hardwareItems, setHardwareItems] = useState([]);

  // Populate materialItems and labourItems from V3 pricing
  useEffect(() => {
    if (!v3Pricing) return;

    // Build materials list: VRV System total first, then V3 allocated materials
    const allMaterials = [];

    // Add VRV System as a single line item with the total from V3 pricing
    const hardwareTotal = v3Pricing.pricing?.breakdown?.hardware || 0;
    if (hardwareTotal > 0) {
      allMaterials.push({
        id: 'hw0',
        name: 'VRV System (from supplier quote)',
        qty: 1,
        unit: hardwareTotal,
        unitLabel: 'system',
      });
    }

    // Add V3 auto-allocated materials
    if (v3Pricing.allocation?.materials) {
      v3Pricing.allocation.materials.forEach((mat, i) => {
        allMaterials.push({
          id: `v3m${i}`,
          name: mat.name,
          qty: mat.quantity,
          unit: mat.unitPrice,
          unitLabel: mat.unit || 'each',
        });
      });
    }

    if (allMaterials.length > 0) {
      setMaterialItems(allMaterials);
    }

    // Populate labour from V3 pricing
    if (v3Pricing.labourBreakdown) {
      const v3Labour = v3Pricing.labourBreakdown.map((tech, i) => ({
        id: `v3l${i}`,
        name: tech.role,
        qty: tech.hours,
        unit: tech.rate,
        unitLabel: 'hours',
        type: 'Employee', // Default to Employee, can be toggled
      }));
      setLabourItems(v3Labour);
    }
  }, [v3Pricing]);

  // Check authentication on mount
  useEffect(() => {
    checkAuth();
  }, []);

  // URL-based routing using hash
  useEffect(() => {
    const handleHashChange = () => {
      const hash = window.location.hash.slice(1); // Remove #
      if (hash && hash !== screen) {
        // Parse route: #dashboard, #quote/123/hardware, etc.
        const parts = hash.split('/');
        const route = parts[0];

        // Extract quote ID if present
        if (parts[0] === 'quote' && parts[1]) {
          setCurrentQuoteId(parts[1]);
          if (parts[2]) {
            setScreen(parts[2]);
          }
        } else if (route) {
          setScreen(route);
        }
      }
    };

    window.addEventListener('hashchange', handleHashChange);
    // Check initial hash
    if (window.location.hash) {
      handleHashChange();
    }

    return () => window.removeEventListener('hashchange', handleHashChange);
  }, [screen]);

  const checkAuth = async () => {
    try {
      setAuthLoading(true);
      // DEMO MODE: Skip login, just set a fake user and go to dashboard
      // The API will auto-authenticate as demo user
      setCurrentUser({
        id: 'demo',
        email: 'demo@traidmin.com',
        name: 'Demo User',
        company_name: 'Demo Company'
      });
      await loadQuotes();
      go('dashboard');
    } catch (err) {
      console.error('[App] Auth check error:', err);
      // Still go to dashboard
      go('dashboard');
    } finally {
      setAuthLoading(false);
    }
  };

  const handleLogin = async (email, password) => {
    try {
      setAuthError(null);
      const result = await api.login(email, password);
      setCurrentUser(result.user);
      await loadQuotes();
      go('dashboard');
      return { success: true };
    } catch (err) {
      setAuthError(err.message);
      return { success: false, error: err.message };
    }
  };

  const handleLogout = async () => {
    try {
      await api.logout();
    } catch (err) {
      // Ignore logout errors
    }
    setCurrentUser(null);
    setCurrentQuoteId(null);
    setQuotes([]);
    go('login');
  };

  const loadQuotes = async () => {
    try {
      console.log('[App] Loading quotes...');
      const response = await api.listQuotes();
      console.log('[App] Quotes response:', response);
      // API returns {success, data: [...], pagination}
      const quotesArray = response.data || response.quotes || response || [];
      console.log('[App] Quotes array:', quotesArray);
      setQuotes(Array.isArray(quotesArray) ? quotesArray : []);
    } catch (err) {
      console.error('[App] Failed to load quotes:', err);
      setQuotes([]);
    }
  };

  // Create a new quote and navigate to upload
  const handleCreateQuote = async () => {
    console.log('[App] Create quote button clicked');
    try {
      if (typeof api === 'undefined' || !api.createQuote) {
        console.error('[App] API not available');
        alert('Unable to create quote - API not available. Please refresh the page.');
        return;
      }
      console.log('[App] Calling api.createQuote()...');
      const response = await api.createQuote();
      console.log('[App] Create quote response:', response);
      // API returns {success, data: {id, ...}}
      const quoteId = response.data?.id || response.id;
      if (quoteId) {
        console.log('[App] Quote created with ID:', quoteId);
        setCurrentQuoteId(quoteId);
        go('upload');
      } else {
        console.error('[App] No quote ID in response:', response);
        alert('Failed to create quote - no ID returned');
      }
    } catch (err) {
      console.error('[App] Failed to create quote:', err);
      alert('Failed to create quote: ' + (err.message || 'Unknown error'));
    }
  };

  // Load quote data when quote ID changes
  useEffect(() => {
    if (currentQuoteId) {
      loadQuoteData(currentQuoteId);
    }
  }, [currentQuoteId]);

  const loadQuoteData = async (id) => {
    try {
      // Load hardware, materials, labour, pricing, copy in parallel
      const [hwData, matsData, labData, priceData, copyData] = await Promise.all([
        api.getHardware(id).catch(() => null),
        api.getMaterials(id).catch(() => null),
        api.getLabour(id).catch(() => null),
        api.getPricing(id).catch(() => null),
        api.getCopy(id).catch(() => null),
      ]);

      if (hwData) {
        setHardware(hwData);
        const total = hwData.items?.reduce((s, it) => s + (it.qty * it.unit), 0) || 0;
        setHardwareTotal(total);
      }
      if (matsData?.items) {
        setMaterialItems(matsData.items);
      }
      if (labData?.items) {
        setLabourItems(labData.items);
      }
      if (priceData) {
        setPricing(priceData);
        if (priceData.multiplier) {
          setMultiplier(priceData.multiplier);
        }
      }
      if (copyData?.sections) {
        setCopy(copyData.sections);
      }
    } catch (err) {
      console.error('Failed to load quote data:', err);
    }
  };

  const go = useCallback((next, dir = 'forward') => {
    setDirection(dir);
    setTransitioning(true);

    // Update URL hash
    if (currentQuoteId && ['upload', 'loader', 'error', 'hardware', 'pricing', 'pricesummary', 'materials', 'labour', 'netprofit', 'clientdetails', 'copyedit', 'docpreview', 'export'].includes(next)) {
      window.location.hash = `quote/${currentQuoteId}/${next}`;
    } else {
      window.location.hash = next;
    }

    setTimeout(() => {
      setScreen(next);
      setHistory(h => dir === 'back' ? h.slice(0, -1) : [...h, next]);
      requestAnimationFrame(() => setTransitioning(false));
    }, 120);
  }, [currentQuoteId]);

  const back = useCallback((fallback) => {
    if (history.length > 1) {
      const prev = history[history.length - 2];
      go(prev, 'back');
    } else if (fallback) {
      go(fallback, 'back');
    }
  }, [history, go]);

  // expose for tweak-panel "jump to screen" if needed
  useEffect(() => {
    window.__vrvGo = go;
  }, [go]);

  // Show loading spinner while checking auth
  if (authLoading) {
    return (
      <div style={{
        width: '100%', height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center',
        background: '#171717',
      }}>
        <div style={{
          width: 40, height: 40, border: '3px solid #404040', borderTopColor: '#FEC230',
          borderRadius: '50%', animation: 'vrvSpin 1s linear infinite',
        }}/>
      </div>
    );
  }

  let inner;
  switch (screen) {
    case 'login':
      inner = <LoginScreen
        onLogin={handleLogin}
        authError={authError}
      />;
      break;
    case 'dashboard':
      inner = <DashboardScreen
        onCreate={handleCreateQuote}
        quotes={quotes}
        onOpenQuote={(quote) => {
          // Set quote ID and navigate to quote summary
          const quoteId = quote.id;
          setCurrentQuoteId(quoteId);
          loadQuoteData(quoteId);
          go('pricesummary');
        }}
        onRefresh={loadQuotes}
        onLogout={handleLogout}
        currentUser={currentUser}
      />;
      break;
    case 'upload':
      inner = <UploadScreen
        progress={0.1}
        quoteId={currentQuoteId}
        onBack={() => back('dashboard')}
        onUploaded={(r) => { setUploadResult(r); go('loader'); }}
      />;
      break;
    case 'loader':
      inner = <LoaderScreen
        quoteId={currentQuoteId}
        isError={uploadResult?.error}
        onDone={() => go('hardware')}
        onError={(errType) => {
          // Update uploadResult with error type from backend if provided
          if (errType) {
            setUploadResult(prev => ({ ...prev, error: true, errorType: errType }));
          }
          go('error');
        }}
      />;
      break;
    case 'error':
      inner = <ErrorScreen
        progress={0.2}
        filename={uploadResult?.filename}
        errorType={uploadResult?.errorType}
        onRetry={() => go('upload', 'back')}
      />;
      break;
    case 'hardware':
      inner = <HardwareScreen
        progress={0.3}
        quoteId={currentQuoteId}
        hardware={hardware}
        onBack={() => back('upload')}
        onContinue={(data) => {
          // V3: Always go to pricesummary, skip old pricing screen
          if (data && typeof data === 'object') {
            setHardwareTotal(data.hardwareTotal || 0);
            setMultiplier(data.multiplier || 3.5);
            if (data.v3Pricing) {
              setV3Pricing(data.v3Pricing);
            }
            if (data.hardwareItems) {
              setHardwareItems(data.hardwareItems);
            }
          }
          // Start generating copy in background (don't await)
          if (currentQuoteId && typeof api !== 'undefined') {
            api.generateCopy(currentQuoteId).catch(err => {
              console.warn('Background copy generation failed:', err);
            });
          }
          go('pricesummary');
        }}
      />;
      break;
    case 'pricing':
      inner = <PricingScreen
        progress={0.45}
        quoteId={currentQuoteId}
        hardwareTotal={hardwareTotal}
        multiplier={multiplier}
        setMultiplier={setMultiplier}
        onBack={() => back('hardware')}
        onContinue={() => go('pricesummary')}
      />;
      break;
    case 'pricesummary':
      inner = <PriceSummaryScreen
        progress={0.6}
        quoteId={currentQuoteId}
        hardwareTotal={hardwareTotal}
        multiplier={multiplier}
        v3Pricing={v3Pricing}
        onBack={() => back(v3Pricing ? 'hardware' : 'pricing')}
        onContinue={() => go('copyedit')}
        onAddClient={() => go('clientdetails')}
        onEditProfit={() => go('netprofit')}
        onEditMaterials={() => go('materials')}
        onEditLabour={() => go('labour')}
        onEditCopy={() => go('copyedit')}
      />;
      break;
    case 'materials':
      inner = <MaterialsScreen
        progress={0.6}
        quoteId={currentQuoteId}
        items={materialItems}
        setItems={setMaterialItems}
        onBack={() => back('pricesummary')}
        onSave={() => back('pricesummary')}
      />;
      break;
    case 'labour':
      inner = <LabourScreen
        progress={0.6}
        quoteId={currentQuoteId}
        items={labourItems}
        setItems={setLabourItems}
        onBack={() => back('pricesummary')}
        onSave={() => back('pricesummary')}
      />;
      break;
    case 'netprofit':
      // Use V3 pricing breakdown if available, otherwise fall back to calculated values
      const v3Breakdown = v3Pricing?.pricing?.breakdown;
      inner = <NetProfitScreen
        progress={0.6}
        quoteId={currentQuoteId}
        // V3: Hardware + Materials are "external costs"
        hardwareCost={v3Breakdown?.hardware || hardwareTotal || 0}
        materialsTotal={v3Breakdown?.materials || 0}
        labourTotal={v3Breakdown?.labour || labourItems.reduce((s, i) => s + i.qty * i.unit, 0)}
        initialProfit={v3Breakdown?.profit || 0}
        finalPrice={v3Pricing?.pricing?.totalQuoteValue || hardwareTotal * multiplier}
        v3Pricing={v3Pricing}
        onBack={() => back('pricesummary')}
        onSave={() => back('pricesummary')}
      />;
      break;
    case 'clientdetails':
      inner = <ClientDetailsScreen
        quoteId={currentQuoteId}
        onBack={() => back('pricesummary')}
        onFinish={() => go('copyedit')}
      />;
      break;
    case 'copyedit':
      inner = <CopyEditScreen
        progress={0.75}
        quoteId={currentQuoteId}
        copy={copy} setCopy={setCopy}
        onBack={() => back('pricesummary')}
        onContinue={() => go('docpreview')}
      />;
      break;
    case 'docpreview':
      inner = <DocumentPreviewScreen
        progress={0.9}
        quoteId={currentQuoteId}
        copy={copy} pricing={pricing} hardwareTotal={hardwareTotal} multiplier={multiplier}
        onBack={() => back('copyedit')}
        onSave={() => {
          setCurrentQuoteId(null);
          setHistory(['dashboard']);
          setScreen('dashboard');
          window.location.hash = 'dashboard';
        }}
      />;
      break;
    case 'export':
      inner = <ExportScreen
        progress={1}
        quoteId={currentQuoteId}
        finalPrice={pricing?.finalPrice || 0}
        onBack={() => back('docpreview')}
        onDone={() => {
          setCurrentQuoteId(null);
          setHistory(['dashboard']);
          setScreen('dashboard');
          window.location.hash = 'dashboard';
        }}
      />;
      break;
    default:
      inner = <div style={{ color: '#fff', padding: 24 }}>Unknown screen: {screen}</div>;
  }

  return (
    <div style={{
      width: '100%', height: '100%', position: 'relative', overflow: 'hidden',
      background: '#171717',
    }}>
      <div key={screen} style={{
        width: '100%', height: '100%',
        animation: transitioning
          ? 'none'
          : `vrv${direction === 'forward' ? 'In' : 'BackIn'} .28s cubic-bezier(.2,.8,.2,1)`,
      }}>
        {inner}
      </div>
    </div>
  );
}

// ─── Tweaks panel ──────────────────────────────────────────
function VRVTweaks() {
  const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
    "startScreen": "login",
    "showAllScreens": false
  }/*EDITMODE-END*/;
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);

  return (
    <TweaksPanel title="Tweaks">
      <TweakSection title="Demo">
        <TweakSelect
          label="Start screen"
          value={t.startScreen}
          options={[
            ['login', 'Login'],
            ['dashboard', 'Dashboard'],
            ['upload', 'Upload'],
            ['loader', 'AI loader'],
            ['error', 'Error state'],
            ['hardware', 'Hardware summary'],
            ['pricing', 'Pricing builder'],
            ['pricesummary', 'Quote summary'],
            ['materials', 'Material costs'],
            ['labour', 'Labour costs'],
            ['netprofit', 'Net profit'],
            ['clientdetails', 'Client details'],
            ['copyedit', 'Copy editor'],
            ['docpreview', 'Document preview'],
            ['export', 'Export'],
          ]}
          onChange={(v) => {
            setTweak('startScreen', v);
            window.__vrvGo?.(v);
          }}
        />
      </TweakSection>
    </TweaksPanel>
  );
}

window.App = App;
window.VRVTweaks = VRVTweaks;
