import { useRuntimeConfig } from "#app";
import type { FetchResponse } from "ofetch";
import { workpulseApiRaw } from "~/utils/workpulse-api-fetch";
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 ReportRow = {
  id: number;
  userId: number;
  teamId?: number | null;
  title: string;
  body: string;
  status: string;
  division?: string | null;
  reportDate?: string | null;
  createdAt?: string;
  updatedAt?: 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 };
}

export function useWorkpulseReports() {
  const listReports = async (params: { limit?: number; offset?: number; from?: string; to?: string } = {}) => {
    const b = apiBase();
    if (!b) return { ok: false as const, status: 0, message: "API belum dikonfigurasi." };
    const qs = new URLSearchParams();
    if (params.limit != null) qs.set("limit", String(params.limit));
    if (params.offset != null) qs.set("offset", String(params.offset));
    if (params.from) qs.set("from", params.from);
    if (params.to) qs.set("to", params.to);
    const q = qs.toString();
    const raw = await workpulseApiRaw(`${b}/api/v1/reports${q ? `?${q}` : ""}`, {
      method: "GET",
      headers: bearerHeaders(),
      credentials: "include",
      ignoreResponseError: true
    });
    return parseEnvelope<ReportRow[]>(raw);
  };

  const getReport = async (id: number) => {
    const b = apiBase();
    if (!b) return { ok: false as const, status: 0, message: "API belum dikonfigurasi." };
    const raw = await workpulseApiRaw(`${b}/api/v1/reports/${id}`, {
      method: "GET",
      headers: bearerHeaders(),
      credentials: "include",
      ignoreResponseError: true
    });
    return parseEnvelope<ReportRow>(raw);
  };

  const createReport = async (body: {
    title: string;
    body: string;
    status?: string;
    division?: string;
    reportDate?: string;
    teamId?: number;
  }) => {
    const b = apiBase();
    if (!b) return { ok: false as const, status: 0, message: "API belum dikonfigurasi." };
    const raw = await workpulseApiRaw(`${b}/api/v1/reports`, {
      method: "POST",
      headers: bearerHeaders(),
      credentials: "include",
      body: {
        title: body.title,
        body: body.body,
        status: body.status ?? "draft",
        division: body.division ?? "",
        reportDate: body.reportDate ?? "",
        ...(body.teamId != null ? { teamId: body.teamId } : {})
      },
      ignoreResponseError: true
    });
    const parsed = await parseEnvelope<{ id: number }>(raw);
    return parsed;
  };

  const patchReport = async (
    id: number,
    patch: { title?: string; body?: string; status?: string; division?: string; reportDate?: string }
  ) => {
    const b = apiBase();
    if (!b) return { ok: false as const, status: 0, message: "API belum dikonfigurasi." };
    const raw = await workpulseApiRaw(`${b}/api/v1/reports/${id}`, {
      method: "PATCH",
      headers: bearerHeaders(),
      credentials: "include",
      body: patch,
      ignoreResponseError: true
    });
    return parseEnvelope<{ id: number }>(raw);
  };

  const uploadReportAttachment = async (reportId: number, file: File) => {
    const b = apiBase();
    if (!b) return { ok: false as const, status: 0, message: "API belum dikonfigurasi." };
    const form = new FormData();
    form.append("file", file, file.name || "screenshot.png");
    const raw = await workpulseApiRaw(`${b}/api/v1/reports/${reportId}/attachments`, {
      method: "POST",
      headers: bearerHeaders(),
      credentials: "include",
      body: form,
      ignoreResponseError: true
    });
    return parseEnvelope<{
      attachment: { id: string; url: string; name: string; mimeType: string; size: number };
      attachments: { id: string; url: string; name: string; mimeType: string; size: number }[];
    }>(raw);
  };

  const deleteReportAttachment = async (reportId: number, attachmentId: string) => {
    const b = apiBase();
    if (!b) return { ok: false as const, status: 0, message: "API belum dikonfigurasi." };
    const raw = await workpulseApiRaw(
      `${b}/api/v1/reports/${reportId}/attachments/${encodeURIComponent(attachmentId)}`,
      {
        method: "DELETE",
        headers: bearerHeaders(),
        credentials: "include",
        ignoreResponseError: true
      }
    );
    return parseEnvelope<{
      attachments: { id: string; url: string; name: string; mimeType: string; size: number }[];
    }>(raw);
  };

  const deleteReport = async (id: number) => {
    const b = apiBase();
    if (!b) return { ok: false as const, status: 0, message: "API belum dikonfigurasi." };
    const raw = await workpulseApiRaw(`${b}/api/v1/reports/${id}`, {
      method: "DELETE",
      headers: bearerHeaders(),
      credentials: "include",
      ignoreResponseError: true
    });
    return parseEnvelope<{ id: number }>(raw);
  };

  return {
    listReports,
    getReport,
    createReport,
    patchReport,
    deleteReport,
    uploadReportAttachment,
    deleteReportAttachment
  };
}
