import { useRuntimeConfig } from "#app";
import type { FetchResponse } from "ofetch";
import { workpulseApiRaw } from "~/utils/workpulse-api-fetch";
import { userFacingApiError } from "~/utils/workpulse-api-error";
import { normalizeWorkpulseApiBase } from "~/utils/workpulse-api-base";
import { readWorkpulseAccessToken } from "~/utils/workpulse-session-user";
import { useAuth } from "./useAuth";

type ApiEnvelope<T> = {
  ok: boolean;
  data?: T;
  error?: { code?: string; message?: string };
};

export type MasterOrgDivision = {
  id: number;
  code: string;
  name: string;
  description?: string;
  sortOrder: number;
  isActive: boolean;
  createdAt?: string | null;
  updatedAt?: string | null;
};

export type OrgDivisionMemberRow = {
  userId: number;
  name: string;
  email: string;
  isActive: boolean;
  orgRole: string;
};

function apiBase(): string {
  return normalizeWorkpulseApiBase(String(useRuntimeConfig().public.workpulseApiBase || ""));
}

function bearerHeaders(): { Authorization: string } | undefined {
  const { accessToken } = useAuth();
  const t = accessToken.value || readWorkpulseAccessToken();
  if (!t) return undefined;
  return { Authorization: `Bearer ${t}` };
}

async function parseEnvelope<T>(raw: FetchResponse<unknown>): Promise<{
  ok: boolean;
  status: number;
  data?: T;
  message?: string;
}> {
  const status = raw.status;
  let body = raw._data as ApiEnvelope<T> | string | undefined;
  if (typeof body === "string") {
    try {
      body = JSON.parse(body) as ApiEnvelope<T>;
    } catch {
      body = undefined;
    }
  }
  if (!body) return { ok: false, status, message: `HTTP ${status}` };
  if (!body.ok) {
    return {
      ok: false,
      status,
      message: body.error?.message || body.error?.code || `HTTP ${status}`
    };
  }
  return { ok: true, status, data: body.data as T };
}

/** Superadmin: master divisi + anggota (`/api/v1/org/divisions`). */
export function useWorkpulseOrgDivisions() {
  const listDivisions = async (params: { limit?: number; offset?: number; active?: "1" | "0" | "all" } = {}) => {
    const b = apiBase();
    if (!b) return { ok: false as const, status: 0, message: "API belum dikonfigurasi." };
    const qs = new URLSearchParams();
    qs.set("limit", String(params.limit ?? 500));
    if (params.offset != null) qs.set("offset", String(params.offset));
    if (params.active) qs.set("active", params.active);
    const raw = await workpulseApiRaw(`${b}/api/v1/org/divisions?${qs}`, {
      method: "GET",
      headers: bearerHeaders(),
      credentials: "include",
      ignoreResponseError: true
    });
    return parseEnvelope<{ divisions: MasterOrgDivision[]; total: number }>(raw);
  };

  const createDivision = async (body: { code: string; name: string; description?: string; sortOrder?: number }) => {
    const b = apiBase();
    if (!b) return { ok: false as const, status: 0, message: "API belum dikonfigurasi." };
    const payload: Record<string, unknown> = { code: body.code.trim(), name: body.name.trim() };
    if (body.description != null && body.description.trim() !== "") payload.description = body.description.trim();
    if (body.sortOrder != null) payload.sortOrder = body.sortOrder;
    const raw = await workpulseApiRaw(`${b}/api/v1/org/divisions`, {
      method: "POST",
      headers: bearerHeaders(),
      credentials: "include",
      body: payload,
      ignoreResponseError: true
    });
    return parseEnvelope<{ id: number }>(raw);
  };

  const updateDivision = async (
    id: number,
    body: { name?: string; description?: string; sortOrder?: number; isActive?: boolean }
  ) => {
    const b = apiBase();
    if (!b) return { ok: false as const, status: 0, message: "API belum dikonfigurasi." };
    const payload: Record<string, unknown> = {};
    if (body.name != null) payload.name = body.name.trim();
    if (body.description != null) payload.description = body.description.trim();
    if (body.sortOrder != null) payload.sortOrder = body.sortOrder;
    if (body.isActive != null) payload.isActive = body.isActive;
    const raw = await workpulseApiRaw(`${b}/api/v1/org/divisions/${id}`, {
      method: "PATCH",
      headers: bearerHeaders(),
      credentials: "include",
      body: payload,
      ignoreResponseError: true
    });
    const parsed = await parseEnvelope<{ id: number }>(raw);
    if (!parsed.ok) {
      return {
        ...parsed,
        message: userFacingApiError({
          code: (raw._data as ApiEnvelope<unknown>)?.error?.code,
          message: parsed.message,
          fallback: "Gagal menyimpan perubahan divisi."
        })
      };
    }
    return parsed;
  };

  const listMembers = async (divisionId: number) => {
    const b = apiBase();
    if (!b) return { ok: false as const, status: 0, message: "API belum dikonfigurasi." };
    const raw = await workpulseApiRaw(`${b}/api/v1/org/divisions/${divisionId}/members`, {
      method: "GET",
      headers: bearerHeaders(),
      credentials: "include",
      ignoreResponseError: true
    });
    return parseEnvelope<{ divisionId: number; members: OrgDivisionMemberRow[] }>(raw);
  };

  const postMember = async (divisionId: number, body: { userId: number; orgRole?: string }) => {
    const b = apiBase();
    if (!b) return { ok: false as const, status: 0, message: "API belum dikonfigurasi." };
    const raw = await workpulseApiRaw(`${b}/api/v1/org/divisions/${divisionId}/members`, {
      method: "POST",
      headers: bearerHeaders(),
      credentials: "include",
      body: { userId: body.userId, orgRole: body.orgRole ?? "" },
      ignoreResponseError: true
    });
    return parseEnvelope<{ divisionId: number; userId: number; orgRole: string }>(raw);
  };

  const deleteMember = async (divisionId: number, userId: number) => {
    const b = apiBase();
    if (!b) return { ok: false as const, status: 0, message: "API belum dikonfigurasi." };
    const raw = await workpulseApiRaw(`${b}/api/v1/org/divisions/${divisionId}/members/${userId}`, {
      method: "DELETE",
      headers: bearerHeaders(),
      credentials: "include",
      ignoreResponseError: true
    });
    return parseEnvelope<{ divisionId: number; userId: number }>(raw);
  };

  return { listDivisions, createDivision, updateDivision, listMembers, postMember, deleteMember };
}
