import type { DocumentType, ProviderStatus } from "@/types/provider";

export enum UserRole {
  ADMIN_SUPER = "ADMIN_SUPER",
  ADMIN_SUPPORT = "ADMIN_SUPPORT",
  PROVIDER_OWNER = "PROVIDER_OWNER",
  PROVIDER_MANAGER = "PROVIDER_MANAGER",
  PROVIDER_TECHNICIAN = "PROVIDER_TECHNICIAN",
  CUSTOMER = "CUSTOMER",
}

export enum AuthType {
  PASSWORD = "password",
  OTP = "otp",
}

export interface AuthUser {
  id: string;
  email: string | null;
  phoneNumber: string | null;
  firstName: string;
  lastName: string;
  role: UserRole;
  providerId: string | null;
  isActive: boolean;
  createdAt: string;
  updatedAt: string;
  /**
   * Which panel the user belongs to — returned by the backend, derived from
   * `role`. Optional because some responses (e.g. the register echo) may omit
   * it; the RBAC layer falls back to deriving it from `role`.
   */
  panelAccess?: "ADMIN" | "PROVIDER" | null;
  /**
   * The user's effective permission keys. NOT yet returned by the backend —
   * `usePermissions` falls back to deriving these from `role` (see
   * `lib/constants/permissions.ts`). Once `GET /auth/profile` includes it, the
   * RBAC layer consumes it automatically with no other changes. Typed as
   * `string[]` (the wire shape); it's narrowed to `Permission` at the check site.
   */
  permissions?: string[];
}

// ─── Login ────────────────────────────────────────────────────────────────────

export interface LoginRequest {
  identifier: string;
  authType: AuthType;
  password?: string;
  otpCode?: string;
}

export interface LoginResponse {
  user: AuthUser;
  accessToken: string;
}

// ─── OTP Send ────────────────────────────────────────────────────────────────

export interface SendOtpRequest {
  phoneNumber?: string;
  email?: string;
}

export interface SendOtpResponse {
  success: boolean;
  message: string;
}

// ─── Forgot Password ─────────────────────────────────────────────────────────

export interface ForgotPasswordRequest {
  identifier: string;
}

export interface ForgotPasswordResponse {
  success: boolean;
  message: string;
}

// ─── Reset Password ───────────────────────────────────────────────────────────

export interface ResetPasswordRequest {
  identifier: string;
  otpCode: string;
  newPassword: string;
}

export interface ResetPasswordResponse {
  success: boolean;
  message: string;
}

// ─── OTP Verify ─────────────────────────────────────────────────────────────

export interface VerifyOtpRequest {
  phoneNumber: string;
  code: string;
}

/**
 * `/auth/otp/verify` is dual-purpose:
 *  - unknown phone → `{ isRegistered: false, phoneNumber }`, and the backend sets
 *    a Redis "verified" flag that provider registration later requires.
 *  - existing phone → `{ isRegistered: true, user, accessToken }` (logs them in).
 *
 * During provider registration, `isRegistered: true` means the number is already
 * taken — block and send the user to sign in instead.
 */
export interface VerifyOtpResponse {
  isRegistered: boolean;
  phoneNumber?: string;
  user?: AuthUser;
  accessToken?: string;
}

// ─── Provider Registration ────────────────────────────────────────────────────

export interface RegisterDocumentPayload {
  documentType: DocumentType;
  /** tmp/ key returned by the presign step; committed server-side on register */
  s3Key: string;
}

/**
 * Body for `POST /auth/provider/register`. Mirrors backend `RegisterProviderDto`.
 * The phone must already be OTP-verified. `logoS3Key` / `documents[]` reference
 * files already uploaded to temporary storage — the backend commits them.
 */
export interface RegisterProviderRequest {
  businessName: string;
  phoneNumber: string;
  email: string;
  password: string;
  firstName: string;
  lastName: string;
  stationAddress: string;
  stationCity: string;
  stationState?: string;
  stationZipCode?: string;
  stationLatitude: number;
  stationLongitude: number;
  serviceRadiusKm?: number;
  logoS3Key?: string;
  documents?: RegisterDocumentPayload[];
}

/** The owner account echoed back by register — note: no `updatedAt` field */
export interface RegisteredOwner {
  id: string;
  firstName: string;
  lastName: string;
  email: string | null;
  phoneNumber: string | null;
  role: UserRole;
  providerId: string | null;
  isActive: boolean;
  createdAt: string;
  panelAccess: string;
}

export interface RegisteredProvider {
  id: string;
  businessName: string;
  logoUrl: string | null;
  status: ProviderStatus;
  stationAddress: string;
  stationCity: string;
  stationState: string | null;
  stationZipCode: string | null;
  stationLatitude: number;
  stationLongitude: number;
  serviceRadiusKm: number;
  createdAt: string;
}

export interface RegisterProviderResponse {
  registered: boolean;
  user: RegisteredOwner;
  provider: RegisteredProvider;
  accessToken: string;
}
