/* rfi-data.jsx — plain JS, browser global */
(function () {
  "use strict";

  const sb = window.sb; // supabase client, may be null
  const cdeData = window.cdeData; // { projectId(), nextCode(table,prefix), logAudit(ev) }

  /* ---------- helpers ---------- */
  function safeDate(iso) {
    if (!iso) return "";
    try {
      return new Date(iso).toLocaleDateString("vi-VN");
    } catch (_) {
      return "";
    }
  }

  function safeDateTime(iso) {
    if (!iso) return "";
    try {
      return new Date(iso).toLocaleString("vi-VN");
    } catch (_) {
      return "";
    }
  }

  function daysOpen(iso) {
    if (!iso) return 0;
    try {
      const ms = Date.now() - new Date(iso).getTime();
      return Math.max(0, Math.round(ms / 86400000));
    } catch (_) {
      return 0;
    }
  }

  function propsOrDefault(row) {
    const p = (row.props || {});
    return {
      reviewers: Array.isArray(p.reviewers) ? p.reviewers : [],
      refs: Array.isArray(p.refs) ? p.refs : [],
      viewpoint: p.viewpoint || null,
      cost: (p.cost && typeof p.cost === "object") ? p.cost : { on: false },
      schedule: (p.schedule && typeof p.schedule === "object") ? p.schedule : { on: false },
      drawing: p.drawing || "",
      spec: p.spec || "",
    };
  }

  /* ---------- main API ---------- */
  async function rfis() {
    if (!sb) return [];
    try {
      const pid = await cdeData.projectId();
      if (!pid) return [];   // lọc theo dự án ở FE (RLS đọc đang mở — tránh rò chéo dự án)
      // fetch rfis của dự án hiện tại
      const { data: rfiRows, error: rfiErr } = await sb
        .from("rfis")
        .select("*")
        .eq("project_id", pid)
        .order("created_at", { ascending: false });
      if (rfiErr) throw rfiErr;
      if (!rfiRows || !rfiRows.length) return [];

      // fetch responses của các rfi đó
      const rids = rfiRows.map(r => r.id);
      const { data: respRows, error: respErr } = await sb
        .from("rfi_responses")
        .select("*")
        .in("rfi_id", rids);
      if (respErr) throw respErr;

      // group responses by rfi_id
      const respByRfi = {};
      if (respRows) {
        for (const r of respRows) {
          const rid = r.rfi_id;
          if (!respByRfi[rid]) respByRfi[rid] = [];
          respByRfi[rid].push(r);
        }
      }

      // map rows to desired shape
      return rfiRows.map((row) => {
        const p = propsOrDefault(row);
        const responses = (respByRfi[row.id] || []).map((r) => ({
          author: r.author,
          company: r.company || "",
          date: safeDateTime(r.created_at),
          official: !!r.official,
          body: r.body,
        }));
        return {
          id: row.id,
          num: row.code,
          subject: row.subject,
          disc: row.disc,
          type: row.type,
          prio: row.priority,
          status: row.status,
          question: row.question,
          proposed: row.proposed,
          suit: row.suit,
          bic: row.bic,
          originator: row.originator,
          manager: row.manager,
          due: row.due,
          linkedIssue: row.linked_issue,
          reviewers: p.reviewers,
          refs: p.refs,
          viewpoint: p.viewpoint,
          cost: p.cost,
          schedule: p.schedule,
          drawing: p.drawing,
          spec: p.spec,
          created: safeDate(row.created_at),
          daysOpen: daysOpen(row.created_at),
          responses: responses,
          activity: [],
        };
      });
    } catch (_) {
      return [];
    }
  }

  async function createRfi(p) {
    if (!sb) throw new Error("Supabase not available");
    const pid = await cdeData.projectId();
    const code = await cdeData.nextCode("rfis", "RFI-");
    const insertObj = {
      project_id: pid,
      code: code,
      subject: p.subject,
      disc: p.disc,
      type: p.type,
      priority: p.prio || "normal",
      status: "open",
      question: p.question,
      proposed: p.proposed,
      suit: p.suit,
      bic: p.bic,
      originator: p.originator,
      manager: p.manager,
      due: p.due,
      props: {
        reviewers: p.reviewers || [],
        refs: p.refs || [],
        viewpoint: p.viewpoint || null,
        cost: p.cost || { on: false },
        schedule: p.schedule || { on: false },
        drawing: p.drawing || "",
        spec: p.spec || "",
      },
    };
    const { data, error } = await sb
      .from("rfis")
      .insert(insertObj)
      .select()
      .maybeSingle();
    if (error) throw error;
    // audit
    try {
      await cdeData.logAudit({
        project_id: pid,
        action: "rfi_open",
        target_type: "rfi",
        target_id: code,
      });
    } catch (_) {
      // non‑fatal
    }
    return data;
  }

  async function setRfiStatus(id, status) {
    if (!sb) throw new Error("Supabase not available");
    const { data, error } = await sb
      .from("rfis")
      .update({ status: status, updated_at: new Date().toISOString() })
      .eq("id", id)
      .select()
      .maybeSingle();
    if (error) throw error;
    // audit
    try {
      await cdeData.logAudit({
        action: "rfi:" + status,
        target_type: "rfi",
        target_id: data.code,
      });
    } catch (_) {
      // non‑fatal
    }
    return data;
  }

  async function addRfiResponse(rfiId, body, official) {
    if (!sb) throw new Error("Supabase not available");
    const insertObj = {
      rfi_id: rfiId,
      body: body,
      official: !!official,
    };
    const { error } = await sb.from("rfi_responses").insert(insertObj);
    if (error) throw error;
  }

  /* ---------- expose ---------- */
  window.cdeRfi = {
    rfis: rfis,
    createRfi: createRfi,
    setRfiStatus: setRfiStatus,
    addRfiResponse: addRfiResponse,
  };
})();
