/* global React */
/* estimator.jsx — Phase 00: AI-assisted project cost & ROI estimator
   Feeds operative cost + expected ROI into calculator.jsx Section 01.
   Bilingual EN/ES, mirrors tweaks-panel lang setting via window.estimatorLang.
*/

const { useState: useEstState, useEffect: useEstEffect, useRef: useEstRef, useCallback: useEstCallback } = React;

// ── i18n ──────────────────────────────────────────────────────────────────
const EST_STRINGS = {
  en: {
    phaseLabel: '00 · Estimation',
    phaseTitle: 'Project cost & ROI estimation',
    phaseSub: 'Describe your project and the AI will calculate operative cost and first-year ROI',
    startBtn: 'Start estimation',
    skipBtn: 'Enter manually',
    continueBtn: 'Continue to calculator →',
    applyBtn: 'Apply to calculator',
    applied: 'Applied ✓',
    resetBtn: 'New estimation',
    placeholder: 'Describe your project, team, tools, timeline, and what the client will gain…',
    send: 'Send',
    thinking: 'Analysing…',
    you: 'You',
    ai: 'AI',
    error: 'Could not reach the model. Please try again.',
    resultTitle: 'Estimation results',
    costLabel: 'Operative cost',
    roiLabel: 'Expected 1st-year ROI',
    dealLabel: 'Deal name',
    editHint: 'You can adjust these values before applying',
    welcome: `Welcome to the DiALOGA project estimator.\n\nI'll guide you through a structured conversation to calculate:\n• **Operative cost** — your team hours + tools + APIs + licences\n• **Client's 1st-year ROI** — time saved + expenses reduced + revenue generated\n\nTell me about the project. A good starting point: what does it do, who is the client, and roughly how many people from DiALOGA will work on it?`,
    suggest1: 'I have all details ready',
    suggest2: 'Help me think through ROI',
    suggest3: 'What information do you need?',
    confirmTitle: 'Ready to apply to calculator',
    confirmSub: 'Review and adjust if needed, then click Apply.',
  },
  es: {
    phaseLabel: '00 · Estimación',
    phaseTitle: 'Estimación de costo y ROI del proyecto',
    phaseSub: 'Describe tu proyecto y la IA calculará el costo operativo y el ROI del primer año',
    startBtn: 'Iniciar estimación',
    skipBtn: 'Ingresar manualmente',
    continueBtn: 'Continuar a la calculadora →',
    applyBtn: 'Aplicar a la calculadora',
    applied: 'Aplicado ✓',
    resetBtn: 'Nueva estimación',
    placeholder: 'Describe el proyecto, equipo, herramientas, plazo y qué ganará el cliente…',
    send: 'Enviar',
    thinking: 'Analizando…',
    you: 'Tú',
    ai: 'IA',
    error: 'No se pudo contactar al modelo. Intenta de nuevo.',
    resultTitle: 'Resultados de estimación',
    costLabel: 'Costo operativo',
    roiLabel: 'ROI esperado a 1 año',
    dealLabel: 'Nombre del trato',
    editHint: 'Puedes ajustar estos valores antes de aplicar',
    welcome: `Bienvenido al estimador de proyectos DiALOGA.\n\nTe guiaré en una conversación estructurada para calcular:\n• **Costo operativo** — horas del equipo + herramientas + APIs + licencias\n• **ROI del cliente a 1 año** — tiempo ahorrado + gastos reducidos + ingresos generados\n\nCuéntame del proyecto. Un buen punto de partida: ¿qué hace, quién es el cliente y cuántas personas de DiALOGA trabajarán en él?`,
    suggest1: 'Tengo todos los detalles listos',
    suggest2: 'Ayúdame a pensar en el ROI',
    suggest3: '¿Qué información necesitas?',
    confirmTitle: 'Listo para aplicar a la calculadora',
    confirmSub: 'Revisa y ajusta si es necesario, luego haz clic en Aplicar.',
  },
};

// ── System prompt builder ────────────────────────────────────────────────
function buildEstimatorSystem(lang, userTurns = 0) {
  const isES = lang === 'es';
  const isExperienced = userTurns >= 4;
  return `You are DiALOGA's internal project estimation assistant. DiALOGA is an AI solutions company that builds custom AI integrations, automation workflows, and digital products for B2B clients.
Reply ALWAYS in ${isES ? 'Spanish' : 'English'}.

YOUR ROLE:
Guide the user through a structured conversation to produce two key numbers:
1. DiALOGA's OPERATIVE COST (USD) — what it costs DiALOGA to deliver the project
2. CLIENT'S FIRST-YEAR ROI (USD) — the quantified value the client gets in year 1

OPERATIVE COST FORMULA:
= (Sum of: employees × hours × hourly_rate) × (1 + safety_margin)
  + API usage fees for the project period
  + Tool/SaaS subscriptions prorated to the project
  + Direct licenses purchased for the project

- safety_margin: 20–25% (use 22% by default, adjust if project has high technical risk)
- REQUIRED before calculating: you MUST ask and receive the actual hourly cost ($/hr) for each role involved. Never use default rates — this number directly determines the floor price and must come from the user. Ask: "What is the hourly cost for each team member role? (e.g. Developer, PM, AI Engineer)"
- Hours should account for development + testing + deployment + documentation
- If the user mentions a timeframe (e.g. "2 months"), help estimate hours from it
- Add hourly_rate to the list of critical data required in STRICT MODE

CLIENT ROI FORMULA:
= (Hours saved per year × client's cost per hour)
  + Annual expenses eliminated by the solution
  + Direct revenue generated or enabled by the solution
  + Indirect revenue (conversion improvements, faster sales cycles, etc.)
  - Annual running costs for the client (API fees, DiALOGA retainer/subscription, energy, maintenance)

- Typical DiALOGA retainer: 15–20% of project cost per year (ask user to confirm)
- Always ask: what does the client currently pay for the process being replaced?
- Always ask: what is the client's approximate cost per employee hour?

CONVERSATION RULES:
- Ask ONE focused question at a time — never dump a long list
- Always show your reasoning: break down the numbers visibly
- When the user gives approximate numbers, round them conservatively (better to underestimate ROI and overestimate cost)
- Flag every assumption you make so the user can correct it
- If you notice a likely underestimate or overestimate, point it out with justification

STRICTNESS MODE — ${userTurns} user turns so far:
${isExperienced
  ? `RELAXED MODE (${userTurns} turns in): You may now make reasonable assumptions for missing data rather than blocking on questions. State each assumption explicitly inline, e.g. "Assuming 2 months development → ~320 dev hours". Proceed to produce the ESTIMATE_RESULT once you have the core numbers, even if some details are approximate.`
  : `STRICT MODE (early conversation, ${userTurns} turns in): Do NOT produce an ESTIMATE_RESULT yet — you are still gathering data. Ask one focused question. Critical data you MUST have before estimating: (1) project name/client, (2) rough scope or timeline, (3) team composition (roles + count), (4) hourly cost per role in USD — NEVER assume this, always ask, (5) at least one quantified ROI driver (hours saved, cost eliminated, or revenue enabled).`
}

WHEN READY — output the calculation in this exact block at the end of your message (nothing after it):

ESTIMATE_RESULT
DEAL: <project/client name>
COST: <integer USD>
ROI: <integer USD>
COST_BREAKDOWN: <2-3 sentence breakdown of cost components>
ROI_BREAKDOWN: <2-3 sentence breakdown of ROI components>
END_ESTIMATE

${isExperienced ? 'You may output ESTIMATE_RESULT now if you have enough to justify it.' : 'Do NOT output ESTIMATE_RESULT yet — gather more data first.'}`;
}

// ── Parse ESTIMATE_RESULT block ──────────────────────────────────────────
function parseEstimate(text) {
  const block = text.match(/ESTIMATE_RESULT\s*([\s\S]*?)\s*END_ESTIMATE/i);
  if (!block) return { clean: text, estimate: null };
  const raw = block[1];
  const get = (key) => { const m = raw.match(new RegExp(`^${key}:\\s*(.+)$`, 'im')); return m ? m[1].trim() : ''; };
  const cost = parseInt(get('COST').replace(/[^0-9]/g, ''), 10);
  const roi = parseInt(get('ROI').replace(/[^0-9]/g, ''), 10);
  if (!Number.isFinite(cost) || !Number.isFinite(roi)) return { clean: text, estimate: null };
  const estimate = {
    deal: get('DEAL'),
    cost,
    roi,
    costBreakdown: get('COST_BREAKDOWN'),
    roiBreakdown: get('ROI_BREAKDOWN'),
  };
  const clean = text.replace(block[0], '').trim();
  return { clean, estimate };
}

// ── Markdown-lite ────────────────────────────────────────────────────────
function EstMd({ text }) {
  const parts = text.split(/(\*\*[^*]+\*\*)/g);
  return (
    <>
      {parts.map((p, i) => {
        if (/^\*\*[^*]+\*\*$/.test(p)) return <strong key={i}>{p.slice(2, -2)}</strong>;
        return p.split('\n').map((line, j, arr) => (
          <React.Fragment key={`${i}-${j}`}>
            {line}{j < arr.length - 1 && <br />}
          </React.Fragment>
        ));
      })}
    </>
  );
}

// ── Message bubble ───────────────────────────────────────────────────────
function EstMessage({ role, text, t }) {
  return (
    <div className={`est-msg est-msg-${role}`}>
      <div className="est-avatar">{role === 'user' ? t.you : t.ai}</div>
      <div className="est-bubble"><EstMd text={text} /></div>
    </div>
  );
}

// ── Editable result card ─────────────────────────────────────────────────
function EstResultCard({ estimate, lang, onApply, t }) {
  const [deal, setDeal] = React.useState(estimate.deal || '');
  const [cost, setCost] = React.useState(estimate.cost);
  const [roi, setRoi] = React.useState(estimate.roi);
  const [applied, setApplied] = React.useState(false);

  const fmt = (n) => new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', maximumFractionDigits: 0 }).format(n);

  const handleApply = () => {
    onApply({ deal, cost, roi });
    setApplied(true);
  };

  return (
    <div className="est-result-card">
      <div className="est-result-header">
        <div className="est-result-title">{t.resultTitle}</div>
        <div className="est-result-hint">{t.editHint}</div>
      </div>

      <div className="est-result-field">
        <label className="est-result-label">{t.dealLabel}</label>
        <input className="est-result-input" value={deal} onChange={e => setDeal(e.target.value)} placeholder="Client · Project" />
      </div>

      <div className="est-result-row">
        <div className="est-result-field">
          <label className="est-result-label">{t.costLabel}</label>
          <div className="est-result-money">
            <span className="est-result-prefix">$</span>
            <input
              className="est-result-input mono"
              type="number"
              value={cost}
              onChange={e => setCost(parseInt(e.target.value) || 0)}
            />
          </div>
          {estimate.costBreakdown && <div className="est-breakdown">{estimate.costBreakdown}</div>}
        </div>
        <div className="est-result-field">
          <label className="est-result-label">{t.roiLabel}</label>
          <div className="est-result-money">
            <span className="est-result-prefix">$</span>
            <input
              className="est-result-input mono"
              type="number"
              value={roi}
              onChange={e => setRoi(parseInt(e.target.value) || 0)}
            />
          </div>
          {estimate.roiBreakdown && <div className="est-breakdown">{estimate.roiBreakdown}</div>}
        </div>
      </div>

      <div className="est-result-ratio">
        <span className="est-ratio-label">ROI/Cost ratio</span>
        <span className="est-ratio-value mono">{cost > 0 ? `${(roi / cost).toFixed(1)}×` : '—'}</span>
        <span className="est-ratio-label" style={{marginLeft:'16px'}}>Margin on ROI</span>
        <span className="est-ratio-value mono">{roi > 0 ? `${((roi - cost) / roi * 100).toFixed(1)}%` : '—'}</span>
      </div>

      <button
        className={`est-apply-btn ${applied ? 'is-applied' : ''}`}
        onClick={handleApply}
        disabled={applied}
      >
        {applied ? t.applied : t.applyBtn}
      </button>
    </div>
  );
}

// ── Main estimator component ─────────────────────────────────────────────
window.Estimator = function Estimator({ lang, modelSelection = 'standard', onApplyEstimate, onSkip, initialMessages = null, compact = false }) {
  const t = EST_STRINGS[lang] || EST_STRINGS.en;
  const [phase, setPhase] = React.useState(initialMessages ? 'chat' : 'landing'); // landing | chat | result
  const [messages, setMessages] = useEstState(initialMessages || []);
  const [input, setInput] = useEstState('');
  const [busy, setBusy] = useEstState(false);
  const [estimate, setEstimate] = useEstState(null);
  const scrollRef = useEstRef(null);
  const inputRef = useEstRef(null);

  useEstEffect(() => {
    if (scrollRef.current) scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
  }, [messages, busy]);

  useEstEffect(() => {
    if (phase === 'chat' && inputRef.current) {
      setTimeout(() => inputRef.current?.focus(), 150);
    }
  }, [phase]);

  const startChat = () => {
    setPhase('chat');
    setMessages([{ role: 'assistant', text: t.welcome }]);
  };

  const send = async (text) => {
    const trimmed = (text ?? input).trim();
    if (!trimmed || busy) return;
    setInput(''); // FIX 1: clear immediately before async work
    const next = [...messages, { role: 'user', text: trimmed }];
    setMessages(next);
    if (compact) { window._drawerMessages = next; } else { window._estimatorMessages = next; }
    setBusy(true);
    try {
      const userTurns = next.filter(m => m.role === 'user').length;
      const system = buildEstimatorSystem(lang, userTurns);
      const apiMessages = next.map(m => ({ role: m.role === 'user' ? 'user' : 'assistant', content: m.text }));

      const confirmationText = lang === 'es'
        ? 'Entendido. Seguiré estas instrucciones al pie de la letra y responderé en español.'
        : 'Understood. I will follow these instructions and reply in English.';

      const messages = [
        { role: 'user', content: system },
        { role: 'assistant', content: confirmationText },
        ...apiMessages,
      ];
      const response = await fetch('/api/chat', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ messages, modelSelection }),
      });
      const data = await response.json();
      if (!response.ok) {
        console.error('Chat API error:', response.status, JSON.stringify(data));
        throw new Error(data?.error || 'API error ' + response.status);
      }
      const raw = data?.response || t.error;
      const { clean, estimate: est } = parseEstimate(raw);
      const botMsg = { role: 'assistant', text: clean || raw };
      setMessages(prev => { const updated = [...prev, botMsg]; if (compact) { window._drawerMessages = updated; } else { window._estimatorMessages = updated; } return updated; });
      if (est) {
        setEstimate(est);
        onApplyEstimate({ deal: est.deal, cost: est.cost, roi: est.roi, costBreakdown: est.costBreakdown, roiBreakdown: est.roiBreakdown });
        if (!compact) {
          // Full page: transition to result card
          setTimeout(() => setPhase('result'), 400);
        }
        // compact=true: stay in chat — confirmation already in the AI message
      }
    } catch {
      setMessages(prev => [...prev, { role: 'assistant', text: t.error }]);
    } finally {
      setBusy(false);
    }
  };

  const handleApply = (vals) => {
    onApplyEstimate(vals);
    // scroll to calculator section after short delay
    setTimeout(() => {
      const el = document.querySelector('.calculator-root');
      if (el) el.scrollIntoView({ behavior: 'smooth' });
    }, 300);
  };

  const reset = () => {
    setPhase('landing');
    setMessages([]);
    setEstimate(null);
    setInput('');
  };

  // ── Landing ──
  if (phase === 'landing') {
    return (
      <section className="est-landing">
        <div className="est-landing-inner">
          <div className="est-phase-eyebrow">{t.phaseLabel}</div>
          <h2 className="est-phase-title">{t.phaseTitle}</h2>
          <p className="est-phase-sub">{t.phaseSub}</p>
          <div className="est-landing-actions">
            <button className="est-btn-primary" onClick={startChat}>{t.startBtn}</button>
            <button className="est-btn-ghost" onClick={onSkip}>{t.skipBtn}</button>
          </div>
        </div>
        <div className="est-landing-diagram" aria-hidden="true">
          <div className="est-diagram-node node-a">
            <div className="est-node-label">Project brief</div>
          </div>
          <div className="est-diagram-arrow">→</div>
          <div className="est-diagram-node node-b">
            <div className="est-node-label">AI analysis</div>
          </div>
          <div className="est-diagram-arrow">→</div>
          <div className="est-diagram-node node-c">
            <div className="est-node-label">Cost + ROI</div>
          </div>
          <div className="est-diagram-arrow">→</div>
          <div className="est-diagram-node node-d">
            <div className="est-node-label">Calculator</div>
          </div>
        </div>
      </section>
    );
  }

  // ── Result ──
  if (phase === 'result' && estimate) {
    return (
      <section className="est-result-section">
        <div className="est-result-header-bar">
          <div>
            <div className="est-phase-eyebrow">{t.phaseLabel}</div>
            <h2 className="est-phase-title">{t.confirmTitle}</h2>
            <p className="est-phase-sub">{t.confirmSub}</p>
          </div>
          <button className="est-btn-ghost small" onClick={reset}>{t.resetBtn}</button>
        </div>
        <EstResultCard estimate={estimate} lang={lang} onApply={handleApply} t={t} />
        <div className="est-result-continue">
          <button className="est-continue-btn" onClick={() => { handleApply({ deal: estimate.deal, cost: estimate.cost, roi: estimate.roi }); }}>
            {t.continueBtn}
          </button>
        </div>
      </section>
    );
  }

  // ── Chat ──
  const suggestions = [t.suggest1, t.suggest2, t.suggest3];
  return (
    <section className={compact ? 'est-chat-section est-chat-compact' : 'est-chat-section'}>
      {!compact && <div className="est-chat-header">
        <div>
          <div className="est-phase-eyebrow">{t.phaseLabel}</div>
          <h2 className="est-phase-title">{t.phaseTitle}</h2>
        </div>
        <button className="est-btn-ghost small" onClick={onSkip}>{t.skipBtn}</button>
      </div>}

      <div className="est-chat-scroll" ref={scrollRef}>
        {messages.map((m, i) => (
          <EstMessage key={i} role={m.role} text={m.text} t={t} />
        ))}
        {messages.length === 1 && !busy && (
          <div className="est-suggestions">
            {suggestions.map(s => (
              <button key={s} className="est-suggestion" onClick={() => send(s)}>{s}</button>
            ))}
          </div>
        )}
        {busy && (
          <div className="est-msg est-msg-assistant">
            <div className="est-avatar">{t.ai}</div>
            <div className="est-bubble est-thinking">
              <span className="est-dot" /><span className="est-dot" /><span className="est-dot" />
            </div>
          </div>
        )}
      </div>

      <div className="est-chat-input-row">
        <textarea
          ref={inputRef}
          className="est-chat-input"
          placeholder={t.placeholder}
          value={input}
          onChange={e => setInput(e.target.value)}
          onKeyDown={e => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); send(); } }}
          rows={2}
          disabled={busy}
        />
        <button className="est-send-btn" onClick={() => send()} disabled={busy || !input.trim()}>
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <path d="M22 2L11 13M22 2l-7 20-4-9-9-4 20-7z"/>
          </svg>
        </button>
      </div>
    </section>
  );
};
