/* ===== Root App: state, nav, persistence (Supabase) ===== */
const { useState, useEffect } = React;

/* ---- DB field mapping helpers ---- */
function taskFromDB(r) {
  return { id: r.id, title: r.title, desc: r.description, assignee: r.assignee,
    status: r.status, priority: r.priority, start: r.start_date, deadline: r.due_date };
}
function taskToDB(t) {
  return { id: t.id, title: t.title, description: t.desc || "", assignee: t.assignee,
    status: t.status, priority: t.priority, start_date: t.start || "", due_date: t.deadline || "" };
}
function schedFromDB(r) {
  return { id: r.id, owner: r.owner, name: r.name, cadence: r.cadence,
    dueHour: r.due_hour, dueDow: r.due_dow, dueDom: r.due_dom,
    startDate: r.start_date || null };
}
function schedToDB(s) {
  return { id: s.id, owner: s.owner, name: s.name, cadence: s.cadence,
    due_hour: s.dueHour ?? 18, due_dow: s.dueDow ?? null, due_dom: s.dueDom ?? null,
    start_date: s.startDate || null };
}
function trashItemFromDB(r) { return { ...r.task_data, deletedAt: r.deleted_at }; }

const TRASH_DAYS_MS = 30 * 24 * 60 * 60 * 1000;

const trashBadgeStyle = {
  position: "absolute", top: -6, right: -6,
  background: "var(--high)", color: "#fff",
  fontFamily: "var(--font-num)", fontSize: 11, fontWeight: 700,
  minWidth: 18, height: 18, padding: "0 6px", borderRadius: 20,
  display: "grid", placeItems: "center",
  boxShadow: "0 0 0 2px var(--bg)",
};

/* ---- "กรอก Supabase credentials ก่อน" screen ---- */
function SetupScreen() {
  return (
    <div style={{ display:"flex", alignItems:"center", justifyContent:"center", minHeight:"100vh", padding:24 }}>
      <div style={{ maxWidth:480, textAlign:"center" }}>
        <div className="brand-mark" style={{ width:56, height:56, borderRadius:18, margin:"0 auto 20px" }}>
          <svg width="28" height="28" viewBox="0 0 24 24" fill="none">
            <path d="M5 13l4 4 10-11" stroke="#fff" strokeWidth="2.6" strokeLinecap="round" strokeLinejoin="round"/>
          </svg>
        </div>
        <h2 style={{ fontSize:22, fontWeight:700, marginBottom:8 }}>ตั้งค่า Supabase ก่อนใช้งาน</h2>
        <p style={{ color:"var(--ink-2)", lineHeight:1.7, marginBottom:24 }}>
          แก้ไขไฟล์ <code style={{ background:"var(--surface)", padding:"2px 6px", borderRadius:6 }}>src/supabase-client.jsx</code><br/>
          แล้วใส่ <strong>SUPABASE_URL</strong> และ <strong>SUPABASE_ANON_KEY</strong><br/>
          จาก Supabase Dashboard → Project Settings → API
        </p>
        <div style={{ background:"var(--surface)", borderRadius:12, padding:"16px 20px", textAlign:"left", fontSize:13, fontFamily:"monospace", lineHeight:2 }}>
          <div style={{ color:"var(--ink-3)" }}>// src/supabase-client.jsx</div>
          <div>const SUPABASE_URL = <span style={{ color:"#18b58a" }}>"https://xxxx.supabase.co"</span>;</div>
          <div>const SUPABASE_ANON_KEY = <span style={{ color:"#18b58a" }}>"eyJ..."</span>;</div>
        </div>
        <p style={{ color:"var(--ink-3)", marginTop:16, fontSize:13 }}>
          ดูขั้นตอนเต็มใน <strong>DEPLOY.md</strong>
        </p>
      </div>
    </div>
  );
}

/* ---- Loading screen ---- */
function LoadingScreen() {
  return (
    <div style={{ display:"flex", alignItems:"center", justifyContent:"center", minHeight:"100vh", flexDirection:"column", gap:16 }}>
      <div className="brand-mark" style={{ width:52, height:52, borderRadius:18 }}>
        <svg width="26" height="26" viewBox="0 0 24 24" fill="none">
          <path d="M5 13l4 4 10-11" stroke="#fff" strokeWidth="2.6" strokeLinecap="round" strokeLinejoin="round"/>
        </svg>
      </div>
      <div style={{ color:"var(--ink-2)", fontSize:15 }}>กำลังโหลดข้อมูล...</div>
    </div>
  );
}

function App() {
  /* guard: Supabase not configured yet */
  if (!window.__SB_READY) return <SetupScreen />;

  const SB = window.SB;

  const [loading, setLoading]         = useState(true);
  const [view, setView]               = useState("manager");
  const [currentUser, setCurrentUser] = useState(null);
  const [tasks, setTasks]             = useState([]);
  const [subs, setSubs]               = useState({});
  const [schedules, setSchedules]     = useState([]);
  const [members, setMembers]         = useState([]);
  const [trash, setTrash]             = useState([]);
  const [pinHash, setPinHashState]    = useState(null);
  const [modal, setModal]             = useState(null);
  const [schedModal, setSchedModal]   = useState(null);
  const [membersModal, setMembersModal] = useState(null);
  const [trashOpen, setTrashOpen]     = useState(false);

  /* keep window maps in sync so components that use MEMBER_MAP directly stay correct */
  window.MEMBERS    = members;
  window.MEMBER_MAP = Object.fromEntries(members.map(m => [m.id, m]));

  /* ---- load all data from Supabase on mount ---- */
  useEffect(() => {
    async function load() {
      const [
        { data: mData },
        { data: tData },
        { data: sData },
        { data: subData },
        { data: trData },
        { data: setData },
      ] = await Promise.all([
        SB.from("members").select("*").order("sort_order"),
        SB.from("tasks").select("*"),
        SB.from("schedules").select("*"),
        SB.from("submissions").select("*"),
        SB.from("trash").select("*"),
        SB.from("app_settings").select("*"),
      ]);

      const loadedMembers = mData || [];
      setMembers(loadedMembers);
      setTasks((tData || []).map(taskFromDB));
      setSchedules((sData || []).map(schedFromDB));

      const subsObj = {};
      (subData || []).forEach(r => { subsObj[r.sub_key] = { at: r.at, remark: r.remark || "" }; });
      setSubs(subsObj);

      /* auto-purge expired trash items */
      const cutoff = Date.now() - TRASH_DAYS_MS;
      const expiredIds = (trData || []).filter(r => r.deleted_at <= cutoff).map(r => r.id);
      if (expiredIds.length) await SB.from("trash").delete().in("id", expiredIds);
      setTrash((trData || []).filter(r => r.deleted_at > cutoff).map(trashItemFromDB));

      const pinRow = (setData || []).find(r => r.key === "pin_hash");
      if (pinRow) setPinHashState(pinRow.value);

      if (loadedMembers.length) setCurrentUser(loadedMembers[0].id);
      setLoading(false);
    }
    load();
  }, []);

  if (loading) return <LoadingScreen />;

  /* ---- task ops ---- */
  const moveTask = async (id, status) => {
    setTasks(ts => ts.map(t => t.id === id ? { ...t, status } : t));
    await SB.from("tasks").update({ status }).eq("id", id);
  };

  const saveTask = async (task) => {
    const isNew = !tasks.some(t => t.id === task.id);
    const saved = isNew ? { ...task, id: "t" + Date.now() } : task;
    setTasks(ts => isNew ? [...ts, saved] : ts.map(t => t.id === saved.id ? saved : t));
    await SB.from("tasks").upsert(taskToDB(saved));
    setModal(null);
  };

  const deleteTask = async (id) => {
    const t = tasks.find(x => x.id === id);
    if (t) {
      const deletedAt = Date.now();
      setTrash(tr => [{ ...t, deletedAt }, ...tr]);
      setTasks(ts => ts.filter(x => x.id !== id));
      await SB.from("tasks").delete().eq("id", id);
      await SB.from("trash").upsert({ id: t.id, task_data: t, deleted_at: deletedAt });
    }
    setModal(null);
  };

  const openNew   = (assignee, status = "todo") =>
    setModal({ task: { assignee: assignee || currentUser, status }, lockAssignee: false });
  const openEdit  = (task) => setModal({ task, lockAssignee: false });
  const gotoBoard = (userId) => { setCurrentUser(userId); setView("board"); };

  /* ---- report ops ---- */
  const submitReport = async (scheduleId, periodKey, remark, atMs) => {
    const key = subKey(scheduleId, periodKey);
    // remark == null && atMs == null => ลบ submission (ยกเลิกการส่ง)
    if (remark === null && atMs === null) {
      setSubs(s => { const n = { ...s }; delete n[key]; return n; });
      await SB.from("submissions").delete().eq("sub_key", key);
      return;
    }
    const at = atMs ?? Date.now();
    setSubs(s => ({ ...s, [key]: { at, remark: remark || "" } }));
    await SB.from("submissions").upsert({ sub_key: key, at, remark: remark || "" });
  };

  const openNewSchedule  = (owner) => setSchedModal({ schedule: owner ? { owner } : {} });
  const openEditSchedule = (schedule) => setSchedModal({ schedule });

  const saveSchedule = async (sch) => {
    const isNew = !schedules.some(x => x.id === sch.id);
    const saved = isNew ? { ...sch, id: "r" + Date.now() } : sch;
    setSchedules(list => isNew ? [...list, saved] : list.map(x => x.id === saved.id ? saved : x));
    await SB.from("schedules").upsert(schedToDB(saved));
    setSchedModal(null);
  };

  const deleteSchedule = async (id) => {
    setSchedules(list => list.filter(x => x.id !== id));
    await SB.from("schedules").delete().eq("id", id);
    setSchedModal(null);
  };

  /* ---- trash ops ---- */
  const restoreTask = async (id) => {
    const item = trash.find(x => x.id === id);
    if (!item) return;
    const exists = members.some(m => m.id === item.assignee);
    const { deletedAt, ...restored } = item;
    if (!exists && members.length) restored.assignee = members[0].id;
    setTasks(ts => [...ts, restored]);
    setTrash(tr => tr.filter(x => x.id !== id));
    await SB.from("tasks").upsert(taskToDB(restored));
    await SB.from("trash").delete().eq("id", id);
  };

  const permDeleteTask = async (id) => {
    setTrash(tr => tr.filter(x => x.id !== id));
    await SB.from("trash").delete().eq("id", id);
  };

  const emptyTrash = async () => {
    setTrash([]);
    await SB.from("trash").delete().neq("id", "");
  };

  /* ---- member ops ---- */
  const openMembers = (prefill = "") => setMembersModal({ prefill });

  const saveMember = async (m) => {
    const isNew = !members.some(x => x.id === m.id);
    const saved = isNew ? { ...m, sort_order: members.length } : m;
    setMembers(list => isNew ? [...list, saved] : list.map(x => x.id === saved.id ? saved : x));
    await SB.from("members").upsert(saved);
  };

  const deleteMember = async (id) => {
    const remaining = members.filter(x => x.id !== id);
    if (!remaining.length) return;
    const fallback = remaining[0].id;
    setMembers(remaining);
    setTasks(ts => ts.map(t => t.assignee === id ? { ...t, assignee: fallback } : t));
    setSchedules(ss => ss.map(s => s.owner === id ? { ...s, owner: fallback } : s));
    if (currentUser === id) setCurrentUser(fallback);
    await SB.from("tasks").update({ assignee: fallback }).eq("assignee", id);
    await SB.from("schedules").update({ owner: fallback }).eq("owner", id);
    await SB.from("members").delete().eq("id", id);
  };

  /* ---- PIN ---- */
  const setPinHash = async (hash) => {
    setPinHashState(hash);
    if (hash) await SB.from("app_settings").upsert({ key: "pin_hash", value: hash });
    else       await SB.from("app_settings").delete().eq("key", "pin_hash");
  };

  /* ---- render ---- */
  return (
    <>
      <div className="topbar">
        <div className="topbar-in">
          <div className="brand">
            <div className="brand-mark">
              <svg width="22" height="22" viewBox="0 0 24 24" fill="none">
                <path d="M5 13l4 4 10-11" stroke="#fff" strokeWidth="2.6" strokeLinecap="round" strokeLinejoin="round"/>
              </svg>
            </div>
            <div>
              <div className="brand-name">TeamFlow</div>
              <div className="brand-sub">งานทีม · เห็นทุกความคืบหน้า</div>
            </div>
          </div>

          <div className="viewtabs">
            <button className={"viewtab" + (view === "manager" ? " active" : "")} onClick={() => setView("manager")}>
              <GridIcon /> ภาพรวมทีม
            </button>
            <button className={"viewtab" + (view === "board" ? " active" : "")} onClick={() => setView("board")}>
              <BoardIcon /> บอร์ดงาน
            </button>
            <button className={"viewtab" + (view === "reports" ? " active" : "")} onClick={() => setView("reports")}>
              <ReportIcon /> รายงาน
            </button>
          </div>

          <div className="spacer"></div>

          {view === "board" && (
            <div className="who">
              <span className="who-label">กำลังดูในชื่อ</span>
              <select className="who-select" value={currentUser || ""}
                onChange={(e) => setCurrentUser(e.target.value)}>
                {members.map(m => <option key={m.id} value={m.id}>{m.nick} — {m.role}</option>)}
              </select>
            </div>
          )}
          <button className="btn btn-ghost" onClick={() => openMembers()} title="จัดการรายชื่อทีม">
            <UsersIcon /> <span className="btn-label">สมาชิก</span>
          </button>
          <button className="btn btn-ghost" onClick={() => setTrashOpen(true)}
            title={`ถังขยะ (${trash.length})`} style={{ position: "relative" }}>
            <TrashIcon /> <span className="btn-label">ถังขยะ</span>
            {trash.length > 0 && <span style={trashBadgeStyle}>{trash.length}</span>}
          </button>
        </div>
      </div>

      <div className="shell">
        {view === "manager" &&
          <ManagerDashboard tasks={tasks} members={members}
            onAddTask={openNew} onOpenTask={openEdit} onGotoBoard={gotoBoard} />}
        {view === "board" && currentUser &&
          <KanbanBoard tasks={tasks} currentUser={currentUser} members={members}
            onMove={moveTask} onOpenTask={openEdit} onAddTask={openNew}
            schedules={schedules} submissions={subs} onSubmitReport={submitReport}
            onAddSchedule={openNewSchedule} onEditSchedule={openEditSchedule} />}
        {view === "reports" &&
          <ReportsView schedules={schedules} submissions={subs} members={members}
            onGotoBoard={gotoBoard} onSubmitReport={submitReport}
            onAddSchedule={openNewSchedule} onEditSchedule={openEditSchedule} />}
      </div>

      {modal && (
        <TaskModal task={modal.task} lockAssignee={modal.lockAssignee} members={members}
          onClose={() => setModal(null)} onSave={saveTask} onDelete={deleteTask}
          onManageMembers={openMembers} />
      )}
      {schedModal && (
        <ScheduleModal schedule={schedModal.schedule} members={members}
          onClose={() => setSchedModal(null)} onSave={saveSchedule} onDelete={deleteSchedule}
          onManageMembers={openMembers} />
      )}
      {membersModal && (
        <MembersModal members={members} tasks={tasks} schedules={schedules}
          prefillName={membersModal.prefill}
          onClose={() => setMembersModal(null)} onSave={saveMember} onDelete={deleteMember} />
      )}
      {trashOpen && (
        <TrashModal trash={trash} members={members} pinHash={pinHash}
          onClose={() => setTrashOpen(false)}
          onRestore={restoreTask} onPermDelete={permDeleteTask} onEmpty={emptyTrash}
          onSetPin={setPinHash} />
      )}
    </>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
