/* ============================================================
   INside One — Tablero Logístico
   Trazabilidad completa: cotización → RFQ proveedor → entrega.
   SLA de 3 días desde la cotización. Sin entrada manual innecesaria.
   ============================================================ */

const LOG_SLA_DAYS = 3;

// ── Constantes ────────────────────────────────────────────────
const LOG_STATUSES = [
  { key: "sin_gestionar",     label: "Sin gestionar",     color: "#6b7280" },
  { key: "rfq_enviado",       label: "RFQ enviado",       color: "#a78bfa" },
  { key: "respuesta_recibida",label: "Respuesta recibida",color: "#0ea5e9" },
  { key: "estimado",          label: "Estimado ⚠️",       color: "#f59e0b" },
  { key: "listo",             label: "Listo para despacho",color:"#22c55e" },
  { key: "en_transito",       label: "En tránsito",       color: "#3b82f6" },
  { key: "entregado",         label: "Entregado ✓",       color: "#16a34a" },
  { key: "cancelado",         label: "Cancelado",         color: "#ef4444" },
];
const LOG_STATUS_MAP = Object.fromEntries(LOG_STATUSES.map(s => [s.key, s]));
const logSt = (k) => LOG_STATUS_MAP[k] || LOG_STATUSES[0];

// ── Helpers ────────────────────────────────────────────────────
function fmtD(iso) {
  if (!iso) return "—";
  try { return new Date(iso).toLocaleDateString("es-PA",{day:"2-digit",month:"short",year:"numeric"}); }
  catch { return iso; }
}

function slaInfo(quoteDateIso, status) {
  if (!quoteDateIso) return null;
  if (["entregado","cancelado"].includes(status)) return { done: true };
  const created = new Date(quoteDateIso);
  const deadline = new Date(created);
  deadline.setDate(deadline.getDate() + LOG_SLA_DAYS);
  const now = new Date();
  const diffMs = deadline - now;
  const diffH = Math.round(diffMs / 3600000);
  const diffD = Math.ceil(diffMs / 86400000);
  const overdue = diffMs < 0;
  const color = overdue ? "#ef4444" : diffH <= 24 ? "#f59e0b" : "#22c55e";
  const label = overdue
    ? `Venció hace ${Math.abs(diffD)} día${Math.abs(diffD)!==1?"s":""}`
    : diffH < 24 ? `${diffH}h restantes` : `${diffD} día${diffD!==1?"s":""} restantes`;
  return { overdue, color, label, deadline };
}

// ── Badge SLA ──────────────────────────────────────────────────
function SlaBadge({ quoteDate, status }) {
  const info = slaInfo(quoteDate, status);
  if (!info) return null;
  if (info.done) return (
    <span style={{ fontSize:10, color:"var(--muted)", fontWeight:600 }}>Cerrado</span>
  );
  return (
    <span style={{ fontSize:10, fontWeight:700, color:info.color,
      background:info.color+"1a", border:"1px solid "+info.color+"44",
      borderRadius:99, padding:"2px 8px", whiteSpace:"nowrap" }}>
      {info.label}
    </span>
  );
}

// ── StatusBadge ───────────────────────────────────────────────
function StatusBadge({ status }) {
  const s = logSt(status);
  return (
    <span style={{ display:"inline-flex", alignItems:"center", gap:4, fontSize:11,
      fontWeight:600, padding:"3px 9px", borderRadius:99,
      color:s.color, background:s.color+"1a", border:"1px solid "+s.color+"44" }}>
      {s.label}
    </span>
  );
}

// ── Modal de detalle ──────────────────────────────────────────
function LogModal({ ticket, quotes, clients, factories, onSave, onClose }) {
  const quote    = quotes.find(q => q.id === ticket.quoteId) || {};
  const [data, setData] = React.useState({
    status:          ticket.status          || "sin_gestionar",
    supplierId:      ticket.supplierId      || "",
    rfqSentAt:       ticket.rfqSentAt       || "",
    rfqRespondedAt:  ticket.rfqRespondedAt  || "",
    leadTimeDays:    ticket.leadTimeDays    || "",
    isEstimated:     ticket.isEstimated     || false,
    carrier:         ticket.carrier         || "",
    eta:             ticket.eta             || "",
    logisticsNotes:  ticket.logisticsNotes  || "",
    internalNotes:   ticket.internalNotes   || "",
  });
  const set = (k,v) => setData(p=>({...p,[k]:v}));

  const supplier = factories.find(f=>f.id===data.supplierId);
  const items    = quote.items || [];

  const handleSave = () => {
    onSave({ ...ticket, ...data, _ts: Date.now() });
    onClose();
  };

  const Row = ({label, children}) => (
    <div style={{display:"grid",gridTemplateColumns:"140px 1fr",gap:12,alignItems:"start",
      padding:"10px 0",borderBottom:"1px solid var(--border)"}}>
      <div style={{fontSize:11,fontWeight:700,color:"var(--muted)",paddingTop:6}}>{label}</div>
      <div>{children}</div>
    </div>
  );

  return (
    <div style={{position:"fixed",inset:0,background:"rgba(0,0,0,.5)",zIndex:200,
      display:"flex",alignItems:"center",justifyContent:"center",padding:20}}>
      <div style={{background:"var(--surface)",borderRadius:16,width:"100%",maxWidth:680,
        maxHeight:"90vh",overflow:"auto",boxShadow:"0 24px 48px rgba(0,0,0,.3)"}}>
        {/* Header */}
        <div style={{padding:"20px 24px 16px",borderBottom:"1px solid var(--border)",
          display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:12}}>
          <div>
            <div style={{display:"flex",alignItems:"center",gap:10,flexWrap:"wrap"}}>
              <span style={{fontWeight:800,fontSize:16}}>{quote.num || ticket.quoteId}</span>
              <StatusBadge status={data.status}/>
              <SlaBadge quoteDate={quote.date||ticket.createdAt} status={data.status}/>
              {data.isEstimated && (
                <span style={{fontSize:10,fontWeight:700,color:"#f59e0b",
                  background:"#f59e0b1a",border:"1px solid #f59e0b44",
                  borderRadius:99,padding:"2px 8px"}}>ESTIMADO</span>
              )}
            </div>
            <div style={{fontSize:12,color:"var(--muted)",marginTop:4}}>
              {ticket.clientName} · {fmtD(quote.date||ticket.createdAt)}
            </div>
          </div>
          <button className="iconbtn" onClick={onClose}><window.Icon name="x" size={16}/></button>
        </div>

        <div style={{padding:"0 24px"}}>
          {/* Items de la cotización */}
          {items.length > 0 && (
            <div style={{margin:"16px 0",padding:14,background:"var(--bg)",borderRadius:10,
              border:"1px solid var(--border)"}}>
              <div style={{fontSize:10,fontWeight:700,color:"var(--muted)",textTransform:"uppercase",
                letterSpacing:".07em",marginBottom:10}}>Ítems de la cotización</div>
              {items.map((it,i)=>(
                <div key={i} style={{display:"flex",justifyContent:"space-between",
                  padding:"5px 0",borderBottom:i<items.length-1?"1px solid var(--border)":""
                }}>
                  <div style={{fontSize:12,flex:1}}>{it.name}</div>
                  <div style={{fontSize:12,color:"var(--muted)",marginLeft:12}}>
                    {it.qty} {it.unit||"un"}
                  </div>
                </div>
              ))}
            </div>
          )}

          <Row label="Estado">
            <select className="inp" value={data.status} onChange={e=>set("status",e.target.value)}>
              {LOG_STATUSES.map(s=><option key={s.key} value={s.key}>{s.label}</option>)}
            </select>
          </Row>

          <Row label="Proveedor / Fábrica">
            <select className="inp" value={data.supplierId}
              onChange={e=>set("supplierId",e.target.value)}>
              <option value="">— Seleccionar proveedor —</option>
              {factories.map(f=>(
                <option key={f.id} value={f.id}>{f.name}{f.country?" · "+f.country:""}</option>
              ))}
            </select>
            {supplier?.contact && (
              <div style={{fontSize:11,color:"var(--muted)",marginTop:4}}>
                Contacto: {supplier.contact}{supplier.email?" · "+supplier.email:""}
              </div>
            )}
          </Row>

          <Row label="RFQ enviado">
            <div style={{display:"flex",alignItems:"center",gap:10}}>
              <input className="inp" type="date" style={{flex:1}}
                value={data.rfqSentAt} onChange={e=>set("rfqSentAt",e.target.value)}/>
              {!data.rfqSentAt && (
                <window.Btn size="sm" variant="outline"
                  onClick={()=>set("rfqSentAt",new Date().toISOString().slice(0,10))}>
                  Hoy
                </window.Btn>
              )}
            </div>
          </Row>

          <Row label="Proveedor respondió">
            <div style={{display:"flex",alignItems:"center",gap:10}}>
              <input className="inp" type="date" style={{flex:1}}
                value={data.rfqRespondedAt} onChange={e=>{
                  set("rfqRespondedAt",e.target.value);
                  if(e.target.value && data.status==="rfq_enviado")
                    set("status","respuesta_recibida");
                }}/>
              {!data.rfqRespondedAt && data.rfqSentAt && (
                <window.Btn size="sm" variant="outline"
                  onClick={()=>{
                    set("rfqRespondedAt",new Date().toISOString().slice(0,10));
                    set("status","respuesta_recibida");
                  }}>
                  Hoy
                </window.Btn>
              )}
            </div>
          </Row>

          <Row label="Tiempo de entrega">
            <div style={{display:"flex",alignItems:"center",gap:10}}>
              <input className="inp" type="number" min="1" style={{width:100}}
                placeholder="Días" value={data.leadTimeDays}
                onChange={e=>set("leadTimeDays",parseInt(e.target.value)||"")}/>
              <label style={{display:"flex",alignItems:"center",gap:6,cursor:"pointer",fontSize:12}}>
                <input type="checkbox" checked={data.isEstimated}
                  onChange={e=>set("isEstimated",e.target.checked)}/>
                <span>Es una estimación</span>
              </label>
            </div>
          </Row>

          <Row label="Transportista / Courier">
            <input className="inp" value={data.carrier}
              onChange={e=>set("carrier",e.target.value)}
              placeholder="DHL, FedEx, courier local..."/>
          </Row>

          <Row label="ETA de llegada">
            <input className="inp" type="date" value={data.eta}
              onChange={e=>set("eta",e.target.value)}/>
          </Row>

          <Row label="Notas para logística">
            <textarea className="inp" rows={3}
              style={{resize:"vertical",fontFamily:"inherit",lineHeight:1.5}}
              value={data.logisticsNotes}
              onChange={e=>set("logisticsNotes",e.target.value)}
              placeholder="Instrucciones de entrega, dirección, contacto en sitio, requisitos especiales..."/>
          </Row>

          <Row label="Notas internas">
            <textarea className="inp" rows={2}
              style={{resize:"vertical",fontFamily:"inherit",lineHeight:1.5}}
              value={data.internalNotes}
              onChange={e=>set("internalNotes",e.target.value)}
              placeholder="Notas privadas del equipo..."/>
          </Row>
        </div>

        <div style={{padding:"16px 24px",borderTop:"1px solid var(--border)",
          display:"flex",justifyContent:"flex-end",gap:10}}>
          <window.Btn variant="ghost" onClick={onClose}>Cancelar</window.Btn>
          <window.Btn onClick={handleSave} icon="check">Guardar</window.Btn>
        </div>
      </div>
    </div>
  );
}

// ── Card de ticket ─────────────────────────────────────────────
function TicketCard({ ticket, quote, onClick }) {
  const sla    = slaInfo(quote?.date || ticket.createdAt, ticket.status);
  const st     = logSt(ticket.status);
  const urgent = sla && !sla.done && sla.overdue;
  const soon   = sla && !sla.done && !sla.overdue && sla.label?.includes("h");

  return (
    <div onClick={onClick}
      style={{ background:"var(--surface)", border:`1px solid ${urgent?"#ef444455":soon?"#f59e0b55":"var(--border)"}`,
        borderRadius:12, padding:"14px 16px", cursor:"pointer",
        transition:"border-color .15s,box-shadow .15s",
        boxShadow: urgent?"0 0 0 2px #ef444422":soon?"0 0 0 2px #f59e0b22":"none" }}
      onMouseEnter={e=>{ if(!urgent&&!soon) e.currentTarget.style.borderColor="var(--accent)"; }}
      onMouseLeave={e=>{ e.currentTarget.style.borderColor=urgent?"#ef444455":soon?"#f59e0b55":"var(--border)"; }}>

      <div style={{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:8,marginBottom:8}}>
        <div>
          <div style={{fontWeight:700,fontSize:14}}>{quote?.num || ticket.quoteId}</div>
          <div style={{fontSize:12,color:"var(--muted)",marginTop:2}}>{ticket.clientName}</div>
        </div>
        <div style={{display:"flex",flexDirection:"column",alignItems:"flex-end",gap:4}}>
          <StatusBadge status={ticket.status}/>
          {ticket.isEstimated && (
            <span style={{fontSize:9,fontWeight:700,color:"#f59e0b",textTransform:"uppercase",
              letterSpacing:".05em"}}>estimado</span>
          )}
        </div>
      </div>

      <div style={{display:"flex",justifyContent:"space-between",alignItems:"center",flexWrap:"wrap",gap:6}}>
        <div style={{fontSize:11,color:"var(--muted)"}}>
          {ticket.supplierName
            ? <span>📦 {ticket.supplierName}</span>
            : <span style={{color:"#ef4444",fontWeight:600}}>⚠ Sin proveedor</span>}
          {ticket.leadTimeDays && (
            <span style={{marginLeft:8}}>· {ticket.leadTimeDays}d entrega{ticket.isEstimated?" (est.)":""}</span>
          )}
        </div>
        <SlaBadge quoteDate={quote?.date||ticket.createdAt} status={ticket.status}/>
      </div>

      {(quote?.items||[]).length > 0 && (
        <div style={{marginTop:8,fontSize:11,color:"var(--muted)",
          display:"-webkit-box",WebkitLineClamp:1,WebkitBoxOrient:"vertical",overflow:"hidden"}}>
          {(quote.items||[]).slice(0,3).map(i=>i.name).join(" · ")}
          {(quote.items||[]).length>3?` +${quote.items.length-3} más`:""}
        </div>
      )}
    </div>
  );
}

// ── LogisticsView ─────────────────────────────────────────────
function LogisticsView() {
  const { quotes, clients, factories, adminMode, auth } = React.useContext(window.AppCtx);

  // Logistics data stored on Firestore per quote
  const [logMap, setLogMap]       = React.useState({});   // quoteId → log doc
  const [loadingLog, setLoadingLog] = React.useState(true);
  const [openTicket, setOpenTicket] = React.useState(null);
  const [filterStatus, setFilterStatus] = React.useState("todos");
  const [search, setSearch]       = React.useState("");
  const [sortBy, setSortBy]       = React.useState("sla"); // sla | date | status

  // Load logistics collection
  React.useEffect(() => {
    if (!window.DB) return;
    const unsub = window.DB.collection("qg_logistics")
      .onSnapshot(snap => {
        const map = {};
        snap.docs.forEach(d => { map[d.id] = d.data(); });
        setLogMap(map);
        setLoadingLog(false);
      }, () => setLoadingLog(false));
    return unsub;
  }, []);

  const saveTicket = (ticket) => {
    const factory = factories.find(f=>f.id===ticket.supplierId);
    window.DB.collection("qg_logistics").doc(ticket.quoteId).set({
      ...ticket,
      supplierName: factory?.name || ticket.supplierName || "",
    }, { merge: true });
  };

  // Build ticket list from quotes (auto-sync: every quote = potential ticket)
  const tickets = React.useMemo(() => {
    return quotes.map(q => {
      const log = logMap[q.id] || {};
      const client = clients.find(c=>c.id===q.clientId);
      return {
        quoteId:      q.id,
        clientName:   q.clientName || client?.name || "—",
        createdAt:    q.date || q._ts,
        status:       log.status       || "sin_gestionar",
        supplierId:   log.supplierId   || "",
        supplierName: log.supplierName || "",
        rfqSentAt:    log.rfqSentAt    || "",
        rfqRespondedAt: log.rfqRespondedAt || "",
        leadTimeDays: log.leadTimeDays || "",
        isEstimated:  log.isEstimated  || false,
        carrier:      log.carrier      || "",
        eta:          log.eta          || "",
        logisticsNotes: log.logisticsNotes || "",
        internalNotes:  log.internalNotes  || "",
        _ts:          log._ts || 0,
      };
    });
  }, [quotes, logMap, clients]);

  // Filter + sort
  const filtered = React.useMemo(() => {
    let list = tickets;
    if (filterStatus !== "todos") list = list.filter(t=>t.status===filterStatus);
    if (search.trim()) {
      const q = search.toLowerCase();
      list = list.filter(t =>
        t.clientName.toLowerCase().includes(q) ||
        (quotes.find(x=>x.id===t.quoteId)?.num||"").toLowerCase().includes(q) ||
        t.supplierName.toLowerCase().includes(q)
      );
    }
    // Sort
    list = [...list].sort((a,b) => {
      if (sortBy === "sla") {
        // urgency: overdue first, then by least time remaining
        const getMs = t => {
          const q = quotes.find(x=>x.id===t.quoteId);
          const si = slaInfo(q?.date||t.createdAt, t.status);
          if (!si || si.done) return Infinity;
          return si.deadline - new Date();
        };
        return getMs(a)-getMs(b);
      }
      if (sortBy === "date") return (b.createdAt||"").localeCompare(a.createdAt||"");
      if (sortBy === "status") return a.status.localeCompare(b.status);
      return 0;
    });
    return list;
  }, [tickets, filterStatus, search, sortBy, quotes]);

  // KPIs
  const kpis = React.useMemo(() => {
    const active = tickets.filter(t=>!["entregado","cancelado"].includes(t.status));
    const overdue = active.filter(t=>{
      const q = quotes.find(x=>x.id===t.quoteId);
      const si = slaInfo(q?.date||t.createdAt, t.status);
      return si && !si.done && si.overdue;
    });
    const sinProveedor = active.filter(t=>!t.supplierId);
    const estimados    = active.filter(t=>t.isEstimated);
    const sinRfq       = active.filter(t=>!t.rfqSentAt && t.status==="sin_gestionar");
    return { total:active.length, overdue:overdue.length, sinProveedor:sinProveedor.length,
      estimados:estimados.length, sinRfq:sinRfq.length };
  }, [tickets, quotes]);

  if (loadingLog) return (
    <div style={{display:"flex",justifyContent:"center",padding:60,color:"var(--muted)"}}>
      Cargando logística...
    </div>
  );

  return (
    <div style={{padding:"24px 28px 80px"}}>
      {/* Header */}
      <div style={{display:"flex",alignItems:"flex-start",justifyContent:"space-between",
        marginBottom:20,gap:16,flexWrap:"wrap"}}>
        <div>
          <h1 style={{margin:0,fontSize:22,fontWeight:800}}>Tablero Logístico</h1>
          <div style={{fontSize:13,color:"var(--muted)",marginTop:4}}>
            Trazabilidad de cotizaciones · SLA {LOG_SLA_DAYS} días
          </div>
        </div>
      </div>

      {/* KPI strip */}
      <div style={{display:"grid",gridTemplateColumns:"repeat(5,1fr)",gap:10,marginBottom:20}}>
        {[
          { label:"Activos",       val:kpis.total,         color:"var(--text)" },
          { label:"Vencidos SLA",  val:kpis.overdue,       color:"#ef4444" },
          { label:"Sin proveedor", val:kpis.sinProveedor,  color:"#f59e0b" },
          { label:"Estimados",     val:kpis.estimados,     color:"#f59e0b" },
          { label:"Sin gestionar", val:kpis.sinRfq,        color:"#a78bfa" },
        ].map(k=>(
          <div key={k.label} style={{background:"var(--surface)",border:"1px solid var(--border)",
            borderRadius:11,padding:"12px 14px",textAlign:"center"}}>
            <div style={{fontSize:24,fontWeight:800,color:k.val>0?k.color:"var(--text)"}}>
              {k.val}
            </div>
            <div style={{fontSize:10,color:"var(--muted)",textTransform:"uppercase",
              letterSpacing:".06em",marginTop:3}}>{k.label}</div>
          </div>
        ))}
      </div>

      {/* Filters bar */}
      <div style={{display:"flex",gap:10,marginBottom:16,flexWrap:"wrap",alignItems:"center"}}>
        <input className="inp" style={{width:220}} placeholder="Buscar cotización, cliente..."
          value={search} onChange={e=>setSearch(e.target.value)}/>
        <select className="inp" style={{width:200}} value={filterStatus}
          onChange={e=>setFilterStatus(e.target.value)}>
          <option value="todos">Todos los estados</option>
          {LOG_STATUSES.map(s=><option key={s.key} value={s.key}>{s.label}</option>)}
        </select>
        <select className="inp" style={{width:160}} value={sortBy}
          onChange={e=>setSortBy(e.target.value)}>
          <option value="sla">Ordenar: urgencia SLA</option>
          <option value="date">Ordenar: más reciente</option>
          <option value="status">Ordenar: estado</option>
        </select>
        <div style={{marginLeft:"auto",fontSize:12,color:"var(--muted)"}}>
          {filtered.length} cotización{filtered.length!==1?"es":""}
        </div>
      </div>

      {/* Ticket grid */}
      {filtered.length === 0 ? (
        <div style={{textAlign:"center",padding:"60px 20px",color:"var(--muted)",fontSize:14}}>
          {tickets.length===0
            ? "No hay cotizaciones aún. Crea una desde el Cotizador."
            : "Ninguna cotización coincide con el filtro."}
        </div>
      ) : (
        <div style={{display:"grid",gridTemplateColumns:"repeat(auto-fill,minmax(320px,1fr))",gap:12}}>
          {filtered.map(t=>(
            <TicketCard
              key={t.quoteId}
              ticket={t}
              quote={quotes.find(q=>q.id===t.quoteId)}
              onClick={()=>setOpenTicket(t)}
            />
          ))}
        </div>
      )}

      {/* Detail modal */}
      {openTicket && (
        <LogModal
          ticket={openTicket}
          quotes={quotes}
          clients={clients}
          factories={factories}
          onSave={saveTicket}
          onClose={()=>setOpenTicket(null)}
        />
      )}
    </div>
  );
}

window.LogisticsView = LogisticsView;
