/**
 * API ثبت‌نام و تأیید موبایل — Identity Service
 */

import type { TokenBundle } from "@/lib/auth";

const IDENTITY_API =
  typeof window !== "undefined"
    ? "/api/identity"
    : process.env.IDENTITY_SERVICE_URL ||
      process.env.NEXT_PUBLIC_IDENTITY_API_URL ||
      "http://localhost:8001";

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

export interface MobileAuthStartResult extends OtpRequestResult {
  intent: "login" | "register";
}

export interface AuthSessionResult extends TokenBundle {
  message: string;
  intent: "login" | "register";
  user_id?: string;
  mobile_verified: boolean;
}

export interface RegisterCompleteResult {
  message: string;
  mobile_verified: boolean;
  user_id?: string;
}

export interface MeProfile {
  user_id: string;
  mobile: string | null;
  mobile_verified: boolean;
  requires_mobile_verification: boolean;
}

export interface TenantMembershipSummary {
  tenant_id: string;
  role: string;
  is_active: boolean;
}

export interface AccountProfile {
  user_id: string;
  keycloak_sub: string;
  email: string | null;
  username: string | null;
  display_name: string | null;
  mobile: string | null;
  mobile_verified: boolean;
  requires_mobile_verification: boolean;
  roles: string[];
  tenant_memberships: TenantMembershipSummary[];
}

export interface AdminUser {
  id: string;
  keycloak_sub: string;
  email: string;
  username: string | null;
  display_name: string | null;
  mobile: string | null;
  mobile_verified: boolean;
  mobile_verified_at: string | null;
  core_user_id: string | null;
  status: string;
  created_at: string;
}

export type MembershipRole = "tenant_admin" | "tenant_member";

export interface TenantMember {
  id: string;
  tenant_id: string;
  user_id: string;
  role: MembershipRole;
  is_active: boolean;
  joined_at: string;
}

function parseIdentityError(body: Record<string, unknown>, fallback: string): string {
  const err = body?.error as { message?: string } | undefined;
  if (err?.message) return err.message;
  if (typeof body?.detail === "string") return body.detail;
  if (Array.isArray(body?.detail) && body.detail[0]?.msg) {
    return String(body.detail[0].msg);
  }
  return fallback;
}

async function identityRequest<T>(
  path: string,
  options: RequestInit & { token?: string | null } = {}
): Promise<T> {
  const { token, headers: customHeaders, ...init } = options;
  const headers = new Headers(customHeaders);
  headers.set("Content-Type", "application/json");
  if (token) headers.set("Authorization", `Bearer ${token}`);

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

  if (!res.ok) {
    const body = (await res.json().catch(() => ({}))) as Record<string, unknown>;
    throw new Error(parseIdentityError(body, res.statusText));
  }
  return res.json() as Promise<T>;
}

export const identityApi = {
  mobileStart: (mobile: string, forceSms = false) =>
    identityRequest<MobileAuthStartResult>("/api/v1/auth/mobile/start", {
      method: "POST",
      body: JSON.stringify({ mobile, force_sms: forceSms }),
    }),

  mobileComplete: (payload: {
    mobile: string;
    code: string;
    display_name?: string;
    email?: string;
    username?: string;
    password?: string;
  }) =>
    identityRequest<AuthSessionResult>("/api/v1/auth/mobile/complete", {
      method: "POST",
      body: JSON.stringify(payload),
    }),

  register: (data: {
    email: string;
    username: string;
    password: string;
    mobile: string;
    display_name?: string;
  }) =>
    identityRequest<OtpRequestResult>("/api/v1/auth/register", {
      method: "POST",
      body: JSON.stringify(data),
    }),

  verifyRegistrationMobile: (mobile: string, code: string) =>
    identityRequest<AuthSessionResult>("/api/v1/auth/register/verify-mobile", {
      method: "POST",
      body: JSON.stringify({ mobile, code }),
    }),

  registerMobileRequest: (mobile: string, forceSms = false) =>
    identityRequest<OtpRequestResult>("/api/v1/auth/register/mobile", {
      method: "POST",
      body: JSON.stringify({ mobile, force_sms: forceSms }),
    }),

  registerMobileVerify: (mobile: string, code: string, display_name?: string) =>
    identityRequest<AuthSessionResult>("/api/v1/auth/register/mobile/verify", {
      method: "POST",
      body: JSON.stringify({ mobile, code, display_name }),
    }),

  requestMobileVerify: (mobile: string, token: string) =>
    identityRequest<OtpRequestResult>("/api/v1/auth/mobile/request", {
      method: "POST",
      token,
      body: JSON.stringify({ mobile }),
    }),

  verifyMobile: (mobile: string, code: string, token: string) =>
    identityRequest<RegisterCompleteResult>("/api/v1/auth/mobile/verify", {
      method: "POST",
      token,
      body: JSON.stringify({ mobile, code }),
    }),

  me: (token: string) =>
    identityRequest<MeProfile>("/api/v1/auth/me", { token }),

  profile: (token: string) =>
    identityRequest<AccountProfile>("/api/v1/auth/me", { token }),

  updateProfile: (
    token: string,
    data: { display_name?: string | null; email?: string }
  ) =>
    identityRequest<AccountProfile>("/api/v1/auth/me", {
      method: "PATCH",
      token,
      body: JSON.stringify(data),
    }),

  changePassword: (
    token: string,
    data: { current_password?: string; new_password: string }
  ) =>
    identityRequest<{ message: string }>("/api/v1/auth/password", {
      method: "POST",
      token,
      body: JSON.stringify(data),
    }),

  listUsers: (token: string, options?: { offset?: number; limit?: number }) => {
    const params = new URLSearchParams({
      offset: String(options?.offset ?? 0),
      limit: String(options?.limit ?? 50),
    });
    return identityRequest<AdminUser[]>(`/api/v1/users?${params.toString()}`, { token });
  },

  getUser: (token: string, userId: string) =>
    identityRequest<AdminUser>(`/api/v1/users/${userId}`, { token }),

  createUser: (
    token: string,
    data: {
      email: string;
      username: string;
      password: string;
      mobile: string;
      display_name?: string;
    }
  ) =>
    identityRequest<AdminUser>("/api/v1/users", {
      method: "POST",
      token,
      body: JSON.stringify(data),
    }),

  listMembers: (token: string, tenantId: string) =>
    identityRequest<TenantMember[]>(`/api/v1/tenants/${tenantId}/members`, { token }),

  addMember: (
    token: string,
    tenantId: string,
    data: { user_id: string; role?: MembershipRole }
  ) =>
    identityRequest<TenantMember>(`/api/v1/tenants/${tenantId}/members`, {
      method: "POST",
      token,
      body: JSON.stringify(data),
    }),
};
