// Gantt view — timeline with draggable bars
// Rebuilt using the original "Claude Designer" design with months as columns and weekly sub-labels.

const getMondaysForMonth = (year, month) => {
  const mondays = [];
  const d = new Date(year, month, 1);
  // Find first Monday
  while (d.getDay() !== 1) d.setDate(d.getDate() + 1);
  // Add all Mondays of the month
  while (d.getMonth() === month) {
    mondays.push(d.getDate().toString().padStart(2, '0') + '/' + (d.getMonth() + 1).toString().padStart(2, '0'));
    d.setDate(d.getDate() + 7);
  }
  return mondays;
};

const getScaleConfig = (scale) => {
  const start = new Date(2026, 4, 1); // May 1
  let end;
  let months = [];
  
  const monthList = [
    { key: "may", label: "Mayo", m: 4 },
    { key: "jun", label: "Junio", m: 5 },
    { key: "jul", label: "Julio", m: 6 },
    { key: "aug", label: "Agosto", m: 7 },
    { key: "sep", label: "Sept", m: 8 },
    { key: "oct", label: "Octubre", m: 9 },
    { key: "nov", label: "Nov", m: 10 },
    { key: "dic", label: "Dic", m: 11 },
  ];

  if (scale === "quarter") {
    end = new Date(2026, 7, 31); 
    months = monthList.slice(0, 4).map(m => ({ ...m, weeks: getMondaysForMonth(2026, m.m) }));
  } else if (scale === "year") {
    end = new Date(2026, 11, 31);
    months = monthList.map(m => ({ ...m, weeks: getMondaysForMonth(2026, m.m) }));
  } else {
    end = new Date(2026, 5, 30); 
    months = monthList.slice(0, 2).map(m => ({ ...m, weeks: getMondaysForMonth(2026, m.m) }));
  }

  const days = Math.round((end - start) / 86400000) + 1;
  return { start, end, days, months };
};

const dayPct = (iso, config) => {
  if (!iso) return 0;
  const d = new Date(iso + "T00:00:00");
  const days = (d - config.start) / 86400000;
  return Math.max(0, Math.min(100, (days / config.days) * 100));
};

const pctToIso = (pct, config) => {
  const days = Math.round((pct / 100) * config.days);
  const d = new Date(config.start.getTime() + days * 86400000);
  return d.toISOString().slice(0, 10);
};

const GanttBar = ({ item, project, onUpdate, onShowPopover, config, type = "epic" }) => {
  const [drag, setDrag] = React.useState(null);
  const isUS = type === "us";
  
  const start = item.start || (isUS && item.deadline ? pctToIso(dayPct(item.deadline, config) - 3, config) : item.start);
  const end   = item.end || item.deadline || start;

  const startPct = dayPct(start, config);
  const endPct = dayPct(end, config);
  const widthPct = Math.max(isUS ? 1.5 : 2, endPct - startPct);
  const toast = window.useToast();

  const onMouseDown = (mode) => (e) => {
    if (type === "project") return; // Read-only
    e.preventDefault(); e.stopPropagation();
    const rect = e.currentTarget.closest(".gantt-bar-area").getBoundingClientRect();
    const origStart = startPct;
    const origEnd = endPct;
    const startX = e.clientX;
    
    const onMove = (ev) => {
      const dx = ((ev.clientX - startX) / rect.width) * 100;
      let ns = origStart, ne = origEnd;
      if (mode === "move")  { ns = origStart + dx; ne = origEnd + dx; }
      if (mode === "left")  { ns = Math.min(origEnd - 1, origStart + dx); }
      if (mode === "right") { ne = Math.max(origStart + 1, origEnd + dx); }
      ns = Math.max(0, Math.min(100, ns));
      ne = Math.max(0, Math.min(100, ne));
      setDrag({ ns, ne });
    };
    
    const onUp = (upEv) => {
      window.removeEventListener("mousemove", onMove);
      window.removeEventListener("mouseup", onUp);
      
      const moved = Math.abs(upEv.clientX - startX) > 3;

      if (!moved && mode === "move") {
        // It's a click!
        const rect = upEv.currentTarget.getBoundingClientRect();
        onShowPopover({ item, type, project, rect });
      }

      // Calculate final dates outside of state setter to avoid duplicate side-effects
      setDrag((cur) => {
        if (cur && moved) {
          const newStart = pctToIso(cur.ns, config);
          const newEnd = pctToIso(cur.ne, config);
          // Side effects after state is captured
          setTimeout(() => {
            onUpdate(project.id, item.id, { start: newStart, [isUS ? "deadline" : "end"]: newEnd }, type);
            toast.push(`📅 ${item.name}: ${window.fmtShortDate(newStart)} → ${window.fmtShortDate(newEnd)}`, { color: project.color, icon: "calendar" });
          }, 0);
        }
        return null;
      });
    };
    window.addEventListener("mousemove", onMove);
    window.addEventListener("mouseup", onUp);
  };

  const left = drag ? drag.ns : startPct;
  const width = drag ? Math.max(isUS ? 1.5 : 2, drag.ne - drag.ns) : widthPct;

  if (left >= 100 || (left + width) <= 0) return null;

  const isProject = type === "project";
    
  return (
    <div
      className={`gantt-bar ${type} ${item.tbd ? "tbd" : ""} ${drag ? "dragging" : ""}`}
      style={{
        left: left + "%",
        width: width + "%",
        "--proj-color": project.color,
        height: isProject ? "10px" : isUS ? "18px" : "28px",
        top: isProject ? "calc(50% + 2px)" : "50%"
      }}
      onMouseDown={onMouseDown("move")}
    >
      {type !== "project" && <span className="handle l" onMouseDown={onMouseDown("left")} />}
      <span className="bar-label">{item.name}{item.tbd ? " · TBD" : ""}</span>
      {type !== "project" && <span className="handle r" onMouseDown={onMouseDown("right")} />}
    </div>
  );
};

const AREA_COLOR_MAP = {
  "Transversal": "#02396B", "Marketing": "#A82025", "Operaciones": "#FBBF24",
  "Legal": "#A78BFA", "Finanzas": "#60A5FA", "Comercial": "#34D399", "RH": "#F87171",
};

const AreaFilterChips = ({ areas, selected, onToggle, onAll }) => {
  const allSelected = areas.every((a) => selected.has(a));
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 10, padding: "14px 20px", borderBottom: "1px solid var(--border-subtle)" }}>
      <button onClick={onAll} className={`tab ${allSelected ? "active" : ""}`} style={{ height: 28, fontSize: 10 }}>Todas</button>
      {areas.map((area) => {
        const active = selected.has(area);
        const color = AREA_COLOR_MAP[area] || "#94A3B8";
        return (
          <button key={area} onClick={() => onToggle(area)} 
            className={`tab ${active ? "active" : ""}`} 
            style={{ height: 28, fontSize: 10, color: active ? color : undefined, borderColor: active ? color + "55" : undefined }}>
            <span style={{ width: 8, height: 8, borderRadius: "50%", background: color, marginRight: 2 }} />
            {area}
          </button>
        );
      })}
    </div>
  );
};

const GanttView = ({ projects, setProjects }) => {
  const toast = window.useToast();
  const [scale, setScale] = React.useState("quarter");
  const [expanded, setExpanded] = React.useState(new Set(projects.map(p => p.id)));
  const [history, setHistory] = React.useState([]);
  
  const config = React.useMemo(() => getScaleConfig(scale), [scale]);
  const todayPct = dayPct(window.TZ_TODAY_ISO, config);
  const allAreas = React.useMemo(() => [...new Set(projects.map(p => p.area))], [projects]);
  const [selectedAreas, setSelectedAreas] = React.useState(new Set(allAreas));
  const [popover, setPopover] = React.useState(null);

  const toggleExpand = (id) => {
    setExpanded(prev => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id); else next.add(id);
      return next;
    });
  };

  const onUpdateItem = (pid, itemId, patch, type) => {
    const { projects: next, error } = window.updateHierarchyDates(projects, type, itemId, patch, toast);
    
    if (error) {
      toast.push(`⚠️ Error: ${error}`, { color: "#B3393E", icon: "error" });
      return;
    }

    setHistory(prev => [JSON.stringify(projects), ...prev].slice(0, 20));
    setProjects(next);
  };

  const handleUndo = () => {
    if (history.length === 0) return;
    const [prev, ...rest] = history;
    setProjects(JSON.parse(prev));
    setHistory(rest);
  };

  return (
    <>
      <div className="view-header">
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-end", width: "100%" }}>
          <div>
            <div className="view-title">Gantt · Roadmap Termiz</div>
            <div className="view-sub">Meses con detalle semanal (Mondays)</div>
          </div>
          <div style={{ display: "flex", gap: 10, alignItems: "center" }}>
            {history.length > 0 && <button className="btn-secondary" onClick={handleUndo} style={{ padding: "4px 12px", fontSize: 11, height: 32 }}>↩ Deshacer</button>}
            <div className="tabs" style={{ padding: 0, height: "auto", position: "static", backdropFilter: "none", background: "none" }}>
              {["month", "quarter", "year"].map(s => (
                <button key={s} onClick={() => setScale(s)} className={`tab ${scale === s ? "active" : ""}`} style={{ height: 32 }}>
                  {s === "month" ? "Mes" : s === "quarter" ? "Trimestre" : "Año"}
                </button>
              ))}
            </div>
          </div>
        </div>
      </div>

      <div className="gantt-wrap">
        <div className="gantt-toolbar">
          <div className="gantt-legend">
            <span className="lk"><span className="swatch" style={{ background: "var(--azul-info)" }} /> En Progreso</span>
            <span className="lk"><span className="swatch" style={{ background: "var(--purpura)" }} /> Planeado</span>
            <span className="lk"><span className="swatch" style={{ background: "transparent", border: "1px dashed var(--text-2)" }} /> TBD</span>
          </div>
          <div className="gantt-legend">
            <span className="lk">
              <span style={{ width: 12, height: 12, borderRadius: 2, background: "var(--ambar)", display: "inline-block" }} />
              Línea HOY · {window.fmtShortDate(window.TZ_TODAY_ISO)} {window.TZ_TODAY.getFullYear()}
            </span>
          </div>
        </div>

        <AreaFilterChips areas={allAreas} selected={selectedAreas} onToggle={(a) => {
          setSelectedAreas(prev => {
            const next = new Set(prev);
            if (next.has(a)) next.delete(a); else next.add(a);
            return next;
          });
        }} onAll={() => setSelectedAreas(new Set(allAreas))} />

        <div className="gantt-scroll">
          <div className="gantt-table" style={{ "--cols": config.months.length }}>
            <div className="gantt-head">
              <div className="corner">PROYECTO / EPIC</div>
              <div className="gantt-months">
                {config.months.map((m) => (
                  <div className="month" key={m.key} style={{ display: "flex", flexDirection: "column", padding: 0 }}>
                    <div style={{ padding: "8px 0", borderBottom: "1px solid var(--border-subtle)", width: "100%", textAlign: "center" }}>
                      {m.label}
                    </div>
                    <div style={{ display: "flex", flex: 1, background: "rgba(0,0,0,0.01)" }}>
                      {m.weeks.map(w => (
                        <div key={w} style={{ flex: 1, fontSize: 9, textAlign: "center", color: "var(--text-3)", padding: "4px 0", borderRight: "1px solid rgba(0,0,0,0.05)" }}>
                          {w}
                        </div>
                      ))}
                    </div>
                  </div>
                ))}
              </div>
            </div>

            {projects.filter(p => selectedAreas.has(p.area)).map(p => (
              <React.Fragment key={p.id}>
                {/* Project Row */}
                <div className="gantt-group-head" style={{ "--proj-color": p.color, cursor: "pointer" }} onClick={() => toggleExpand(p.id)}>
                  <div className="label">
                    <span className="csq" />
                    <div style={{ display: "flex", flexDirection: "column" }}>
                      <span style={{ fontSize: 13, fontWeight: 800 }}>{p.name}</span>
                      <span style={{ fontSize: 9, color: "var(--text-2)", fontWeight: 700 }}>
                        {p.start ? window.fmtShortDate(p.start) : "?"} → {p.end ? window.fmtShortDate(p.end) : "?"} · {p.area}
                      </span>
                    </div>
                  </div>
                  <div className="gantt-bar-area">
                    <div className="gridlines">
                      {config.months.map(m => <div className="gl" key={m.key} />)}
                    </div>
                    {p.start && p.end && (
                      <GanttBar item={p} project={p} config={config} type="project" onUpdate={()=>{}} />
                    )}
                  </div>
                </div>

                {expanded.has(p.id) && (p.epics || []).map(epic => (
                  <React.Fragment key={epic.id}>
                    {/* Epic Row */}
                    <div className="gantt-row" style={{ "--proj-color": p.color }}>
                      <div className="epic-label" style={{ cursor: "pointer" }} onClick={() => toggleExpand(epic.id)}>
                        <span style={{ flex: 1, overflow: "hidden", textOverflow: "ellipsis" }}>{epic.name}</span>
                        <span className="sub" style={{ marginLeft: "auto" }}>
                          {window.fmtShortDate(epic.start)} → {window.fmtShortDate(epic.end)}
                        </span>
                      </div>
                      <div className="gantt-bar-area">
                        <div className="gridlines">
                          {config.months.map(m => <div className="gl" key={m.key} />)}
                        </div>
                        <GanttBar item={epic} project={p} onUpdate={onUpdateItem} onShowPopover={setPopover} config={config} type="epic" />
                      </div>
                    </div>

                    {/* US Rows */}
                    {expanded.has(epic.id) && (epic.userStories || []).map(us => (
                      <div className="gantt-row" key={us.id} style={{ "--proj-color": p.color, minHeight: 32 }}>
                        <div className="epic-label" style={{ paddingLeft: 48, opacity: 0.8 }}>
                          <span style={{ fontSize: 11, flex: 1, overflow: "hidden", textOverflow: "ellipsis" }}>• {us.name}</span>
                          <span className="sub" style={{ marginLeft: "auto" }}>
                            {window.fmtShortDate(us.start)} → {window.fmtShortDate(us.end || us.deadline)}
                          </span>
                        </div>
                        <div className="gantt-bar-area">
                          <div className="gridlines">
                            {config.months.map(m => <div className="gl" key={m.key} />)}
                          </div>
                          <GanttBar item={us} project={p} onUpdate={onUpdateItem} onShowPopover={setPopover} config={config} type="us" />
                        </div>
                      </div>
                    ))}
                  </React.Fragment>
                ))}
              </React.Fragment>
            ))}

            <div className="today-line" style={{ left: `calc(240px + (100% - 240px) * ${todayPct} / 100)` }} />
          </div>
        </div>
      </div>
      
      {popover && (
        <GanttPopover 
          {...popover} 
          onUpdate={onUpdateItem} 
          onClose={() => setPopover(null)} 
        />
      )}
    </>
  );
};

const GanttPopover = ({ item, type, project, onUpdate, onClose, rect }) => {
  const [d, setD] = React.useState({ start: item.start || "", end: item.end || item.deadline || "" });
  
  const handleSave = () => {
    onUpdate(project.id, item.id, { start: d.start, [type === "us" ? "deadline" : "end"]: d.end }, type);
    onClose();
  };

  return (
    <div className="gantt-popover" style={{ 
      top: rect.top - 10, 
      left: rect.left + rect.width / 2 
    }} onClick={e => e.stopPropagation()}>
      <div className="gp-head">
        <div className="gp-title">{item.name}</div>
        <button className="gp-close" onClick={onClose}><Icon name="close" size={10} /></button>
      </div>
      <div className="gp-body">
        <div className="gp-row">
          <div className="gp-field">
            <label>Inicio</label>
            <input type="date" value={d.start} onChange={e => setD({...d, start: e.target.value})} />
          </div>
          <div className="gp-field">
            <label>Fin / Deadline</label>
            <input type="date" value={d.end} onChange={e => setD({...d, end: e.target.value})} />
          </div>
        </div>
      </div>
      <div className="gp-foot">
        <button className="gp-btn-save" onClick={handleSave}>Actualizar</button>
      </div>
      <div className="gp-arrow" />
    </div>
  );
};

Object.assign(window, { GanttView });
