(function () {
  "use strict";

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

  /* ------------------------------------------------------------------ */
  /*  list()                                                             */
  /* ------------------------------------------------------------------ */
  async function list() {
    if (!sb) return [];
    try {
      const pid = await cdeData.projectId();
      const { data, error } = await sb
        .from("approval_workflows")
        .select("id, name, active, version, updated_at, config")
        .eq("project_id", pid)
        .order("updated_at", { ascending: false });

      if (error) {
        console.warn("approval-data list error", error);
        return [];
      }
      return data || [];
    } catch (e) {
      console.warn("approval-data list exception", e);
      return [];
    }
  }

  /* ------------------------------------------------------------------ */
  /*  get(id)                                                            */
  /* ------------------------------------------------------------------ */
  async function get(id) {
    if (!sb) return null;
    try {
      const { data, error } = await sb
        .from("approval_workflows")
        .select("*")
        .eq("id", id)
        .maybeSingle();

      if (error) {
        console.warn("approval-data get error", error);
        return null;
      }
      if (!data) return null;

      return {
        id: data.id,
        name: data.name,
        config: data.config,
        active: data.active,
        version: data.version,
      };
    } catch (e) {
      console.warn("approval-data get exception", e);
      return null;
    }
  }

  /* ------------------------------------------------------------------ */
  /*  create(name)                                                       */
  /* ------------------------------------------------------------------ */
  async function create(name) {
    if (!sb) throw new Error("Supabase not available");
    try {
      const pid = await cdeData.projectId();
      const { data, error } = await sb
        .from("approval_workflows")
        .insert({
          project_id: pid,
          name: name || "Luồng mới",
          config: { gates: [], nodes: [] },
          active: false,
        })
        .select()
        .maybeSingle();

      if (error) {
        console.warn("approval-data create error", error);
        throw error;
      }

      // audit log
      try {
        await cdeData.logAudit({
          project_id: pid,
          action: "approval_wf_create",
          target_type: "workflow",
          target_id: name || "Luồng mới",
        });
      } catch (_) {
        // non‑fatal
      }

      return data;
    } catch (e) {
      console.warn("approval-data create exception", e);
      throw e;
    }
  }

  /* ------------------------------------------------------------------ */
  /*  save(id, name, config)                                             */
  /* ------------------------------------------------------------------ */
  async function save(id, name, config) {
    if (!sb) throw new Error("Supabase not available");
    try {
      // fetch current version
      const { data: current, error: fetchErr } = await sb
        .from("approval_workflows")
        .select("version")
        .eq("id", id)
        .maybeSingle();

      if (fetchErr) {
        console.warn("approval-data save fetch error", fetchErr);
        throw fetchErr;
      }
      if (!current) {
        throw new Error("Workflow not found");
      }

      const newVersion = (current.version || 0) + 1;

      const { data: updated, error: updErr } = await sb
        .from("approval_workflows")
        .update({
          name: name,
          config: config,
          version: newVersion,
          updated_at: new Date().toISOString(),
        })
        .eq("id", id)
        .select()
        .maybeSingle();

      if (updErr) {
        console.warn("approval-data save update error", updErr);
        throw updErr;
      }

      // audit log
      try {
        const pid = await cdeData.projectId();
        await cdeData.logAudit({
          project_id: pid,
          action: "approval_wf_save",
          target_type: "workflow",
          target_id: name,
        });
      } catch (_) {
        // non‑fatal
      }

      return updated;
    } catch (e) {
      console.warn("approval-data save exception", e);
      throw e;
    }
  }

  /* ------------------------------------------------------------------ */
  /*  setActive(id)                                                      */
  /* ------------------------------------------------------------------ */
  async function setActive(id) {
    if (!sb) throw new Error("Supabase not available");
    try {
      const pid = await cdeData.projectId();

      // deactivate all workflows for this project
      const { error: deactErr } = await sb
        .from("approval_workflows")
        .update({ active: false })
        .eq("project_id", pid);

      if (deactErr) {
        console.warn("approval-data setActive deactivate error", deactErr);
        throw deactErr;
      }

      // activate the chosen one
      const { data, error: actErr } = await sb
        .from("approval_workflows")
        .update({
          active: true,
          updated_at: new Date().toISOString(),
        })
        .eq("id", id)
        .select()
        .maybeSingle();

      if (actErr) {
        console.warn("approval-data setActive activate error", actErr);
        throw actErr;
      }

      // audit log
      try {
        await cdeData.logAudit({
          project_id: pid,
          action: "approval_wf_activate",
          target_type: "workflow",
          target_id: id,
        });
      } catch (_) {
        // non‑fatal
      }

      return data;
    } catch (e) {
      console.warn("approval-data setActive exception", e);
      throw e;
    }
  }

  /* ------------------------------------------------------------------ */
  /*  remove(id)                                                         */
  /* ------------------------------------------------------------------ */
  async function remove(id) {
    if (!sb) throw new Error("Supabase not available");
    try {
      // .select() để biết số dòng thực xóa: nếu RLS lọc (0 dòng) thì PostgREST KHÔNG báo lỗi
      // → phải fail-loud, tránh nút "Xoá luồng" im lặng không tác dụng (bug RLS thiếu DELETE, xem 0030).
      const { data, error } = await sb
        .from("approval_workflows")
        .delete()
        .eq("id", id)
        .select();

      if (error) {
        console.warn("approval-data remove error", error);
        throw error;
      }
      if (!data || !data.length) {
        throw new Error("Không xóa được luồng (thiếu quyền hoặc luồng đã bị xóa).");
      }

      // audit log
      try {
        const pid = await cdeData.projectId();
        await cdeData.logAudit({
          project_id: pid,
          action: "approval_wf_delete",
          target_type: "workflow",
          target_id: id,
        });
      } catch (_) {
        // non‑fatal
      }
    } catch (e) {
      console.warn("approval-data remove exception", e);
      throw e;
    }
  }

  /* ------------------------------------------------------------------ */
  /*  export                                                             */
  /* ------------------------------------------------------------------ */
  window.cdeApproval = {
    list: list,
    get: get,
    create: create,
    save: save,
    setActive: setActive,
    remove: remove,
  };
})();
