// @File: src/lib/bizmailApi.ts
// @Desc: Typed fetch wrappers for the Bizmail360 Reseller Manager module.
//        Mirrors the conventions in adminApi.ts / uptimerobotApi.ts —
//        authenticated with the app JWT from localStorage, JSON error
//        envelopes parsed into a single string message.
import { getToken } from "@/lib/auth";

// ---------- helpers ----------
function authHeaders(extra?: Record<string, string>): HeadersInit {
  const token = getToken();
  return {
    "Content-Type": "application/json",
    ...(token ? { Authorization: `Bearer ${token}` } : {}),
    ...(extra ?? {}),
  };
}

async function handle<T>(res: Response): Promise<T> {
  const raw = await res.text();
  let data: unknown = null;
  if (raw) {
    try {
      data = JSON.parse(raw);
    } catch {
      data = raw;
    }
  }
  if (!res.ok) {
    const detail =
      data && typeof data === "object" && "detail" in (data as Record<string, unknown>)
        ? String((data as Record<string, unknown>).detail)
        : null;
    throw new Error(detail || res.statusText || "Request failed");
  }
  return data as T;
}

// ---------- types ----------
export interface BizmailPlan {
  id: number;
  slug: string;
  name: string;
  description: string | null;
  price_monthly: string | null;
  price_yearly: string | null;
  currency: string;
  mailbox_quota: number;
  storage_mb_per_mailbox: number;
  aliases_included: number;
  features: string | null;
  is_active: boolean;
  is_featured: boolean;
  sort_order: number;
  created_at: string;
  updated_at: string;
}

export interface BizmailSubscription {
  id: number;
  user_id: string;
  user_email: string | null;
  plan_id: number;
  domain_name: string;
  smartermail_domain_ref: string | null;
  status: "pending" | "active" | "suspended" | "cancelled";
  billing_cycle: "monthly" | "yearly";
  primary_mailbox: string | null;
  provisioned_at: string | null;
  activated_at: string | null;
  suspended_at: string | null;
  cancelled_at: string | null;
  current_period_end: string | null;
  notes: string | null;
  mailboxes_used: number;
  aliases_used: number;
  plan?: BizmailPlan | null;
  mailbox_quota?: number | null;
  aliases_included?: number | null;
  storage_mb_per_mailbox?: number | null;
  created_at: string;
  updated_at: string;
}

export interface BizmailActivationResult {
  subscription: BizmailSubscription;
  primary_mailbox: string | null;
  primary_password: string | null;
}

export interface BizmailMailbox {
  username: string;
  display_name: string | null;
  is_domain_admin: boolean;
  disabled: boolean;
  storage_mb: number | null;
}

export interface BizmailAlias {
  name: string;
  addresses: string[];
}

export interface BizmailForwarding {
  username: string;
  forward_to: string;
  enabled: boolean;
}

export interface BizmailUsage {
  mailboxes_used: number;
  mailbox_quota: number;
  aliases_used: number;
  aliases_included: number;
  storage_used_mb: number;
  storage_quota_mb: number;
  degraded: boolean;
  message?: string | null;
}

export interface BizmailSubscriptionActionResult {
  subscription: BizmailSubscription;
  message: string;
}

export interface BizmailAuditLog {
  id: number;
  subscription_id: number | null;
  actor_user_id: string | null;
  actor_email: string | null;
  action: string;
  target: string | null;
  status: string;
  error_message: string | null;
  created_at: string;
}

export interface BizmailIntegrationTestResult {
  ok: boolean;
  message: string;
  latency_ms: number | null;
}

// ---------- public ----------
export async function fetchPublicPlans(): Promise<BizmailPlan[]> {
  const res = await fetch("/api/v1/public/bizmail/plans");
  return handle<BizmailPlan[]>(res);
}

// ---------- client ----------
export async function fetchMySubscriptions(): Promise<BizmailSubscription[]> {
  const res = await fetch("/api/v1/client/bizmail/subscriptions", { headers: authHeaders() });
  return handle<BizmailSubscription[]>(res);
}

export async function fetchMySubscription(id: number): Promise<BizmailSubscription> {
  const res = await fetch(`/api/v1/client/bizmail/subscriptions/${id}`, { headers: authHeaders() });
  return handle<BizmailSubscription>(res);
}

export async function orderSubscription(payload: {
  plan_id: number;
  domain_name: string;
  billing_cycle: "monthly" | "yearly";
}): Promise<BizmailSubscription> {
  const res = await fetch("/api/v1/client/bizmail/subscriptions", {
    method: "POST",
    headers: authHeaders(),
    body: JSON.stringify(payload),
  });
  return handle<BizmailSubscription>(res);
}

export async function activateMySubscription(id: number): Promise<BizmailActivationResult> {
  const res = await fetch(`/api/v1/client/bizmail/subscriptions/${id}/activate`, {
    method: "POST",
    headers: authHeaders(),
  });
  return handle<BizmailActivationResult>(res);
}

export async function cancelMySubscription(id: number): Promise<BizmailSubscriptionActionResult> {
  const res = await fetch(`/api/v1/client/bizmail/subscriptions/${id}/cancel`, {
    method: "POST",
    headers: authHeaders(),
  });
  return handle<BizmailSubscriptionActionResult>(res);
}

export async function fetchMailboxes(id: number): Promise<BizmailMailbox[]> {
  const res = await fetch(`/api/v1/client/bizmail/subscriptions/${id}/mailboxes`, {
    headers: authHeaders(),
  });
  return handle<BizmailMailbox[]>(res);
}

export async function createMailbox(
  id: number,
  payload: { username: string; password: string; display_name?: string; is_domain_admin?: boolean }
): Promise<BizmailMailbox> {
  const res = await fetch(`/api/v1/client/bizmail/subscriptions/${id}/mailboxes`, {
    method: "POST",
    headers: authHeaders(),
    body: JSON.stringify(payload),
  });
  return handle<BizmailMailbox>(res);
}

export async function updateMailbox(
  id: number,
  username: string,
  payload: { display_name?: string; disabled?: boolean }
): Promise<BizmailMailbox> {
  const res = await fetch(
    `/api/v1/client/bizmail/subscriptions/${id}/mailboxes/${encodeURIComponent(username)}`,
    { method: "PUT", headers: authHeaders(), body: JSON.stringify(payload) }
  );
  return handle<BizmailMailbox>(res);
}

export async function resetMailboxPassword(
  id: number,
  username: string,
  newPassword: string
): Promise<BizmailMailbox> {
  const res = await fetch(
    `/api/v1/client/bizmail/subscriptions/${id}/mailboxes/${encodeURIComponent(username)}/reset-password`,
    { method: "POST", headers: authHeaders(), body: JSON.stringify({ new_password: newPassword }) }
  );
  return handle<BizmailMailbox>(res);
}

export async function deleteMailbox(
  id: number,
  username: string
): Promise<BizmailSubscriptionActionResult> {
  const res = await fetch(
    `/api/v1/client/bizmail/subscriptions/${id}/mailboxes/${encodeURIComponent(username)}`,
    { method: "DELETE", headers: authHeaders() }
  );
  return handle<BizmailSubscriptionActionResult>(res);
}

export async function fetchAliases(id: number): Promise<BizmailAlias[]> {
  const res = await fetch(`/api/v1/client/bizmail/subscriptions/${id}/aliases`, {
    headers: authHeaders(),
  });
  return handle<BizmailAlias[]>(res);
}

export async function createAlias(
  id: number,
  payload: { alias_name: string; targets: string[] }
): Promise<BizmailAlias> {
  const res = await fetch(`/api/v1/client/bizmail/subscriptions/${id}/aliases`, {
    method: "POST",
    headers: authHeaders(),
    body: JSON.stringify(payload),
  });
  return handle<BizmailAlias>(res);
}

export async function deleteAlias(
  id: number,
  aliasName: string
): Promise<BizmailSubscriptionActionResult> {
  const res = await fetch(
    `/api/v1/client/bizmail/subscriptions/${id}/aliases/${encodeURIComponent(aliasName)}`,
    { method: "DELETE", headers: authHeaders() }
  );
  return handle<BizmailSubscriptionActionResult>(res);
}

export async function fetchForwarding(id: number, username: string): Promise<BizmailForwarding> {
  const res = await fetch(
    `/api/v1/client/bizmail/subscriptions/${id}/mailboxes/${encodeURIComponent(username)}/forwarding`,
    { headers: authHeaders() }
  );
  return handle<BizmailForwarding>(res);
}

export async function setForwarding(
  id: number,
  username: string,
  forwardTo: string
): Promise<BizmailForwarding> {
  const res = await fetch(
    `/api/v1/client/bizmail/subscriptions/${id}/mailboxes/${encodeURIComponent(username)}/forwarding`,
    { method: "PUT", headers: authHeaders(), body: JSON.stringify({ forward_to: forwardTo }) }
  );
  return handle<BizmailForwarding>(res);
}

export async function fetchUsage(id: number): Promise<BizmailUsage> {
  const res = await fetch(`/api/v1/client/bizmail/subscriptions/${id}/usage`, {
    headers: authHeaders(),
  });
  return handle<BizmailUsage>(res);
}

// ---------- admin ----------
export async function adminListPlans(includeInactive = true): Promise<BizmailPlan[]> {
  const res = await fetch(
    `/api/v1/admin/bizmail/plans?include_inactive=${includeInactive ? "true" : "false"}`,
    { headers: authHeaders() }
  );
  return handle<BizmailPlan[]>(res);
}

export async function adminCreatePlan(payload: Partial<BizmailPlan>): Promise<BizmailPlan> {
  const res = await fetch("/api/v1/admin/bizmail/plans", {
    method: "POST",
    headers: authHeaders(),
    body: JSON.stringify(payload),
  });
  return handle<BizmailPlan>(res);
}

export async function adminUpdatePlan(
  id: number,
  payload: Partial<BizmailPlan>
): Promise<BizmailPlan> {
  const res = await fetch(`/api/v1/admin/bizmail/plans/${id}`, {
    method: "PUT",
    headers: authHeaders(),
    body: JSON.stringify(payload),
  });
  return handle<BizmailPlan>(res);
}

export async function adminDeletePlan(id: number): Promise<void> {
  const res = await fetch(`/api/v1/admin/bizmail/plans/${id}`, {
    method: "DELETE",
    headers: authHeaders(),
  });
  if (!res.ok && res.status !== 204) {
    const raw = await res.text();
    throw new Error(raw || res.statusText);
  }
}

export async function adminListSubscriptions(
  status?: string
): Promise<BizmailSubscription[]> {
  const url = status
    ? `/api/v1/admin/bizmail/subscriptions?status=${encodeURIComponent(status)}`
    : "/api/v1/admin/bizmail/subscriptions";
  const res = await fetch(url, { headers: authHeaders() });
  return handle<BizmailSubscription[]>(res);
}

export async function adminSubscriptionAction(
  id: number,
  action: "activate" | "suspend" | "resume" | "cancel"
): Promise<BizmailSubscriptionActionResult> {
  const res = await fetch(`/api/v1/admin/bizmail/subscriptions/${id}/${action}`, {
    method: "POST",
    headers: authHeaders(),
  });
  return handle<BizmailSubscriptionActionResult>(res);
}

export async function adminFetchAuditLog(subscriptionId?: number): Promise<BizmailAuditLog[]> {
  const url = subscriptionId
    ? `/api/v1/admin/bizmail/audit-log?subscription_id=${subscriptionId}`
    : "/api/v1/admin/bizmail/audit-log";
  const res = await fetch(url, { headers: authHeaders() });
  return handle<BizmailAuditLog[]>(res);
}

export async function adminTestIntegration(): Promise<BizmailIntegrationTestResult> {
  const res = await fetch("/api/v1/admin/bizmail/integration/test", {
    method: "POST",
    headers: authHeaders(),
  });
  return handle<BizmailIntegrationTestResult>(res);
}