import { useMemo } from 'react';
import { useQuery } from '@tanstack/react-query';
import { api } from '../lib/api';
import type { ApiResponse } from '../lib/api';
import { breakdownOf, type BillableLine, type ShareBreakdown, type TenantContract } from '../lib/insuranceShares';

interface ServiceCategoryRow {
  key: string;
  label: string;
  enabled: boolean;
}

interface PricingPayload {
  service_categories?: ServiceCategoryRow[];
  default_service_category?: string | null;
  /** «قیمت ویزیت آزاد» tenant — سرور وقتی نوبت قیمت ندارد همین را می‌گذارد. */
  free_visit_price_rials?: number;
}

/**
 * انتخاب بیمهٔ یک نوبت: نوع خدماتِ فعالِ همین پزشک/کلینیک و قراردادهای بیمهٔ پایهٔ فعال،
 * به‌همراه محاسبهٔ سهم — مشترک بین مودال «قطعی کردن نوبت» و صفحهٔ ویرایش نوبت تا
 * هر دو یک قاعده را نشان دهند.
 */
export function useAppointmentInsurance(enabled: boolean) {
  const pricingQuery = useQuery<ApiResponse<PricingPayload>>({
    queryKey: ['insurance-pricing'],
    queryFn: () => api.get('/api/v1/insurance-pricing'),
    enabled,
  });

  const contractsQuery = useQuery<ApiResponse<{ data: TenantContract[] }>>({
    queryKey: ['tenant-insurances'],
    queryFn: () => api.get('/api/v1/billing/tenant-insurances'),
    enabled,
  });

  const pricing = (pricingQuery.data?.data ?? {}) as PricingPayload;

  const enabledCategories = useMemo(
    () => (pricing.service_categories ?? []).filter((c) => c.enabled),
    [pricing.service_categories],
  );

  const contracts: TenantContract[] = useMemo(
    () => ((contractsQuery.data?.data as any)?.data ?? []) as TenantContract[],
    [contractsQuery.data],
  );

  const activeContracts = useMemo(() => contracts.filter((c) => c.is_active !== false), [contracts]);
  const basicContracts = useMemo(
    () => activeContracts.filter((c) => c.insurance_kind !== 'supplementary'),
    [activeContracts],
  );
  const supplementaryContracts = useMemo(
    () => activeContracts.filter((c) => c.insurance_kind === 'supplementary'),
    [activeContracts],
  );

  const optionsOf = (list: TenantContract[]) =>
    list.map((c) => ({ value: String(c.insurance_id), label: c.insurance_name ?? `#${c.insurance_id}` }));

  return {
    /**
     * هزینهٔ ویزیتِ مؤثر — آینهٔ همان fallback سرور: قیمت خودِ نوبت، در نبودش
     * «قیمت ویزیت آزاد» تنظیمات همین tenant.
     */
    visitPriceOf: (appointmentVisitPrice: number | null | undefined): number =>
      Number(appointmentVisitPrice ?? 0) > 0
        ? Number(appointmentVisitPrice)
        : Number(pricing.free_visit_price_rials ?? 0),

    /** فقط وقتی بیش از یک نوع فعال است، انتخاب از کاربر پرسیده می‌شود. */
    needsCategoryChoice: enabledCategories.length > 1,
    categoryOptions: enabledCategories.map((c) => ({ value: c.key, label: c.label })),
    /** تنها نوع فعال (یا null اگر چند نوع فعال باشد) — همان قاعدهٔ سرور. */
    defaultCategory: pricing.default_service_category ?? enabledCategories[0]?.key ?? null,
    categoryLabelOf: (key: string | null | undefined) =>
      (pricing.service_categories ?? []).find((c) => c.key === key)?.label ?? null,

    insuranceOptions: optionsOf(basicContracts),
    /** قراردادهای تکمیلیِ فعال — روی باقیماندهٔ بعد از بیمهٔ پایه اعمال می‌شوند. */
    supplementaryOptions: optionsOf(supplementaryContracts),
    hasSupplementary: supplementaryContracts.length > 0,
    contractOf: (insuranceId: string | number | null | undefined): TenantContract | null =>
      basicContracts.find((c) => String(c.insurance_id) === String(insuranceId)) ?? null,
    insuranceNameOf: (insuranceId: string | number | null | undefined): string | null =>
      contracts.find((c) => String(c.insurance_id) === String(insuranceId))?.insurance_name ?? null,

    /** تفکیک زنجیره‌ای سهم‌ها: پایه روی کل، تکمیلی روی باقیمانده. */
    breakdown: (
      lines: BillableLine[],
      insuranceId: string | number | null | undefined,
      supplementaryId: string | number | null | undefined = null,
    ): ShareBreakdown =>
      breakdownOf(
        lines,
        basicContracts.find((c) => String(c.insurance_id) === String(insuranceId)) ?? null,
        supplementaryContracts.find((c) => String(c.insurance_id) === String(supplementaryId)) ?? null,
      ),

    isLoading: pricingQuery.isLoading || contractsQuery.isLoading,
  };
}
