import type { PageParams, Paginated } from '@/lib/api/types';

/**
 * Partner-center domain — the licensed sponsoring centers (پروانه تأسیس + مسئول فنی + نماد اعتماد
 * الکترونیکی) that may be the **merchant-of-record / invoice issuer**, and the two audiences that read
 * them: Balinyaar **admins** (list/create/verify/activate/sponsor) and a **center admin** in the separate
 * partner-portal scope (their own center only). Shapes derive from the b15 contract
 * (`dev/contracts/domains/messaging-notifications-admin.md`) and the b11 invoice shape.
 *
 * Load-bearing rules (phase §5):
 *  - **`settlementIban` is never returned in plaintext** — only a masked last-4 (`"••••0001"`). On create
 *    it is **write-then-masked** (submit the full IBAN, only last-4 shows afterwards).
 *  - **Merchant-of-record drives the settlement view** — the invoice/settlement surface renders only when
 *    `isMerchantOfRecord === true`.
 *  - **VAT is on the commission line only**, config-driven — never hardcode 10%.
 *  - **Tenancy** — a center admin sees only their own center (server-enforced); never fetch a raw id they
 *    don't own.
 */

/** A center's onboarding/verification lifecycle (derived from `isActive`/`verifiedAt`; the mock sets it). */
export type CenterOnboardingState = 'draft' | 'pending_verification' | 'verified' | 'suspended';

/** `PartnerCenter` detail (admin + portal). `settlementIbanMasked` is last-4 only, never the full IBAN. */
export interface PartnerCenter {
  id: number;
  name: string;
  legalEntityType: string;
  mohEstablishmentPermitNo: string;
  technicalDirectorNurseUserId: number | null;
  technicalDirectorLicenseNo: string | null;
  enamadCode: string | null;
  settlementIbanMasked: string | null;
  isMerchantOfRecord: boolean;
  commissionRate: number;
  adminUserId: number | null;
  isActive: boolean;
  verifiedAt: string | null;
  sponsoredNurseCount: number;
  onboardingState: CenterOnboardingState;
  createdAt: string;
}

/**
 * Create/update body. `settlementIban` is the **full** IBAN, write-only — the server stores it masked and
 * only ever returns the last-4. Required when `isMerchantOfRecord`. `commissionRate ∈ [0, 1)`.
 */
export interface PartnerCenterInput {
  name: string;
  legalEntityType: string;
  mohEstablishmentPermitNo: string;
  technicalDirectorNurseUserId?: number | null;
  technicalDirectorLicenseNo?: string | null;
  enamadCode?: string | null;
  settlementIban?: string | null;
  isMerchantOfRecord: boolean;
  commissionRate: number;
  adminUserId?: number | null;
}

/** A nurse sponsored by a center (roster + portal list). */
export interface SponsoredNurse {
  nurseProfileId: number;
  name: string;
  isVerified: boolean;
}

/** A booking the center legally covers (portal list; read-only summary, no extra PII). */
export interface SponsoredBooking {
  bookingId: number;
  patientName: string;
  scheduledDate: string;
  status: string;
}

/** `invoices.moadian_status`. */
export type MoadianStatus = 'pending' | 'submitted' | 'registered' | 'failed';

/**
 * A per-booking commission invoice (only meaningful when the center is merchant-of-record). The
 * reconciling breakdown is **platform commission + BNPL commission + VAT = total**; `grossIrr` is shown
 * as context, not part of the total (VAT is on the commission line, never the gross service fee). Money is
 * IRR digit-strings.
 */
export interface CenterInvoice {
  id: number;
  bookingId: number;
  invoiceNumber: string;
  grossIrr: string;
  platformCommissionIrr: string;
  bnplCommissionIrr: string | null;
  vatRate: number;
  vatIrr: string;
  /** commission + bnpl commission + vat (REQ-033 — the wire lacks a total; summed from served legs). */
  totalIrr: string;
  moadianReferenceNumber: string | null;
  moadianStatus: MoadianStatus | null;
  pdfUrl: string | null;
  issuedAt: string;
}

/** Admin list filters. */
export interface PartnerCenterFilters {
  isMerchantOfRecord?: boolean;
  isActive?: boolean;
}

/** Bookings list filter (portal). */
export interface SponsoredBookingFilters {
  status?: string;
}

/**
 * The partner-center API seam — admin-side management + the center-scoped portal reads. The real client
 * and the in-memory mock both implement it (selection by `USE_PARTNER_MOCK`).
 */
export interface PartnerCenterApi {
  // admin-side
  listCenters(filters: PartnerCenterFilters, params: PageParams): Promise<Paginated<PartnerCenter>>;
  getCenter(id: number): Promise<PartnerCenter>;
  createCenter(input: PartnerCenterInput): Promise<PartnerCenter>;
  updateCenter(id: number, input: PartnerCenterInput): Promise<PartnerCenter>;
  verifyCenter(id: number): Promise<void>;
  setCenterActive(id: number, isActive: boolean): Promise<void>;
  assignNurse(id: number, nurseProfileId: number, unlink: boolean): Promise<void>;
  getCenterSponsoredNurses(id: number): Promise<SponsoredNurse[]>;
  // portal (center-scoped)
  getMyCenter(): Promise<PartnerCenter>;
  listMySponsoredNurses(): Promise<SponsoredNurse[]>;
  listMySponsoredBookings(filters: SponsoredBookingFilters, params: PageParams): Promise<Paginated<SponsoredBooking>>;
  listMySettlement(params: PageParams): Promise<Paginated<CenterInvoice>>;
}

/** Derive the onboarding state from a center's `isActive`/`verifiedAt` (the real-path fallback). */
export function deriveCenterState(isActive: boolean, verifiedAt: string | null): CenterOnboardingState {
  if (verifiedAt && isActive) return 'verified';
  if (verifiedAt && !isActive) return 'suspended';
  return 'pending_verification';
}
