/**
 * API Client — ارتباط frontend با Core Backend (پنل ادمین / tenant).
 * توکن SSO مرکزی (Keycloak) از sessionStorage استفاده می‌شود.
 */

import { getValidAccessToken } from "@/lib/auth";

const SERVER_API_BASE =
  process.env.NEXT_PUBLIC_API_BASE_URL ||
  process.env.NEXT_PUBLIC_BACKEND_URL ||
  "http://localhost:8000";
const API_BASE = typeof window === "undefined" ? SERVER_API_BASE : "/api/core";

export class ApiError extends Error {
  constructor(
    public status: number,
    public code: string,
    message: string
  ) {
    super(message);
    this.name = "ApiError";
  }
}

interface RequestOptions extends RequestInit {
  auth?: boolean;
}

async function request<T>(
  path: string,
  options: RequestOptions = {}
): Promise<T> {
  const { auth = true, headers: customHeaders, ...init } = options;

  const headers = new Headers(customHeaders);
  headers.set("Content-Type", "application/json");

  if (auth) {
    const token = await getValidAccessToken();
    if (token) headers.set("Authorization", `Bearer ${token}`);
  }

  let res: Response;
  try {
    res = await fetch(`${API_BASE}${path}`, { ...init, headers });
  } catch {
    throw new Error(`اتصال به سرور برقرار نشد (${API_BASE})`);
  }

  if (res.status === 401 && auth) {
    const { refreshSession } = await import("@/lib/auth");
    const refreshed = await refreshSession({ force: true });
    if (refreshed) {
      headers.set("Authorization", `Bearer ${refreshed}`);
      res = await fetch(`${API_BASE}${path}`, { ...init, headers });
    }
  }

  if (!res.ok) {
    const body = await res.json().catch(() => ({}));
    throw new ApiError(
      res.status,
      body?.error?.code || "unknown_error",
      body?.error?.message || res.statusText
    );
  }

  if (res.status === 204) return undefined as T;
  return res.json() as Promise<T>;
}

export interface PublicTenantSite {
  tenant_id: string;
  name: string;
  slug: string;
  status: string;
  business_type: string | null;
  primary_color: string | null;
  secondary_color: string | null;
  logo_url: string | null;
  favicon_url: string | null;
  primary_domain: string | null;
  tagline: string;
}

export interface OtpRequestResult {
  message: string;
  expires_in: number;
  skipped?: boolean;
}

type OtpContext = "public" | "admin";

export interface OtpVerifyResult {
  access_token: string;
  refresh_token: string;
  token_type: string;
  expires_in: number;
  is_new_user: boolean;
  user_id: string;
  role: string;
}

export interface Tenant {
  id: string;
  name: string;
  slug: string;
  status: string;
  owner_user_id: string | null;
  business_type?: string | null;
  default_locale?: string;
  timezone?: string;
  primary_color?: string | null;
  secondary_color?: string | null;
  logo_url?: string | null;
  favicon_url?: string | null;
  onboarding_completed?: boolean;
  created_at: string;
  updated_at: string;
}

export interface Page<T> {
  items: T[];
  meta: {
    page: number;
    page_size: number;
    total_items: number;
    total_pages: number;
  };
}

// ---- فاز ۳: Onboarding و Tenant Context ----

export interface MembershipSummary {
  tenant_id: string;
  tenant_name: string;
  tenant_slug: string;
  tenant_status: string;
  onboarding_completed: boolean;
  role: string;
  status: string;
  is_owner: boolean;
}

export interface MeResponse {
  user_id: string;
  mobile: string;
  email: string | null;
  platform_role: string;
  onboarding_required: boolean;
  current_tenant_id: string | null;
  memberships: MembershipSummary[];
}

export interface TenantDomain {
  id: string;
  tenant_id: string;
  domain: string;
  domain_type: string;
  is_verified: boolean;
  verified_at: string | null;
  created_at: string;
}

export interface TenantContext {
  tenant: Tenant;
  role: string | null;
  is_owner: boolean;
  plan_code: string | null;
  plan_name: string | null;
  subscription_status: string | null;
  domains: TenantDomain[];
  primary_domain: string | null;
}

export interface OnboardingTenantCreateInput {
  business_name: string;
  slug: string;
  business_type?: string;
  default_locale?: string;
  timezone?: string;
}

export interface OnboardingBrandingInput {
  primary_color?: string;
  secondary_color?: string;
  logo_url?: string;
  favicon_url?: string;
}

export interface OnboardingDomainInput {
  custom_domain?: string;
}

// ---- مدیریت پلتفرم (پنل ادمین): سرویس‌ها ----
// commercial plans/features/subscriptions → /api/v1/commercial/* only

export type ServiceStatus = "active" | "inactive" | "maintenance";

export interface ServiceEntry {
  id: string;
  service_key: string;
  name: string;
  base_url: string | null;
  status: ServiceStatus;
  health_check_url: string | null;
  created_at: string;
}

export const api = {
  public: {
    tenantSite: (opts?: { slug?: string | null; host?: string | null }) => {
      const params = new URLSearchParams();
      if (opts?.slug) params.set("slug", opts.slug);
      const q = params.toString();
      const headers: Record<string, string> = {};
      if (opts?.slug) headers["X-Tenant-Slug"] = opts.slug;
      if (opts?.host) headers["X-Forwarded-Host"] = opts.host;
      return request<PublicTenantSite>(
        `/api/v1/public/tenant-site${q ? `?${q}` : ""}`,
        { auth: false, headers }
      );
    },
  },

  auth: {
    requestOtp: (mobile: string, options?: { forceSms?: boolean; context?: OtpContext }) =>
      request<OtpRequestResult>("/api/v1/auth/otp/request", {
        method: "POST",
        auth: false,
        body: JSON.stringify({
          mobile,
          context: options?.context ?? "admin",
          ...(options?.forceSms ? { force_sms: true } : {}),
        }),
      }),

    verifyOtp: (mobile: string, code: string, context: OtpContext = "admin") =>
      request<OtpVerifyResult>("/api/v1/auth/otp/verify", {
        method: "POST",
        auth: false,
        body: JSON.stringify({ mobile, code, context }),
      }),
  },

  tenants: {
    list: (page = 1, pageSize = 20) =>
      request<Page<Tenant>>(
        `/api/v1/admin/tenants?page=${page}&page_size=${pageSize}`
      ),

    get: (id: string) => request<Tenant>(`/api/v1/admin/tenants/${id}`),

    create: (data: { name: string; slug: string; custom_domain?: string }) =>
      request<Tenant>("/api/v1/admin/tenants", {
        method: "POST",
        body: JSON.stringify(data),
      }),

    update: (id: string, data: { name?: string }) =>
      request<Tenant>(`/api/v1/admin/tenants/${id}`, {
        method: "PATCH",
        body: JSON.stringify(data),
      }),
  },

  me: {
    get: () => request<MeResponse>("/api/v1/me"),
    tenants: () => request<MembershipSummary[]>("/api/v1/me/tenants"),
  },

  onboarding: {
    createTenant: (data: OnboardingTenantCreateInput) =>
      request<TenantContext>("/api/v1/onboarding/tenant", {
        method: "POST",
        body: JSON.stringify(data),
      }),

    updateBranding: (tenantId: string, data: OnboardingBrandingInput) =>
      request<TenantContext>(`/api/v1/onboarding/tenant/${tenantId}/branding`, {
        method: "PATCH",
        body: JSON.stringify(data),
      }),

    updateDomain: (tenantId: string, data: OnboardingDomainInput) =>
      request<TenantContext>(`/api/v1/onboarding/tenant/${tenantId}/domain`, {
        method: "PATCH",
        body: JSON.stringify(data),
      }),

    complete: (tenantId: string) =>
      request<TenantContext>(`/api/v1/onboarding/tenant/${tenantId}/complete`, {
        method: "POST",
      }),
  },

  tenantContext: {
    current: () => request<TenantContext>("/api/v1/tenant/current"),

    switchTenant: (tenantId: string) =>
      request<TenantContext>("/api/v1/tenant/switch", {
        method: "POST",
        body: JSON.stringify({ tenant_id: tenantId }),
      }),
  },

  // مدیریت پلتفرمی tenantها (نیازمند نقش platform_admin)
  platformTenants: {
    list: (page = 1, pageSize = 50) =>
      request<Page<Tenant>>(`/api/v1/tenants?page=${page}&page_size=${pageSize}`),

    get: (id: string) => request<Tenant>(`/api/v1/tenants/${id}`),

    create: (data: {
      name: string;
      slug: string;
      owner_user_id?: string | null;
      custom_domain?: string | null;
    }) =>
      request<Tenant>("/api/v1/tenants", {
        method: "POST",
        body: JSON.stringify(data),
      }),

    update: (
      id: string,
      data: { name?: string; status?: string; owner_user_id?: string | null }
    ) =>
      request<Tenant>(`/api/v1/tenants/${id}`, {
        method: "PATCH",
        body: JSON.stringify(data),
      }),

    suspend: (id: string) =>
      request<Tenant>(`/api/v1/tenants/${id}/suspend`, { method: "POST" }),

    activate: (id: string) =>
      request<Tenant>(`/api/v1/tenants/${id}/activate`, { method: "POST" }),
  },

  domains: {
    listForTenant: (tenantId: string) =>
      request<TenantDomain[]>(`/api/v1/tenants/${tenantId}/domains`),

    create: (
      tenantId: string,
      data: { domain: string; domain_type?: "subdomain" | "custom_domain" }
    ) =>
      request<TenantDomain>(`/api/v1/tenants/${tenantId}/domains`, {
        method: "POST",
        body: JSON.stringify(data),
      }),
  },

  services: {
    list: (page = 1, pageSize = 100) =>
      request<Page<ServiceEntry>>(`/api/v1/services?page=${page}&page_size=${pageSize}`),

    create: (data: {
      service_key: string;
      name: string;
      base_url?: string | null;
      health_check_url?: string | null;
      status?: ServiceStatus;
    }) =>
      request<ServiceEntry>("/api/v1/services", {
        method: "POST",
        body: JSON.stringify(data),
      }),

    updateStatus: (serviceId: string, status: ServiceStatus) =>
      request<ServiceEntry>(`/api/v1/services/${serviceId}/status`, {
        method: "PATCH",
        body: JSON.stringify({ status }),
      }),
  },
};
