import { clientFetch } from '@/lib/api/client';
import { unwrap, type ApiEnvelope, type PageParams, type Paginated } from '@/lib/api/types';
import { PARTNER_PAGE_SIZE } from '../constants';
import type {
  CenterInvoice,
  PartnerCenter,
  PartnerCenterApi,
  PartnerCenterFilters,
  PartnerCenterInput,
  SponsoredBooking,
  SponsoredBookingFilters,
  SponsoredNurse,
} from '../types';
import { deriveCenterState } from '../types';

const API = '/api/v1';

/** Wire `PartnerCenterDto` (b15) — `onboardingState` is derived client-side from `isActive`/`verifiedAt`. */
interface CenterWire {
  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;
  createdAt: string;
}

function mapCenter(w: CenterWire): PartnerCenter {
  return { ...w, onboardingState: deriveCenterState(w.isActive, w.verifiedAt) };
}

/**
 * Real HTTP implementation of the `PartnerCenterApi` seam. **Not primary this phase** (`USE_PARTNER_MOCK =
 * true`). Admin CRUD/verify/sponsor map the live b15 routes; the activate/suspend toggle and the portal's
 * split reads (my-center / nurses / bookings / settlement) are proposed routes (REQ-032/033) kept
 * real-shaped so the seam flips in one file once they land.
 */
export const partnerCenterClientApi: PartnerCenterApi = {
  listCenters: async (filters: PartnerCenterFilters, params) => {
    const q = new URLSearchParams();
    q.set('page', String(params.page ?? 1));
    q.set('pageSize', String(params.pageSize ?? PARTNER_PAGE_SIZE));
    if (filters.isMerchantOfRecord != null) q.set('isMerchantOfRecord', String(filters.isMerchantOfRecord));
    if (filters.isActive != null) q.set('isActive', String(filters.isActive));
    const wire = unwrap(await clientFetch<ApiEnvelope<Paginated<CenterWire>>>(`${API}/admin/partner-centers?${q}`));
    return { ...wire, items: wire.items.map(mapCenter) };
  },

  getCenter: async (id) => mapCenter(unwrap(await clientFetch<ApiEnvelope<CenterWire>>(`${API}/admin/partner-centers/${id}`))),

  createCenter: async (input: PartnerCenterInput) =>
    mapCenter(
      unwrap(
        await clientFetch<ApiEnvelope<CenterWire>>(`${API}/admin/partner-centers`, {
          method: 'POST',
          body: JSON.stringify(input),
        }),
      ),
    ),

  updateCenter: async (id, input: PartnerCenterInput) =>
    mapCenter(
      unwrap(
        await clientFetch<ApiEnvelope<CenterWire>>(`${API}/admin/partner-centers/${id}`, {
          method: 'PATCH',
          body: JSON.stringify(input),
        }),
      ),
    ),

  verifyCenter: async (id) => {
    await clientFetch<ApiEnvelope<boolean>>(`${API}/admin/partner-centers/${id}/verify`, { method: 'POST' });
  },

  // REQ-032 — no activate/suspend route in the b15 contract yet; proposed shape.
  setCenterActive: async (id, isActive) => {
    await clientFetch<ApiEnvelope<boolean>>(`${API}/admin/partner-centers/${id}/set-active`, {
      method: 'POST',
      body: JSON.stringify({ isActive }),
    });
  },

  assignNurse: async (id, nurseProfileId, unlink) => {
    await clientFetch<ApiEnvelope<boolean>>(`${API}/admin/partner-centers/${id}/sponsor-nurse`, {
      method: 'POST',
      body: JSON.stringify({ nurseProfileId, unlink }),
    });
  },

  // REQ-032 — admin roster read (the b15 dashboard is portal-auth); proposed shape.
  getCenterSponsoredNurses: async (id) =>
    unwrap(await clientFetch<ApiEnvelope<SponsoredNurse[]>>(`${API}/admin/partner-centers/${id}/nurses`)),

  // ── portal (center-scoped; REQ-032/033 — proposed split reads over `GET /centers/{id}/dashboard`) ──
  getMyCenter: async () => mapCenter(unwrap(await clientFetch<ApiEnvelope<CenterWire>>(`${API}/centers/me`))),
  listMySponsoredNurses: async () =>
    unwrap(await clientFetch<ApiEnvelope<SponsoredNurse[]>>(`${API}/centers/me/nurses`)),
  listMySponsoredBookings: async (filters: SponsoredBookingFilters, params) => {
    const q = new URLSearchParams();
    q.set('page', String(params.page ?? 1));
    q.set('pageSize', String(params.pageSize ?? PARTNER_PAGE_SIZE));
    if (filters.status) q.set('status', filters.status);
    return unwrap(await clientFetch<ApiEnvelope<Paginated<SponsoredBooking>>>(`${API}/centers/me/bookings?${q}`));
  },
  listMySettlement: async (params) => {
    const q = new URLSearchParams();
    q.set('page', String(params.page ?? 1));
    q.set('pageSize', String(params.pageSize ?? PARTNER_PAGE_SIZE));
    return unwrap(await clientFetch<ApiEnvelope<Paginated<CenterInvoice>>>(`${API}/centers/me/settlement?${q}`));
  },
};
