import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { toast } from 'sonner';
import { api, ApiError, type ApiResponse } from '../lib/api';
import type { CreditLedger, PackageDefinition, PatientPackage } from '../types';

/**
 * پکیج و اعتبار جلسات.
 *
 * مانده هیچ‌جا کش نمی‌شود و بعد از هر تغییر دفتر، کوئری باطل می‌شود: عددی که کاربر
 * می‌بیند باید همان جمع دفتر باشد، نه چیزی که فرانت حساب کرده.
 */
const PACKAGES_KEY = ['packages'];

function fail(e: unknown, fallback: string) {
  toast.error(e instanceof ApiError ? e.message : fallback);
}

export function usePackages() {
  const qc = useQueryClient();

  const query = useQuery({
    queryKey: PACKAGES_KEY,
    queryFn: () => api.get<ApiResponse<PackageDefinition[]>>('/api/v1/packages'),
  });

  const invalidate = () => qc.invalidateQueries({ queryKey: PACKAGES_KEY });

  const create = useMutation({
    mutationFn: (body: Record<string, unknown>) =>
      api.post<ApiResponse<PackageDefinition>>('/api/v1/packages', body),
    onSuccess: () => {
      toast.success('پکیج ساخته شد');
      invalidate();
    },
    onError: (e) => fail(e, 'ساخت پکیج ناموفق بود'),
  });

  const update = useMutation({
    mutationFn: ({ uuid, body }: { uuid: string; body: Record<string, unknown> }) =>
      api.patch<ApiResponse<PackageDefinition>>(`/api/v1/package/${uuid}`, body),
    onSuccess: () => {
      toast.success('پکیج به‌روزرسانی شد');
      invalidate();
    },
    onError: (e) => fail(e, 'به‌روزرسانی پکیج ناموفق بود'),
  });

  /** حذف = غیرفعال کردن؛ پکیج فروخته‌شده حذف‌شدنی نیست. */
  const deactivate = useMutation({
    mutationFn: (uuid: string) => api.delete<ApiResponse<PackageDefinition>>(`/api/v1/package/${uuid}`),
    onSuccess: () => {
      toast.success('پکیج غیرفعال شد');
      invalidate();
    },
    onError: (e) => fail(e, 'غیرفعال‌سازی ناموفق بود'),
  });

  return { packages: query.data?.data ?? [], loading: query.isLoading, create, update, deactivate };
}

export function usePatientPackages(patientUuid: string | undefined) {
  const qc = useQueryClient();
  const key = ['patient-packages', patientUuid];

  const query = useQuery({
    queryKey: key,
    queryFn: () => api.get<ApiResponse<PatientPackage[]>>(`/api/v1/patient/${patientUuid}/packages`),
    enabled: !!patientUuid,
  });

  const sell = useMutation({
    mutationFn: (body: { package_uuid: string; price_paid_rials?: number }) =>
      api.post<ApiResponse<PatientPackage>>(`/api/v1/patient/${patientUuid}/package`, body),
    onSuccess: () => {
      toast.success('پکیج برای بیمار ثبت شد');
      qc.invalidateQueries({ queryKey: key });
    },
    onError: (e) => fail(e, 'ثبت پکیج ناموفق بود'),
  });

  return { patientPackages: query.data?.data ?? [], loading: query.isLoading, sell };
}

export function useCreditLedger(patientPackageUuid: string | undefined) {
  const qc = useQueryClient();
  const key = ['credit-ledger', patientPackageUuid];

  const query = useQuery({
    queryKey: key,
    queryFn: () => api.get<ApiResponse<CreditLedger>>(`/api/v1/patient-package/${patientPackageUuid}/ledger`),
    enabled: !!patientPackageUuid,
  });

  const invalidate = () => {
    qc.invalidateQueries({ queryKey: key });
    qc.invalidateQueries({ queryKey: ['patient-packages'] });
  };

  const adjust = useMutation({
    mutationFn: (body: { delta: number; reason: string }) =>
      api.post<ApiResponse<PatientPackage>>(`/api/v1/patient-package/${patientPackageUuid}/adjust`, body),
    onSuccess: () => {
      toast.success('اصلاح اعتبار ثبت شد');
      invalidate();
    },
    onError: (e) => fail(e, 'اصلاح اعتبار ناموفق بود'),
  });

  const expire = useMutation({
    mutationFn: (reason: string) =>
      api.post<ApiResponse<PatientPackage>>(`/api/v1/patient-package/${patientPackageUuid}/expire`, { reason }),
    onSuccess: () => {
      toast.success('پکیج ابطال شد');
      invalidate();
    },
    onError: (e) => fail(e, 'ابطال پکیج ناموفق بود'),
  });

  return { ledger: query.data?.data, loading: query.isLoading, adjust, expire };
}
