import { useState } from 'react';

interface QuoteItem {
  id: string;
  productId: string;
  sku: string | null;
  nameSnapshot: string;
  quantity: number;
  priceWithoutVatSnapshot: number;
  subtotal: number;
  tax: number;
  total: number;
}
interface Quote {
  id: string;
  status: string;
  requestedM2: number | null;
  postalCode: string | null;
  useCase: string | null;
  subtotal: number;
  tax: number;
  shippingEstimate: number | null;
  total: number;
  notesPublic?: string | null;
  notesInternal?: string | null;
  items: QuoteItem[];
}
interface ProductOpt {
  id: string;
  name: string;
  sku: string | null;
  price: number | null;
}
interface Props {
  quote: Quote;
  statuses: string[];
  statusLabels: Record<string, string>;
  contactName: string;
  companyName: string;
  products: ProductOpt[];
}

const money = new Intl.NumberFormat('es-MX', { style: 'currency', currency: 'MXN' });
const LOCKED = ['sent', 'approved', 'payment_pending', 'paid'];

export default function QuoteEditor({
  quote: initial,
  statuses,
  statusLabels,
  contactName,
  companyName,
  products,
}: Props) {
  const [quote, setQuote] = useState(initial);
  const [status, setStatus] = useState(initial.status);
  const [postalCode, setPostalCode] = useState(initial.postalCode ?? '');
  const [useCase, setUseCase] = useState(initial.useCase ?? '');
  const [shipping, setShipping] = useState(
    initial.shippingEstimate != null ? String(initial.shippingEstimate) : '',
  );
  const [notesInternal, setNotesInternal] = useState(initial.notesInternal ?? '');
  const [notesPublic, setNotesPublic] = useState(initial.notesPublic ?? '');

  const [addProduct, setAddProduct] = useState(products[0]?.id ?? '');
  const [addQty, setAddQty] = useState('1');
  const [busy, setBusy] = useState(false);
  const [msg, setMsg] = useState<{ text: string; ok: boolean } | null>(null);

  function flash(text: string, ok = true) {
    setMsg({ text, ok });
    setTimeout(() => setMsg(null), 3500);
  }
  async function api(url: string, method: string, body?: unknown) {
    const res = await fetch(url, {
      method,
      headers: body ? { 'content-type': 'application/json' } : undefined,
      body: body ? JSON.stringify(body) : undefined,
    });
    return res.json();
  }

  async function saveHeader() {
    setBusy(true);
    const json = await api(`/api/crm/quotes/${quote.id}`, 'PATCH', {
      status,
      postalCode: postalCode || null,
      useCase: useCase || null,
      shippingEstimate: shipping === '' ? null : Number(shipping),
      notesInternal: notesInternal || null,
      notesPublic: notesPublic || null,
    });
    setBusy(false);
    if (json.ok) {
      setQuote(json.data);
      setStatus(json.data.status);
      flash('Cotización guardada.');
    } else {
      flash(json.error || 'No se pudo guardar.', false);
    }
  }

  async function addItem() {
    const product = products.find((p) => p.id === addProduct);
    if (!product) return;
    const qty = Number(addQty);
    if (!qty || qty <= 0) {
      flash('Cantidad inválida.', false);
      return;
    }
    setBusy(true);
    const body: Record<string, unknown> = { productId: addProduct, quantity: qty };
    if (product.price == null) {
      const manual = window.prompt(`"${product.name}" no tiene precio fijo. Precio unitario sin IVA:`);
      if (!manual) {
        setBusy(false);
        return;
      }
      body.unitPriceWithoutVat = Number(manual);
    }
    const json = await api(`/api/crm/quotes/${quote.id}/items`, 'POST', body);
    setBusy(false);
    if (json.ok) {
      syncFrom(json.data);
      setAddQty('1');
      flash('Producto agregado.');
    } else {
      flash(json.error || 'No se pudo agregar.', false);
    }
  }

  async function updateItem(itemId: string, quantity: number, unitPrice: number) {
    setBusy(true);
    const json = await api(`/api/crm/quotes/${quote.id}/items/${itemId}`, 'PATCH', {
      quantity,
      unitPriceWithoutVat: unitPrice,
    });
    setBusy(false);
    if (json.ok) syncFrom(json.data);
    else flash(json.error || 'No se pudo actualizar.', false);
  }

  async function removeItem(itemId: string) {
    if (!window.confirm('¿Quitar este producto de la cotización?')) return;
    setBusy(true);
    const json = await api(`/api/crm/quotes/${quote.id}/items/${itemId}`, 'DELETE');
    setBusy(false);
    if (json.ok) {
      syncFrom(json.data);
      flash('Producto quitado.');
    } else flash(json.error || 'No se pudo quitar.', false);
  }

  function syncFrom(q: Quote) {
    setQuote(q);
    setStatus(q.status);
    setShipping(q.shippingEstimate != null ? String(q.shippingEstimate) : '');
  }

  const wasLocked = LOCKED.includes(initial.status);

  return (
    <div>
      {msg && (
        <p className="notice" style={{ marginBottom: 16, color: msg.ok ? 'var(--pf-success)' : '#ff7a8a' }}>
          {msg.text}
        </p>
      )}

      <div style={{ display: 'grid', gap: 16 }}>
        {/* ---- Encabezado editable ---- */}
        <div className="card" style={{ padding: 18 }}>
          <h2 style={{ fontSize: '1.1rem' }}>Datos de la cotización</h2>
          <div className="muted" style={{ fontSize: '.85rem', marginBottom: 12 }}>
            {quote.id} · Contacto: <strong style={{ color: 'var(--pf-text)' }}>{contactName}</strong>
            {companyName !== '—' && <> · {companyName}</>}
          </div>
          {wasLocked && (
            <p className="notice" style={{ marginBottom: 12 }}>
              Esta cotización está <strong>{statusLabels[initial.status] ?? initial.status}</strong>. Si cambias
              montos o items, volverá a <strong>Calculada</strong> (edición segura), salvo que elijas un estatus
              manualmente.
            </p>
          )}
          <div className="field">
            <label>Estatus</label>
            <select className="select" value={status} onChange={(e) => setStatus(e.target.value)}>
              {statuses.map((s) => (
                <option key={s} value={s}>
                  {statusLabels[s] ?? s}
                </option>
              ))}
            </select>
          </div>
          <div style={{ display: 'flex', gap: 10 }}>
            <div className="field" style={{ flex: 1 }}>
              <label>Código postal</label>
              <input
                className="input"
                inputMode="numeric"
                maxLength={5}
                value={postalCode}
                onChange={(e) => setPostalCode(e.target.value.replace(/\D/g, ''))}
              />
            </div>
            <div className="field" style={{ flex: 1 }}>
              <label>Envío estimado (MXN)</label>
              <input
                className="input"
                type="number"
                inputMode="decimal"
                value={shipping}
                onChange={(e) => setShipping(e.target.value)}
                placeholder="Pendiente"
              />
            </div>
          </div>
          <div className="field">
            <label>Uso del espacio</label>
            <input className="input" value={useCase} onChange={(e) => setUseCase(e.target.value)} />
          </div>
          <div className="field">
            <label>Notas internas (no visibles al cliente)</label>
            <textarea
              className="textarea"
              rows={2}
              value={notesInternal}
              onChange={(e) => setNotesInternal(e.target.value)}
            />
          </div>
          <div className="field">
            <label>Notas para el cliente</label>
            <textarea
              className="textarea"
              rows={2}
              value={notesPublic}
              onChange={(e) => setNotesPublic(e.target.value)}
            />
          </div>
          <button className="btn btn-primary" disabled={busy} onClick={saveHeader}>
            {busy ? 'Guardando…' : 'Guardar cotización'}
          </button>
        </div>

        {/* ---- Items ---- */}
        <div className="card" style={{ padding: 18 }}>
          <h2 style={{ fontSize: '1.1rem' }}>Productos ({quote.items.length})</h2>

          {quote.items.length === 0 && (
            <p className="muted" style={{ fontSize: '.85rem' }}>
              Sin productos. Agrega uno abajo para calcular la cotización.
            </p>
          )}

          <div style={{ display: 'flex', flexDirection: 'column', gap: 10, margin: '10px 0' }}>
            {quote.items.map((it) => (
              <ItemRow key={it.id} item={it} busy={busy} onUpdate={updateItem} onRemove={removeItem} />
            ))}
          </div>

          {/* Agregar producto */}
          <div style={{ borderTop: '1px solid var(--pf-border)', paddingTop: 12 }}>
            <div className="field" style={{ marginBottom: 8 }}>
              <label>Agregar producto</label>
              <select className="select" value={addProduct} onChange={(e) => setAddProduct(e.target.value)}>
                {products.map((p) => (
                  <option key={p.id} value={p.id}>
                    {p.name}
                    {p.price != null ? ` — ${money.format(p.price)}` : ' — (precio a definir)'}
                  </option>
                ))}
              </select>
            </div>
            <div style={{ display: 'flex', gap: 8 }}>
              <input
                className="input"
                type="number"
                inputMode="decimal"
                min={1}
                value={addQty}
                onChange={(e) => setAddQty(e.target.value)}
                style={{ maxWidth: 120 }}
                aria-label="Cantidad"
              />
              <button className="btn btn-secondary" style={{ width: 'auto' }} disabled={busy} onClick={addItem}>
                + Agregar
              </button>
            </div>
          </div>
        </div>

        {/* ---- Totales ---- */}
        <div className="card" style={{ padding: 18 }}>
          <h2 style={{ fontSize: '1.1rem' }}>Totales</h2>
          <Row label="Subtotal" value={money.format(quote.subtotal)} />
          <Row label="IVA (16%)" value={money.format(quote.tax)} />
          <Row label="Envío" value={quote.shippingEstimate != null ? money.format(quote.shippingEstimate) : 'Pendiente'} />
          <div
            style={{
              display: 'flex',
              justifyContent: 'space-between',
              alignItems: 'center',
              marginTop: 8,
              paddingTop: 10,
              borderTop: '1px solid var(--pf-border)',
            }}
          >
            <span className="muted">Total</span>
            <strong style={{ fontFamily: 'var(--pf-font-head)', fontSize: '1.6rem' }}>
              {money.format(quote.total)}
            </strong>
          </div>
        </div>
      </div>
    </div>
  );
}

function Row({ label, value }: { label: string; value: string }) {
  return (
    <div style={{ display: 'flex', justifyContent: 'space-between', padding: '5px 0', fontSize: '.92rem' }}>
      <span className="muted">{label}</span>
      <span>{value}</span>
    </div>
  );
}

function ItemRow({
  item,
  busy,
  onUpdate,
  onRemove,
}: {
  item: QuoteItem;
  busy: boolean;
  onUpdate: (id: string, qty: number, price: number) => void;
  onRemove: (id: string) => void;
}) {
  const [qty, setQty] = useState(String(item.quantity));
  const [price, setPrice] = useState(String(item.priceWithoutVatSnapshot));

  function commit() {
    const q = Number(qty);
    const p = Number(price);
    if (q > 0 && p >= 0 && (q !== item.quantity || p !== item.priceWithoutVatSnapshot)) {
      onUpdate(item.id, q, p);
    }
  }

  return (
    <div style={{ border: '1px solid var(--pf-border)', borderRadius: 8, padding: 10 }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', gap: 8 }}>
        <strong style={{ fontSize: '.9rem' }}>{item.nameSnapshot}</strong>
        <button className="chip" style={{ cursor: 'pointer' }} disabled={busy} onClick={() => onRemove(item.id)}>
          🗑
        </button>
      </div>
      {item.sku && (
        <div className="muted" style={{ fontSize: '.72rem' }}>
          SKU: {item.sku}
        </div>
      )}
      <div style={{ display: 'flex', gap: 8, marginTop: 8, alignItems: 'flex-end' }}>
        <label style={{ fontSize: '.72rem', flex: 1 }}>
          <span className="muted">Cantidad</span>
          <input
            className="input"
            type="number"
            inputMode="decimal"
            min={1}
            value={qty}
            onChange={(e) => setQty(e.target.value)}
            onBlur={commit}
            style={{ minHeight: 40 }}
          />
        </label>
        <label style={{ fontSize: '.72rem', flex: 1 }}>
          <span className="muted">P. unitario s/IVA</span>
          <input
            className="input"
            type="number"
            inputMode="decimal"
            min={0}
            value={price}
            onChange={(e) => setPrice(e.target.value)}
            onBlur={commit}
            style={{ minHeight: 40 }}
          />
        </label>
        <div style={{ textAlign: 'right', fontSize: '.8rem' }}>
          <div className="muted">Importe</div>
          <strong>{new Intl.NumberFormat('es-MX', { style: 'currency', currency: 'MXN' }).format(item.total)}</strong>
        </div>
      </div>
    </div>
  );
}
