/* global React, I, fmt, fmt0, SEED, Badge, Button, PhoneShell, api */
const { useState, useEffect, useMemo, useRef, useCallback } = React;

// ─── Quote copy editor ────────────────────────────────────────
function CopyEditScreen({ onBack, onContinue, copy, setCopy, progress, quoteId }) {
  const sections = [
    { key: 'overview', heading: 'Overview', icon: I.FileText },
    { key: 'scope', heading: 'Scope of Work', icon: I.Wrench },
    { key: 'exclusions', heading: 'Exclusions', icon: I.AlertCircle },
  ];
  const [editing, setEditing] = useState(null);
  const [draft, setDraft] = useState('');
  const [loading, setLoading] = useState(!!quoteId);
  const [loadError, setLoadError] = useState(null);
  const [saving, setSaving] = useState(false);
  const [localCopy, setLocalCopy] = useState(copy);
  const [regenerating, setRegenerating] = useState(false);

  // Regenerate copy using AI
  const handleRegenerate = async () => {
    if (!quoteId || typeof api === 'undefined' || regenerating) return;
    setRegenerating(true);
    try {
      const genResult = await api.generateCopy(quoteId);
      if (genResult?.data?.sections) {
        const newCopy = {};
        genResult.data.sections.forEach(s => {
          const key = s.key || s.section_type;
          const body = s.body || s.content;
          if (key && body) newCopy[key] = body;
        });
        if (Object.keys(newCopy).length > 0) {
          setLocalCopy(newCopy);
          setCopy(newCopy);
        }
      }
    } catch (err) {
      console.error('Failed to regenerate copy:', err);
    } finally {
      setRegenerating(false);
    }
  };

  // Load or generate copy from API
  useEffect(() => {
    if (!quoteId || typeof api === 'undefined') {
      setLoading(false);
      return;
    }
    let cancelled = false;
    (async () => {
      try {
        // First try to get existing copy
        let data = await api.getCopy(quoteId);

        // If no sections exist, generate new copy using AI
        if (!data?.sections || data.sections.length === 0) {
          console.log('[CopyEdit] No existing copy, generating...');
          const genResult = await api.generateCopy(quoteId);
          if (genResult?.data?.sections) {
            data = { sections: genResult.data.sections };
          }
        }

        if (cancelled) return;

        if (data?.sections && data.sections.length > 0) {
          const newCopy = {};
          data.sections.forEach(s => {
            // Handle both formats: { key, body } and { section_type, content }
            const key = s.key || s.section_type;
            const body = s.body || s.content;
            if (key && body) newCopy[key] = body;
          });
          if (Object.keys(newCopy).length > 0) {
            setLocalCopy(newCopy);
            setCopy(newCopy);
          }
        }
      } catch (err) {
        if (!cancelled) setLoadError(err.message);
      } finally {
        if (!cancelled) setLoading(false);
      }
    })();
    return () => { cancelled = true; };
  }, [quoteId]);

  const openEditor = (key) => { setDraft(localCopy[key]); setEditing(key); };

  const saveEditor = async () => {
    const newCopy = { ...localCopy, [editing]: draft };
    setLocalCopy(newCopy);
    setCopy(newCopy);
    setSaving(true);

    // Save to API if quoteId is provided
    if (quoteId && typeof api !== 'undefined') {
      try {
        const sectionsArray = Object.entries(newCopy).map(([key, body]) => ({ key, body }));
        await api.updateCopy(quoteId, sectionsArray);
      } catch (err) {
        console.error('Failed to save copy:', err);
      }
    }

    setSaving(false);
    setEditing(null);
  };

  const cancelEditor = () => setEditing(null);

  // Use localCopy instead of copy prop for display
  const displayCopy = localCopy;

  const editingSection = sections.find(s => s.key === editing);

  // Loading state
  if (loading) {
    return (
      <PhoneShell title="Quote copy" onBack={onBack} progress={progress}>
        <div style={{ padding: '60px 20px', textAlign: 'center' }}>
          <I.Loader size={32} color="#FEC230" style={{ animation: 'vrvSpin 1.2s linear infinite' }} />
          <div style={{ color: '#B8B8B8', fontSize: 14, marginTop: 16 }}>Loading quote copy...</div>
        </div>
      </PhoneShell>
    );
  }

  // Error state
  if (loadError) {
    return (
      <PhoneShell title="Quote copy" onBack={onBack} progress={progress}>
        <div style={{ padding: '60px 20px', textAlign: 'center' }}>
          <I.AlertTriangle size={32} color="#EF4444" />
          <div style={{ color: '#fff', fontSize: 16, fontWeight: 600, marginTop: 16 }}>Failed to load copy</div>
          <div style={{ color: '#B8B8B8', fontSize: 13, marginTop: 8 }}>{loadError}</div>
          <Button variant="secondary" style={{ marginTop: 20 }} onClick={onBack}>Go Back</Button>
        </div>
      </PhoneShell>
    );
  }

  return (
    <PhoneShell title="Quote copy" onBack={onBack} progress={progress}>
      <div style={{ padding: '12px 16px 120px' }}>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          {sections.map(s => {
            const Icon = s.icon;
            return (
              <button
                key={s.key}
                onClick={() => openEditor(s.key)}
                style={{
                  width: '100%', textAlign: 'left', cursor: 'pointer', fontFamily: 'inherit',
                  background: '#262626', border: '1px solid #404040',
                  borderRadius: 6, padding: 12, transition: 'border-color .15s ease',
                }}
              >
                <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 10 }}>
                  <div style={{
                    width: 28, height: 28, borderRadius: 6, background: 'rgba(254,194,48,0.12)',
                    color: '#FEC230', display: 'flex', alignItems: 'center', justifyContent: 'center',
                  }}><Icon size={15}/></div>
                  <div style={{ flex: 1 }}>
                    <div style={{ color: '#fff', fontSize: 15, fontWeight: 600, lineHeight: '20px' }}>{s.heading}</div>
                  </div>
                  <span style={{
                    color: '#B8B8B8', fontSize: 12, fontWeight: 500,
                    display: 'inline-flex', alignItems: 'center', gap: 4, padding: '4px 6px',
                  }}>
                    <I.Pencil size={13}/> Edit
                  </span>
                </div>
                <div style={{
                  color: '#D4D4D4', fontSize: 13, lineHeight: '20px', whiteSpace: 'pre-wrap',
                  display: '-webkit-box', WebkitLineClamp: 4, WebkitBoxOrient: 'vertical', overflow: 'hidden',
                }}>{displayCopy[s.key]}</div>
              </button>
            );
          })}
        </div>
      </div>

      <div style={{
        position: 'absolute', bottom: 0, left: 0, right: 0, padding: '12px 16px 16px',
        background: 'linear-gradient(to top, rgba(23,23,23,1) 70%, rgba(23,23,23,0))',
      }}>
        <Button variant="primary" full onClick={onContinue}>Preview customer document</Button>
      </div>

      {/* Fullscreen editor overlay */}
      {editing && editingSection && (
        <div style={{
          position: 'absolute', inset: 0, background: '#171717', zIndex: 50,
          display: 'flex', flexDirection: 'column',
          animation: 'tmSlideUp .22s cubic-bezier(.2,.8,.2,1)',
        }}>
          {/* Header */}
          <div style={{
            height: 88, padding: '0 8px 12px', display: 'flex', alignItems: 'flex-end',
            borderBottom: '1px solid #404040', background: 'rgba(23,23,23,0.92)',
            backdropFilter: 'blur(20px)', WebkitBackdropFilter: 'blur(20px)',
          }}>
            <button onClick={cancelEditor} style={{
              width: 64, height: 40, border: 0, background: 'transparent', color: '#B8B8B8',
              cursor: 'pointer', fontFamily: 'inherit', fontSize: 14, textAlign: 'left', padding: '0 8px',
            }}>Cancel</button>
            <div style={{ flex: 1, textAlign: 'center', color: '#fff', fontSize: 16, fontWeight: 600 }}>
              {editingSection.heading}
            </div>
            <button onClick={saveEditor} style={{
              width: 64, height: 40, border: 0, background: 'transparent', color: '#FEC230',
              cursor: 'pointer', fontFamily: 'inherit', fontSize: 14, fontWeight: 600, padding: '0 8px',
            }}>Done</button>
          </div>

          {/* Fixed-heading badge */}
          <div style={{
            padding: '12px 16px 8px', display: 'flex', alignItems: 'center', gap: 8,
            color: '#808080', fontSize: 11,
          }}>
            <I.Lock size={12}/>
            <span>Heading is fixed</span>
          </div>

          {/* Full-screen textarea */}
          <textarea
            autoFocus
            value={draft}
            onChange={(e) => setDraft(e.target.value)}
            style={{
              flex: 1, width: '100%', background: 'transparent', border: 0,
              color: '#fff', fontSize: 15, lineHeight: '24px',
              fontFamily: 'inherit', padding: '4px 16px 24px', outline: 'none', resize: 'none', boxSizing: 'border-box',
            }}
          />

          {/* Footer hint */}
          <div style={{
            padding: '12px 16px 28px', borderTop: '1px solid #404040',
            display: 'flex', justifyContent: 'space-between', alignItems: 'center',
            color: '#808080', fontSize: 11,
            background: 'rgba(23,23,23,0.92)',
          }}>
            <span>{draft.length} chars · {draft.trim().split(/\s+/).filter(Boolean).length} words</span>
            <span>Auto-saved on Done</span>
          </div>
        </div>
      )}
    </PhoneShell>
  );
}

// ─── Document Preview (Word-style) ────────────────────────────
function DocumentPreviewScreen({ onBack, onSave, copy, pricing, hardwareTotal: propHardwareTotal, multiplier: propMultiplier, docStyle = 'word', progress, quoteId, client }) {
  const [loading, setLoading] = useState(!!quoteId);
  const [loadError, setLoadError] = useState(null);
  const [previewData, setPreviewData] = useState(null);
  const [clientData, setClientData] = useState(client || null);
  const [copied, setCopied] = useState(false);

  // Load preview and client data from API
  useEffect(() => {
    if (!quoteId || typeof api === 'undefined') {
      setLoading(false);
      return;
    }
    let cancelled = false;
    (async () => {
      try {
        const [previewResult, clientResult] = await Promise.all([
          api.getPreview(quoteId).catch(() => null),
          api.getClient(quoteId).catch(() => null)
        ]);
        if (cancelled) return;
        // Extract data from API response wrapper
        if (previewResult?.data) {
          const preview = previewResult.data;
          // Transform copy sections from array to object format
          let copyObj = {};
          if (preview.copy?.sections) {
            preview.copy.sections.forEach(s => {
              // Handle both formats: { key, body } and { section_type, content }
              const key = s.key || s.section_type;
              const body = s.body || s.content;
              if (key && body) copyObj[key] = body;
            });
          }
          setPreviewData({
            pricing: preview.pricing,
            copy: copyObj,
            quote: preview.quote,
            hardware: preview.hardware,
          });
        }
        if (clientResult?.data) setClientData(clientResult.data);
      } catch (err) {
        console.warn('Failed to load preview:', err);
      } finally {
        if (!cancelled) setLoading(false);
      }
    })();
    return () => { cancelled = true; };
  }, [quoteId]);

  // Use API preview data if available, otherwise use props
  const displayPricing = previewData?.pricing || pricing;
  const displayCopy = previewData?.copy || copy;
  const displayClient = clientData || client || {};

  // Support multiple API formats: total_amount, final_price, or prop format finalPrice
  // Use explicit check for > 0 to avoid treating 0 as falsy
  let finalPrice = displayPricing?.total_amount || displayPricing?.final_price || displayPricing?.finalPrice;
  if (!finalPrice || finalPrice <= 0) {
    // Fallback: calculate from props (passed from App state)
    const hwTotal = displayPricing?.hardware_total || propHardwareTotal || 0;
    const mult = displayPricing?.multiplier || propMultiplier || 3.5;
    finalPrice = hwTotal * mult;
  }
  const gst = finalPrice * 0.10;
  const incGst = finalPrice + gst;
  const today = new Date().toLocaleDateString('en-AU', { day: 'numeric', month: 'long', year: 'numeric' });
  const validDate = new Date();
  validDate.setDate(validDate.getDate() + 30);
  const validUntil = validDate.toLocaleDateString('en-AU', { day: 'numeric', month: 'long', year: 'numeric' });

  // Copy quote content to clipboard
  const copyToClipboard = async () => {
    const lines = [];

    // Client section
    if (displayClient.name || displayClient.email) {
      lines.push('Prepared for');
      if (displayClient.name) lines.push(displayClient.name);
      if (displayClient.billing_address) lines.push(displayClient.billing_address);
      if (displayClient.email) lines.push(displayClient.email);
      if (displayClient.phone) lines.push(displayClient.phone);
      lines.push('');
    }

    // Overview
    if (displayCopy?.overview) {
      lines.push('Overview');
      lines.push(displayCopy.overview);
      lines.push('');
    }

    // Scope of Work
    if (displayCopy?.scope) {
      lines.push('Scope of Work');
      lines.push(displayCopy.scope);
      lines.push('');
    }

    // Exclusions
    if (displayCopy?.exclusions) {
      lines.push('Exclusions');
      lines.push(displayCopy.exclusions);
      lines.push('');
    }

    // Quote Total
    lines.push(`Quote Total (inc GST): ${fmt(incGst)}`);

    const text = lines.join('\n');

    try {
      await navigator.clipboard.writeText(text);
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    } catch (err) {
      console.error('Failed to copy:', err);
    }
  };

  // Loading state
  if (loading) {
    return (
      <PhoneShell title="Customer document" onBack={onBack} progress={progress}>
        <div style={{ padding: '60px 20px', textAlign: 'center' }}>
          <I.Loader size={32} color="#FEC230" style={{ animation: 'vrvSpin 1.2s linear infinite' }} />
          <div style={{ color: '#B8B8B8', fontSize: 14, marginTop: 16 }}>Loading preview...</div>
        </div>
      </PhoneShell>
    );
  }

  const copyButton = (
    <button
      onClick={copyToClipboard}
      aria-label="Copy quote"
      style={{
        width: 36, height: 36, borderRadius: 6, border: 0,
        background: copied ? 'rgba(34,197,94,0.2)' : 'transparent',
        color: copied ? '#22C55E' : '#fff',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        cursor: 'pointer', transition: 'all .2s ease',
      }}
    >
      {copied ? <I.Check size={18} /> : <I.Copy size={18} />}
    </button>
  );

  return (
    <PhoneShell
      title="Customer document"
      onBack={onBack}
      progress={progress}
      right={copyButton}
    >
      <div style={{ padding: '12px 14px 100px', background: '#171717' }}>
        {/* Word doc page */}
        <div style={{
          background: '#fff', borderRadius: 4, padding: '28px 22px 32px',
          boxShadow: '0 8px 24px rgba(0,0,0,0.4), 0 0 0 1px #404040',
          color: '#1a1a1a', fontFamily: '"Calibri", "Segoe UI", -apple-system, sans-serif',
          fontSize: 11, lineHeight: '16px',
          minHeight: 600, position: 'relative',
        }}>
          {/* Header */}
          <div style={{
            display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start',
            paddingBottom: 14, borderBottom: '2px solid #1a1a1a', marginBottom: 18,
          }}>
            <div style={{ fontSize: 16, fontWeight: 700, color: '#1a1a1a', textTransform: 'uppercase', letterSpacing: '0.04em' }}>
              QUOTATION
            </div>
            <div style={{ textAlign: 'right' }}>
              <div style={{ fontSize: 9, color: '#555', lineHeight: '13px' }}>
                Date {today}<br/>
                Valid until {validUntil}
              </div>
            </div>
          </div>

          {/* Client details */}
          {(displayClient.name || displayClient.email) && (
            <div style={{ marginBottom: 18 }}>
              <div style={{ fontSize: 8, color: '#888', fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.06em' }}>Prepared for</div>
              <div style={{ fontSize: 11, color: '#1a1a1a', fontWeight: 600, marginTop: 3 }}>
                {displayClient.name || 'Client Name'}
              </div>
              <div style={{ fontSize: 9, color: '#555', lineHeight: '13px' }}>
                {displayClient.billing_address && <>{displayClient.billing_address}<br/></>}
                {displayClient.email && <>{displayClient.email}<br/></>}
                {displayClient.phone && <>{displayClient.phone}</>}
              </div>
            </div>
          )}

          {/* Body sections */}
          <DocSection heading="Overview" body={displayCopy?.overview || ''}/>
          <DocSection heading="Scope of Work" body={displayCopy?.scope || ''}/>
          <DocSection heading="Exclusions" body={displayCopy?.exclusions || ''}/>

          {/* Quote Total */}
          <div style={{
            marginTop: 28, padding: '16px 14px',
            background: '#f5f5f5', border: '2px solid #1a1a1a', borderRadius: 4,
            display: 'flex', justifyContent: 'space-between', alignItems: 'center',
          }}>
            <div style={{ fontSize: 13, fontWeight: 700, color: '#1a1a1a' }}>
              Quote Total <span style={{ fontWeight: 400, fontSize: 10 }}>(inc GST)</span>
            </div>
            <div style={{ fontSize: 18, fontWeight: 700, color: '#1a1a1a', fontVariantNumeric: 'tabular-nums' }}>
              {fmt(incGst)}
            </div>
          </div>
        </div>

        <div style={{ display: 'flex', justifyContent: 'center', gap: 4, marginTop: 12, color: '#808080', fontSize: 11 }}>
          <span>Page 1 of 1</span>
        </div>
      </div>

      <div style={{
        position: 'absolute', bottom: 0, left: 0, right: 0, padding: '12px 16px 16px',
        background: 'linear-gradient(to top, rgba(23,23,23,1) 70%, rgba(23,23,23,0))',
        display: 'flex', gap: 8,
      }}>
        <Button variant="primary" full onClick={onSave} icon={I.Check}>Save and close</Button>
      </div>
    </PhoneShell>
  );
}

const miniBtn = {
  background: '#171717', border: '1px solid #404040', borderRadius: 6,
  color: '#D4D4D4', fontSize: 11, fontFamily: 'inherit', cursor: 'pointer',
  padding: '4px 8px', display: 'inline-flex', alignItems: 'center', gap: 4,
};

function DocSection({ heading, body }) {
  return (
    <div style={{ marginTop: 14 }}>
      <div style={{ fontSize: 12, fontWeight: 700, color: '#1a1a1a', borderBottom: '1px solid #1a1a1a', paddingBottom: 4, marginBottom: 6 }}>
        {heading}
      </div>
      <div style={{ fontSize: 10, color: '#222', lineHeight: '15px', whiteSpace: 'pre-wrap' }}>{body}</div>
    </div>
  );
}

// ─── Equipment Schedule Table ────────────────────────────────
function EquipmentScheduleTable({ items }) {
  if (!items || items.length === 0) return null;

  return (
    <div style={{ marginTop: 14 }}>
      <div style={{ fontSize: 12, fontWeight: 700, color: '#1a1a1a', borderBottom: '1px solid #1a1a1a', paddingBottom: 4, marginBottom: 6 }}>
        Equipment Schedule
      </div>
      <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 9 }}>
        <thead>
          <tr style={{ background: '#f0f0f0' }}>
            <th style={{ padding: '4px 6px', textAlign: 'left', fontWeight: 600, borderBottom: '1px solid #ccc' }}>Qty</th>
            <th style={{ padding: '4px 6px', textAlign: 'left', fontWeight: 600, borderBottom: '1px solid #ccc' }}>Model</th>
            <th style={{ padding: '4px 6px', textAlign: 'left', fontWeight: 600, borderBottom: '1px solid #ccc' }}>Description</th>
            <th style={{ padding: '4px 6px', textAlign: 'right', fontWeight: 600, borderBottom: '1px solid #ccc' }}>Cooling</th>
            <th style={{ padding: '4px 6px', textAlign: 'right', fontWeight: 600, borderBottom: '1px solid #ccc' }}>Heating</th>
            <th style={{ padding: '4px 6px', textAlign: 'right', fontWeight: 600, borderBottom: '1px solid #ccc' }}>Electrical</th>
          </tr>
        </thead>
        <tbody>
          {items.map((item, idx) => (
            <tr key={idx} style={{ borderBottom: '1px solid #eee' }}>
              <td style={{ padding: '4px 6px', color: '#333' }}>{item.qty}</td>
              <td style={{ padding: '4px 6px', color: '#333', fontFamily: 'monospace', fontSize: 8 }}>{item.model}</td>
              <td style={{ padding: '4px 6px', color: '#555' }}>{item.description}</td>
              <td style={{ padding: '4px 6px', color: '#333', textAlign: 'right' }}>{item.capacity_kw}</td>
              <td style={{ padding: '4px 6px', color: '#333', textAlign: 'right' }}>{item.heat_kw}</td>
              <td style={{ padding: '4px 6px', color: '#333', textAlign: 'right', fontSize: 8 }}>{item.electrical}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

// ─── Electrical Summary Section ──────────────────────────────
function ElectricalSummarySection({ summary }) {
  if (!summary) return null;

  return (
    <div style={{ marginTop: 14 }}>
      <div style={{ fontSize: 12, fontWeight: 700, color: '#1a1a1a', borderBottom: '1px solid #1a1a1a', paddingBottom: 4, marginBottom: 6 }}>
        Electrical Requirements
      </div>
      <div style={{ fontSize: 9, color: '#333', lineHeight: '14px' }}>
        <div style={{ display: 'flex', gap: 24, marginBottom: 8 }}>
          <div>
            <span style={{ fontWeight: 600 }}>Supply: </span>
            <span>{summary.recommended_supply_phase}</span>
          </div>
          <div>
            <span style={{ fontWeight: 600 }}>Total MCA: </span>
            <span>{summary.total_mca_amps}A</span>
          </div>
          {summary.max_breaker_amps > 0 && (
            <div>
              <span style={{ fontWeight: 600 }}>Max Breaker: </span>
              <span>{summary.max_breaker_amps}A</span>
            </div>
          )}
        </div>
        {summary.cable_requirements && summary.cable_requirements.length > 0 && (
          <div style={{ marginTop: 6 }}>
            <div style={{ fontWeight: 600, marginBottom: 4 }}>Cable Requirements:</div>
            <ul style={{ margin: 0, paddingLeft: 16 }}>
              {summary.cable_requirements.map((req, idx) => (
                <li key={idx} style={{ marginBottom: 2 }}>
                  {req.model_number}: {req.breaker_amps}A breaker{req.min_gauge_mm > 0 ? `, min ${req.min_gauge_mm}mm² cable` : ''}
                </li>
              ))}
            </ul>
          </div>
        )}
      </div>
    </div>
  );
}

function SumRow({ label, value }) {
  return (
    <tr>
      <td style={{ padding: '4px 0', color: '#222' }}>{label}</td>
      <td style={{ padding: '4px 0', textAlign: 'right', color: '#1a1a1a', fontVariantNumeric: 'tabular-nums' }}>{value}</td>
    </tr>
  );
}

// ─── Export screen ────────────────────────────────────────────
function ExportScreen({ onBack, onDone, finalPrice, progress, quoteId }) {
  const [exporting, setExporting] = useState(true);
  const [done, setDone] = useState({ excel: false, word: false });
  const [exportError, setExportError] = useState(null);
  const [exportUrls, setExportUrls] = useState({ excel: null, word: null });

  useEffect(() => {
    // If we have a quoteId and API, generate real exports
    if (quoteId && typeof api !== 'undefined') {
      let cancelled = false;
      (async () => {
        try {
          await api.generateExport(quoteId);
          if (cancelled) return;

          // Simulate staggered completion for UX
          setTimeout(() => {
            if (cancelled) return;
            setDone(d => ({ ...d, excel: true }));
            setExportUrls(u => ({ ...u, excel: api.getExportUrl(quoteId, 'xlsx') }));
          }, 800);

          setTimeout(() => {
            if (cancelled) return;
            setDone(d => ({ ...d, word: true }));
            setExportUrls(u => ({ ...u, word: api.getExportUrl(quoteId, 'docx') }));
          }, 1500);

          setTimeout(() => {
            if (cancelled) return;
            setExporting(false);
          }, 1650);
        } catch (err) {
          if (cancelled) return;
          setExportError(err.message);
          setExporting(false);
        }
      })();
      return () => { cancelled = true; };
    } else {
      // Fallback to mock timing for demo mode
      const t1 = setTimeout(() => setDone(d => ({ ...d, excel: true })), 900);
      const t2 = setTimeout(() => setDone(d => ({ ...d, word: true })), 1750);
      const t3 = setTimeout(() => setExporting(false), 1900);
      return () => { clearTimeout(t1); clearTimeout(t2); clearTimeout(t3); };
    }
  }, [quoteId]);

  const handleDownload = (type) => {
    const url = type === 'xlsx' ? exportUrls.excel : exportUrls.word;
    if (url) {
      window.open(url, '_blank');
    }
  };

  // Error state
  if (exportError) {
    return (
      <PhoneShell title="Download" onBack={onBack} progress={progress}>
        <div style={{ padding: '60px 20px', textAlign: 'center' }}>
          <I.AlertTriangle size={48} color="#EF4444" />
          <div style={{ color: '#fff', fontSize: 18, fontWeight: 600, marginTop: 16 }}>Export failed</div>
          <div style={{ color: '#B8B8B8', fontSize: 13, marginTop: 8 }}>{exportError}</div>
          <Button variant="secondary" style={{ marginTop: 20 }} onClick={onBack}>Go Back</Button>
        </div>
      </PhoneShell>
    );
  }

  return (
    <PhoneShell title="Download" onBack={onBack} progress={progress}>
      <div style={{ padding: '24px 20px' }}>
        <div style={{ textAlign: 'center', padding: '16px 0 24px' }}>
          <div style={{
            width: 88, height: 88, borderRadius: '50%', margin: '0 auto',
            background: !exporting ? 'rgba(34,197,94,0.16)' : 'rgba(254,194,48,0.16)',
            border: `1px solid ${!exporting ? 'rgba(34,197,94,0.36)' : 'rgba(254,194,48,0.36)'}`,
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            transition: 'all .35s ease',
          }}>
            {exporting
              ? <I.Loader size={40} color="#FEC230" style={{ animation: 'vrvSpin 1.2s linear infinite' }}/>
              : <I.CheckCircle size={48} color="#22C55E"/>}
          </div>
          <div style={{ color: '#fff', fontSize: 22, fontWeight: 700, lineHeight: '28px', letterSpacing: '-0.3px', marginTop: 18 }}>
            {exporting ? 'Generating documents…' : 'Quote ready to share'}
          </div>
          <div style={{ color: '#B8B8B8', fontSize: 13, marginTop: 6 }}>
            {exporting ? 'Your files will be ready in a moment' : `${fmt0(finalPrice)} customer-ready package`}
          </div>
        </div>

        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          <DownloadCard
            icon={<I.FileSpreadsheet size={22}/>}
            iconBg="rgba(34,197,94,0.14)" iconColor="#22C55E"
            title="Quote workings.xlsx"
            sub="Internal numbers · materials, labour, margin"
            ready={done.excel}
            ext="XLSX"
            onDownload={() => handleDownload('xlsx')}
          />
          <DownloadCard
            icon={<I.FileText size={22}/>}
            iconBg="rgba(59,130,246,0.14)" iconColor="#3B82F6"
            title="Customer quote.docx"
            sub="Client-ready Word document with full copy"
            ready={done.word}
            ext="DOCX"
            onDownload={() => handleDownload('docx')}
          />
        </div>

        <div style={{ display: 'flex', flexDirection: 'column', gap: 8, marginTop: 18 }}>
          <Button variant="secondary" full onClick={onDone}>Back to dashboard</Button>
        </div>
      </div>
    </PhoneShell>
  );
}

function DownloadCard({ icon, iconBg, iconColor, title, sub, ready, ext, onDownload }) {
  return (
    <div style={{
      background: '#262626', border: '1px solid #404040', borderRadius: 8,
      padding: 12, display: 'flex', alignItems: 'center', gap: 12,
      opacity: ready ? 1 : 0.6, transition: 'opacity .3s ease',
    }}>
      <div style={{
        width: 44, height: 44, borderRadius: 8, background: iconBg, color: iconColor,
        display: 'flex', alignItems: 'center', justifyContent: 'center', flex: '0 0 44px', position: 'relative',
      }}>
        {icon}
        <span style={{
          position: 'absolute', bottom: -4, right: -4, fontSize: 8, fontWeight: 700,
          background: '#171717', color: iconColor, padding: '1px 4px', borderRadius: 3, border: `1px solid ${iconColor}`,
        }}>{ext}</span>
      </div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ color: '#fff', fontSize: 14, fontWeight: 600, lineHeight: '20px', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{title}</div>
        <div style={{ color: '#B8B8B8', fontSize: 11, lineHeight: '16px', marginTop: 1 }}>{sub}</div>
      </div>
      <button disabled={!ready} onClick={onDownload} style={{
        background: ready ? '#FEC230' : '#262626', border: ready ? 0 : '1px solid #404040',
        color: ready ? '#000' : '#808080', cursor: ready ? 'pointer' : 'not-allowed',
        padding: '6px 10px', borderRadius: 6, fontFamily: 'inherit', fontSize: 12, fontWeight: 600,
        display: 'inline-flex', alignItems: 'center', gap: 4,
      }}>
        {ready ? <><I.Download size={13}/> Get</> : <I.Loader size={13} style={{ animation: 'vrvSpin 1.2s linear infinite' }}/>}
      </button>
    </div>
  );
}

window.CopyEditScreen = CopyEditScreen;
window.DocumentPreviewScreen = DocumentPreviewScreen;
window.ExportScreen = ExportScreen;
