// ui.jsx — shared components: Money, Tag, Card, PageHead, etc
window.NA = window.NA || {};
const { useState, useEffect, useRef, useMemo, useCallback } = React;

// ============================================================
// ICON — uses Lucide. Force re-render after mount.
// ============================================================
function Icon({ name, size = 16, color, style }) {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    // React owns this stable <span>; Lucide only replaces the inner <i> it
    // injects via innerHTML (a node React does NOT track). This prevents the
    // "removeChild: node is not a child" crash when React unmounts a subtree
    // whose <i data-lucide> had already been swapped for an <svg> by Lucide.
    el.innerHTML = '<i data-lucide="' + name + '" style="width:' + size + 'px;height:' + size + 'px;display:inline-flex"></i>';
    if (window.lucide) {
      try { window.lucide.createIcons({ nameAttr: 'data-lucide' }); } catch (e) {}
    }
  }, [name, size, color]);
  return (
    <span ref={ref} className="na-icon"
       style={{ width: size, height: size, display: "inline-flex", alignItems: "center", justifyContent: "center", color, ...style }}></span>
  );
}

// ============================================================
// MONEY — respects hide-sensitive (CSS handles blur)
// ============================================================
function Money({ value, lang = "pt", className = "", style }) {
  return (
    <span className={"money mono " + className} style={style}>
      {window.NA.fmtMoney(value, lang)}
    </span>
  );
}

// ============================================================
// TAG
// ============================================================
function Tag({ kind = "default", children, dot, icon }) {
  return (
    <span className={"tag " + kind}>
      {dot && <span className="dot" style={{ background: "currentColor" }}></span>}
      {icon && <Icon name={icon} size={12} />}
      {children}
    </span>
  );
}

// Status tag w/ presets
function StatusTag({ status, lang }) {
  const map = {
    active: { kind: "success", icon: null, dot: true },
    inactive: { kind: "default", dot: true },
    pending: { kind: "warning", dot: true },
    overdue: { kind: "error", dot: true },
    settled: { kind: "success", dot: true },
    in_process: { kind: "processing", dot: true },
    in_stock: { kind: "info", dot: true },
    in_settlement: { kind: "warning", dot: true },
    sold: { kind: "default", dot: true },
    trial: { kind: "info", dot: true },
    expired: { kind: "error", dot: true },
    approved: { kind: "success", dot: true },
    rejected: { kind: "error", dot: true },
    draft: { kind: "default", dot: true },
    converted: { kind: "info", dot: true },
  };
  const c = map[status] || { kind: "default" };
  return <Tag kind={c.kind} dot={c.dot}>{window.NA.t("status_" + status, lang)}</Tag>;
}

// ============================================================
// CARD
// ============================================================
function Card({ children, className = "", padded, style, ...rest }) {
  return <div className={"card " + (padded ? "padded " : "") + className} style={style} {...rest}>{children}</div>;
}
function CardHead({ title, icon, right, children }) {
  return (
    <div className="card-head">
      <h3>{icon && <Icon name={icon} size={14} />}{title}{children}</h3>
      {right && <div className="right">{right}</div>}
    </div>
  );
}
function CardBody({ children, style, className = "" }) {
  return <div className={"card-body " + className} style={style}>{children}</div>;
}

// ============================================================
// PAGE HEAD
// ============================================================
function PageHead({ icon, title, subtitle, right }) {
  return (
    <div className="page-head">
      <div className="h">
        <h1>{icon && <Icon name={icon} size={20} />} {title}</h1>
        {subtitle && <div className="sub">{subtitle}</div>}
      </div>
      {right && <div className="right">{right}</div>}
    </div>
  );
}

// ============================================================
// STAT
// ============================================================
function Stat({ label, icon, value, hint, delta, deltaDir, accent, isMoney, lang, suffix }) {
  return (
    <div className={"stat " + (accent ? "accent-" + accent : "")}>
      <div className="label">{icon && <Icon name={icon} size={14} />}{label}</div>
      <div className="num">
        {isMoney ? <Money value={value} lang={lang} /> : (typeof value === "number" ? window.NA.fmtInt(value) : value)}
        {suffix && <span style={{ fontSize: 13, color: "var(--fg3)", marginLeft: 4 }}>{suffix}</span>}
      </div>
      {delta && (
        <div className={"delta " + (deltaDir || "")}>
          <Icon name={deltaDir === "up" ? "trending-up" : deltaDir === "dn" ? "trending-down" : "minus"} size={12} />
          {delta}
        </div>
      )}
      {hint && <div className="hint">{hint}</div>}
    </div>
  );
}

// ============================================================
// BUTTON
// ============================================================
function Button({ kind = "default", size, icon, children, onClick, disabled, style, className = "" }) {
  return (
    <button
      className={"btn " + kind + (size ? " " + size : "") + " " + className}
      onClick={onClick} disabled={disabled} style={style}
    >
      {icon && <Icon name={icon} size={size === "sm" ? 12 : 14} />}
      {children}
    </button>
  );
}

// ============================================================
// SEARCH BOX
// ============================================================
function SearchBox({ placeholder, value, onChange, style }) {
  return (
    <div className="search-box" style={style}>
      <Icon name="search" size={14} />
      <input placeholder={placeholder} value={value || ""} onChange={(e) => onChange && onChange(e.target.value)} />
    </div>
  );
}

// ============================================================
// FIELD / INPUT
// ============================================================
function Field({ label, required, hint, children, style }) {
  return (
    <div className="field" style={style}>
      {label && <label>{label}{required && <span className="req">*</span>}</label>}
      {children}
      {hint && <div className="hint">{hint}</div>}
    </div>
  );
}
function Input({ value, onChange, placeholder, type = "text", mono, style, ...rest }) {
  return (
    <input className={"input" + (mono ? " mono" : "")} type={type}
      value={value || ""}
      onChange={(e) => onChange && onChange(e.target.value)}
      placeholder={placeholder} style={style} {...rest} />
  );
}
function Select({ value, onChange, options, style, placeholder }) {
  return (
    <select className="input" value={value || ""} onChange={(e) => onChange && onChange(e.target.value)} style={style}>
      {placeholder && <option value="">{placeholder}</option>}
      {options.map((o) =>
        typeof o === "string"
          ? <option key={o} value={o}>{o}</option>
          : <option key={o.value} value={o.value}>{o.label}</option>
      )}
    </select>
  );
}
function Textarea({ value, onChange, placeholder, rows = 3, style }) {
  return (
    <textarea className="input" rows={rows} value={value || ""}
      onChange={(e) => onChange && onChange(e.target.value)}
      placeholder={placeholder} style={style} />
  );
}

// ============================================================
// TABS
// ============================================================
function Tabs({ tabs, active, onChange }) {
  return (
    <div className="tabs">
      {tabs.map((t) => (
        <div key={t.key} className={"tab " + (active === t.key ? "active" : "")}
             onClick={() => onChange(t.key)}
             onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); onChange(t.key); } }}
             role="button" tabIndex={0}>
          {t.icon && <Icon name={t.icon} size={14} style={{ marginRight: 6 }} />}
          {t.label}
        </div>
      ))}
    </div>
  );
}

// Segmented control
function Segmented({ value, onChange, options }) {
  return (
    <div className="seg">
      {options.map(o => {
        const v = typeof o === "string" ? o : o.value;
        const l = typeof o === "string" ? o : o.label;
        return <button key={v} className={value === v ? "on" : ""} onClick={() => onChange(v)}>{l}</button>;
      })}
    </div>
  );
}

// ============================================================
// PROGRESS
// ============================================================
function Progress({ value, kind = "primary", height = 6 }) {
  return (
    <div className="progress" style={{ height }}>
      <div className={"bar " + (kind !== "primary" ? kind : "")} style={{ width: Math.max(0, Math.min(100, value)) + "%" }}></div>
    </div>
  );
}

// ============================================================
// SWITCH
// ============================================================
function Switch({ on, onChange }) {
  return <div className={"switch" + (on ? " on" : "")} onClick={() => onChange && onChange(!on)}
    onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); onChange && onChange(!on); } }}
    role="switch" aria-checked={!!on} tabIndex={0}></div>;
}

// ============================================================
// AVATAR
// ============================================================
function Avatar({ name, size = "" , color = "" }) {
  const initials = (name || "").split(" ").filter(Boolean).slice(0, 2).map(w => w[0]).join("").toUpperCase() || "?";
  return <span className={"av " + size + " " + color}>{initials}</span>;
}

// ============================================================
// VEHICLE THUMB
// ============================================================
function VehicleThumb({ vehicle, hideThumb }) {
  return (
    <div className="veh-thumb">
      {!hideThumb && <Icon name="car" size={36} />}
      {vehicle && vehicle.plate && <span className="plate">{vehicle.plate}</span>}
    </div>
  );
}

// ============================================================
// EMPTY STATE
// ============================================================
function Empty({ icon = "inbox", title, message, action }) {
  return (
    <div className="empty">
      <Icon name={icon} size={32} />
      {title && <h3>{title}</h3>}
      {message && <p>{message}</p>}
      {action}
    </div>
  );
}

// ============================================================
// MINI CHART — pure SVG, no deps
// ============================================================
function BarChart({ data, color = "var(--color-primary)", height = 120, formatter }) {
  if (!data || !data.length) return <div className="empty"><p>Sem dados</p></div>;
  const max = Math.max(...data.map(d => d.value), 1);
  const w = 100 / data.length;
  return (
    <div style={{ position: "relative", height, width: "100%" }}>
      <svg width="100%" height={height} viewBox={`0 0 100 ${height}`} preserveAspectRatio="none">
        {data.map((d, i) => {
          const h = (d.value / max) * (height - 30);
          return (
            <g key={i}>
              <rect x={i * w + w * 0.18} y={height - 20 - h} width={w * 0.64} height={h}
                fill={d.color || color} rx="1" />
            </g>
          );
        })}
      </svg>
      <div style={{ display: "flex", position: "absolute", left: 0, right: 0, bottom: 0,
                    fontFamily: "var(--font-mono)", fontSize: 9, color: "var(--fg3)" }}>
        {data.map((d, i) => (
          <div key={i} style={{ flex: 1, textAlign: "center" }}>{d.label}</div>
        ))}
      </div>
    </div>
  );
}

function LineChart({ data, color = "var(--color-primary)", height = 140, fill = true }) {
  if (!data || !data.length) return null;
  const max = Math.max(...data.map(d => d.value), 1);
  const min = Math.min(...data.map(d => d.value), 0);
  const range = max - min || 1;
  const W = 100, H = height - 24;
  const pts = data.map((d, i) => {
    const x = (i / (data.length - 1 || 1)) * W;
    const y = H - ((d.value - min) / range) * H;
    return [x, y];
  });
  const path = pts.map(([x, y], i) => (i ? "L" : "M") + x + " " + y).join(" ");
  const area = path + ` L ${W} ${H} L 0 ${H} Z`;
  return (
    <div style={{ position: "relative", height, width: "100%" }}>
      <svg width="100%" height={H} viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="none">
        {fill && <path d={area} fill={color} opacity="0.12" />}
        <path d={path} stroke={color} strokeWidth="0.6" fill="none" />
      </svg>
      <div style={{ display: "flex", fontFamily: "var(--font-mono)", fontSize: 9, color: "var(--fg3)", marginTop: 4 }}>
        {data.map((d, i) => (
          <div key={i} style={{ flex: 1, textAlign: i === 0 ? "left" : i === data.length - 1 ? "right" : "center" }}>{d.label}</div>
        ))}
      </div>
    </div>
  );
}

// ============================================================
// OVERLAY HELPERS — focus trap + Esc
// ============================================================
function useOverlayKeyboard(open, onClose, panelRef) {
  useEffect(() => {
    if (!open) return;
    function onKey(e) {
      if (e.key === "Escape") { e.preventDefault(); onClose && onClose(); return; }
      if (e.key !== "Tab" || !panelRef.current) return;
      const focusable = panelRef.current.querySelectorAll(
        'button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'
      );
      if (!focusable.length) return;
      const first = focusable[0];
      const last = focusable[focusable.length - 1];
      if (e.shiftKey && document.activeElement === first) { e.preventDefault(); last.focus(); }
      else if (!e.shiftKey && document.activeElement === last) { e.preventDefault(); first.focus(); }
    }
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [open, onClose, panelRef]);
}

function clickKey(onClick) {
  return (e) => {
    if (e.key === "Enter" || e.key === " ") { e.preventDefault(); onClick && onClick(e); }
  };
}

// ============================================================
// MODAL
// ============================================================
function Modal({ open, onClose, title, children, footer, width = 520 }) {
  const panelRef = useRef(null);
  useOverlayKeyboard(open, onClose, panelRef);
  useEffect(() => {
    if (open && panelRef.current) {
      const el = panelRef.current.querySelector("input, button, select, textarea");
      if (el) el.focus();
    }
  }, [open]);
  if (!open) return null;
  return (
    <div className="na-modal-mask" onClick={onClose} role="presentation">
      <div ref={panelRef} className="na-modal-panel" style={{ width, maxWidth: "90vw" }}
        onClick={(e) => e.stopPropagation()} role="dialog" aria-modal="true"
        aria-labelledby={title ? "na-modal-title" : undefined}>
        {title && (
          <div className="na-modal-head">
            <h2 id="na-modal-title">{title}</h2>
            <button type="button" className="icon-btn" onClick={onClose} aria-label="Close">
              <Icon name="x" size={16} />
            </button>
          </div>
        )}
        <div className="na-modal-body">{children}</div>
        {footer && <div className="na-modal-foot">{footer}</div>}
      </div>
    </div>
  );
}

// ============================================================
// DRAWER — vehicle detail panel (480px)
// ============================================================
function VehicleDrawer({ open, vehicle, onClose, lang, setT, t }) {
  const panelRef = useRef(null);
  useOverlayKeyboard(open, onClose, panelRef);
  useEffect(() => {
    if (open && panelRef.current) {
      const btn = panelRef.current.querySelector("button");
      if (btn) btn.focus();
    }
  }, [open, vehicle]);
  if (!open || !vehicle) return null;
  const tr = t || ((k) => window.NA.t(k, lang));
  const go = (module) => { if (setT) setT({ module }); onClose && onClose(); };

  return (
    <div className="na-drawer-mask" onClick={onClose} role="presentation">
      <aside ref={panelRef} className="na-drawer-panel" onClick={(e) => e.stopPropagation()}
        role="dialog" aria-modal="true" aria-label={vehicle.plate}>
        <div className="na-drawer-head">
          <div>
            <div className="row gap-8 mb-8">
              <span className="chip mono fw-600">{vehicle.plate}</span>
              <StatusTag status={vehicle.status} lang={lang} />
            </div>
            <div className="fw-600 fs-16">{vehicle.brand} {vehicle.model}</div>
            <div className="text-faint fs-12">{vehicle.year} · {vehicle.owner}</div>
          </div>
          <button type="button" className="icon-btn" onClick={onClose} aria-label="Close">
            <Icon name="x" size={16} />
          </button>
        </div>
        <div className="na-drawer-body">
          <div className="kv">
            <span className="k">{tr("common_bank")}</span><span className="v">{vehicle.bank}</span>
            <span className="k">{lang === "pt" ? "Compra" : "Purchase"}</span><span className="v"><Money value={vehicle.purchasePrice} lang={lang} /></span>
            <span className="k">{lang === "pt" ? "Quitação" : "Settlement"}</span><span className="v"><Money value={vehicle.settlementValue} lang={lang} /></span>
            <span className="k">{lang === "pt" ? "Valor cliente" : "Client value"}</span><span className="v"><Money value={vehicle.clientValue} lang={lang} /></span>
            <span className="k">{lang === "pt" ? "Parcelas" : "Installments"}</span>
            <span className="v">{vehicle.parcels.paid}/{vehicle.parcels.total}{vehicle.parcels.overdue ? ` (+${vehicle.parcels.overdue} ${lang === "pt" ? "atras." : "overdue"})` : ""}</span>
            <span className="k">{lang === "pt" ? "Aquisição" : "Acquired"}</span><span className="v">{vehicle.acquiredOn}</span>
            <span className="k">{lang === "pt" ? "Rastreador" : "Tracker"}</span>
            <span className="v">{vehicle.trackerStatus === "active" ? (lang === "pt" ? "Ativo" : "Active") : (lang === "pt" ? "Inativo" : "Inactive")}</span>
          </div>
          {vehicle.maintenance && vehicle.maintenance.length > 0 && (
            <div style={{ marginTop: 16 }}>
              <div className="fs-11 fw-600 text-faint mb-8" style={{ textTransform: "uppercase", letterSpacing: "0.06em" }}>
                {lang === "pt" ? "Manutenção pendente" : "Pending maintenance"}
              </div>
              <div className="col gap-4">
                {vehicle.maintenance.map((m, i) => (
                  <div key={i} className="row gap-8 fs-12"><Icon name="wrench" size={12} style={{ color: "var(--fg3)" }} />{m}</div>
                ))}
              </div>
            </div>
          )}
        </div>
        <div className="na-drawer-foot">
          <Button kind="default" icon="scale" onClick={() => go("lawyer")}>{tr("nav_lawyer")}</Button>
          <Button kind="default" icon="wrench" onClick={() => go("maintenance")}>{tr("nav_maintenance")}</Button>
          <Button kind="primary" icon="credit-card" onClick={() => go("financing")}>{tr("nav_financing")}</Button>
        </div>
      </aside>
    </div>
  );
}

// ============================================================
// VEHICLE TABLE — reusable list with filters
// ============================================================
function VehicleTable({
  vehicles = [],
  columns,
  lang,
  t,
  onRowClick,
  selectedId,
  empty,
  filters,
  countLabel,
}) {
  const tr = t || ((k) => window.NA.t(k, lang));
  const cols = columns || vehicleTableColumnsOpportunities(tr, lang);

  return (
    <div>
      {filters && (
        <div style={{ display: "grid", gridTemplateColumns: filters.grid || "1fr 160px 160px", gap: 12, marginBottom: 12 }}>
          {filters.search !== undefined && (
            <Field label={tr("common_search")}>
              <SearchBox value={filters.search} onChange={filters.onSearchChange}
                placeholder={filters.searchPlaceholder || (lang === "pt" ? "Marca, modelo, placa…" : "Brand, model, plate…")} />
            </Field>
          )}
          {filters.status !== undefined && filters.statusOptions && (
            <Field label={tr("common_status")}>
              <Select value={filters.status} onChange={filters.onStatusChange} options={filters.statusOptions} />
            </Field>
          )}
          {filters.brand !== undefined && filters.brandOptions && (
            <Field label={tr("common_brand")}>
              <Select value={filters.brand} onChange={filters.onBrandChange} options={filters.brandOptions} />
            </Field>
          )}
          {filters.extra}
        </div>
      )}
      {countLabel && <div className="text-faint fs-12 mb-8">{countLabel}</div>}
      {vehicles.length === 0 ? (empty || <Empty icon="inbox" title={lang === "pt" ? "Nenhum veículo" : "No vehicles"} />) : (
        <div style={{ overflowX: "auto" }}>
          <table className="tbl">
            <thead><tr>
              {cols.map((c) => <th key={c.key}>{c.label}</th>)}
              {onRowClick && <th></th>}
            </tr></thead>
            <tbody>
              {vehicles.map((v) => (
                <tr key={v.id} className={(selectedId === v.id ? "sel " : "") + (onRowClick ? "tbl-clickable" : "")}
                  onClick={onRowClick ? () => onRowClick(v) : undefined}
                  onKeyDown={onRowClick ? clickKey(() => onRowClick(v)) : undefined}
                  tabIndex={onRowClick ? 0 : undefined}
                  role={onRowClick ? "button" : undefined}>
                  {cols.map((c) => (
                    <td key={c.key}>{c.render ? c.render(v, lang, tr) : v[c.key]}</td>
                  ))}
                  {onRowClick && (
                    <td><Button kind="ghost" size="sm" icon="external-link" onClick={(e) => { e.stopPropagation(); onRowClick(v); }}>{tr("common_open")}</Button></td>
                  )}
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </div>
  );
}

function vehicleTableColumnsOpportunities(t, lang) {
  return [
    { key: "plate", label: t("common_plate"), render: (v) => <span className="mono">{v.plate}</span> },
    { key: "vehicle", label: t("common_brand") + " / " + t("common_model"), render: (v) => (
      <div><div style={{ fontWeight: 500 }}>{v.brand}</div><div className="text-faint fs-11">{v.model}</div></div>
    )},
    { key: "year", label: t("common_year"), render: (v) => <span className="mono">{v.year}</span> },
    { key: "bank", label: t("common_bank"), render: (v) => v.bank },
    { key: "settlement", label: lang === "pt" ? "Quitação" : "Settlement", render: (v, l) => <Money value={v.purchasePrice} lang={l} className="mono" /> },
    { key: "client", label: lang === "pt" ? "Cliente" : "Client", render: (v, l) => <Money value={v.clientValue} lang={l} className="mono" /> },
    { key: "profit", label: lang === "pt" ? "Lucro est." : "Est. profit", render: (v, l) => {
      const profit = Math.max(0, (v.fipeMax || 0) * 0.5 - v.purchasePrice - v.clientValue);
      return <Money value={profit} lang={l} className="mono text-success" />;
    }},
    { key: "status", label: t("common_status"), render: (v, l) => <StatusTag status={v.status} lang={l} /> },
  ];
}

function vehicleTableColumnsSettlement(t, lang) {
  return [
    { key: "plate", label: t("common_plate"), render: (v) => <span className="mono">{v.plate}</span> },
    { key: "vehicle", label: lang === "pt" ? "Veículo" : "Vehicle", render: (v) => `${v.brand} ${v.model.slice(0, 30)}` },
    { key: "status", label: t("common_status"), render: (v, l) => <StatusTag status={v.status} lang={l} /> },
    { key: "parcels", label: lang === "pt" ? "Parcelas" : "Installments", render: (v) => (
      <span className="mono">{v.parcels.paid}/{v.parcels.total}{v.parcels.overdue > 0 ? <span className="text-error"> + {v.parcels.overdue}</span> : null}</span>
    )},
    { key: "next", label: lang === "pt" ? "Próx. parcela" : "Next due", render: (v) => (
      <span className="mono fs-12">{v.status === "overdue" ? "—" : "26/04/2026"}</span>
    )},
  ];
}

// Sparkline
function Sparkline({ data, color = "var(--color-primary)", height = 28 }) {
  if (!data || !data.length) return null;
  const max = Math.max(...data), min = Math.min(...data);
  const range = max - min || 1;
  const W = 100, H = height;
  const pts = data.map((v, i) => {
    const x = (i / (data.length - 1 || 1)) * W;
    const y = H - ((v - min) / range) * H * 0.9 - 1;
    return [x, y];
  });
  const path = pts.map(([x, y], i) => (i ? "L" : "M") + x + " " + y).join(" ");
  return (
    <svg width="100%" height={H} viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="none">
      <path d={path} stroke={color} strokeWidth="1.2" fill="none" />
    </svg>
  );
}

// ============================================================
// EXPORT
// ============================================================
Object.assign(window.NA, {
  Icon, Money, Tag, StatusTag,
  Card, CardHead, CardBody,
  PageHead, Stat, Button,
  SearchBox, Field, Input, Select, Textarea,
  Tabs, Segmented, Progress, Switch, Avatar,
  VehicleThumb, Empty, BarChart, LineChart, Sparkline,
  Modal, VehicleDrawer, VehicleTable,
  vehicleTableColumnsOpportunities, vehicleTableColumnsSettlement,
});
