import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { toast } from 'sonner';
import { api, ApiError, type ApiResponse } from '../lib/api';
import type { CancellationPolicy, CancellationPreview, CancellationResult, WaitlistEntry } from '../types';

/**
 * سیاست لغو و لیست انتظار.
 *
 * پیش‌نمایش لغو همیشه از سرور می‌آید — همان محاسبه‌ای که خودِ لغو انجام می‌دهد، تا عددی
 * که کاربر می‌بیند با آنچه کسر می‌شود یکی باشد.
 */
const POLICY_KEY = ['cancellation-policy'];
const WAITLIST_KEY = ['waitlist'];

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

interface PolicyResponse {
  default: CancellationPolicy | null;
  overrides: CancellationPolicy[];
}

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

  const query = useQuery({
    queryKey: POLICY_KEY,
    queryFn: () => api.get<ApiResponse<PolicyResponse>>('/api/v1/cancellation-policy'),
  });

  const save = useMutation({
    mutationFn: (body: Record<string, unknown>) =>
      api.put<ApiResponse<CancellationPolicy>>('/api/v1/cancellation-policy', body),
    onSuccess: () => {
      toast.success('سیاست لغو ذخیره شد');
      qc.invalidateQueries({ queryKey: POLICY_KEY });
    },
    onError: (e) => fail(e, 'ذخیرهٔ سیاست ناموفق بود'),
  });

  return {
    policy: query.data?.data?.default ?? null,
    overrides: query.data?.data?.overrides ?? [],
    loading: query.isLoading,
    save,
  };
}

export function useCancellationPreview(appointmentUuid: string | undefined, by: 'user' | 'doctor') {
  const query = useQuery({
    queryKey: ['cancellation-preview', appointmentUuid, by],
    queryFn: () =>
      api.get<ApiResponse<CancellationPreview>>(
        `/api/v1/appointment/${appointmentUuid}/cancellation-preview?by=${by}`,
      ),
    enabled: !!appointmentUuid,
  });

  return { preview: query.data?.data, loading: query.isLoading };
}

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

  return useMutation({
    mutationFn: ({ uuid, by, reason }: { uuid: string; by: 'user' | 'doctor'; reason?: string }) =>
      api.post<ApiResponse<CancellationResult>>(`/api/v1/appointment/${uuid}/cancel`, {
        by,
        ...(reason?.trim() ? { reason: reason.trim() } : {}),
      }),
    onSuccess: (res) => {
      const notified = res.data.waitlist_notified;
      toast.success(
        notified > 0 ? `نوبت لغو شد و ${notified} نفر از لیست انتظار خبر شدند` : 'نوبت لغو شد',
      );
      qc.invalidateQueries({ queryKey: ['appointments'] });
      qc.invalidateQueries({ queryKey: WAITLIST_KEY });
    },
    onError: (e) => fail(e, 'لغو نوبت ناموفق بود'),
  });
}

/**
 * درخواست‌هایی که با یک زمان مشخص می‌خوانند — ابزار لحظهٔ آزاد شدن ظرفیت.
 *
 * جدا از فهرست است چون سؤال متفاوتی می‌پرسد: نه «چه کسی منتظر است» بلکه «چه کسی
 * برای **این** وقت منتظر است».
 */
export function useWaitlistMatches(params: { serviceUuid: string; start: number; branchUuid?: string }) {
  const query = useQuery({
    queryKey: ['waitlist-matches', params],
    queryFn: () =>
      api.get<ApiResponse<WaitlistEntry[]>>(
        `/api/v1/waitlist/matches?service_uuid=${params.serviceUuid}&start=${params.start}` +
          (params.branchUuid ? `&branch_uuid=${params.branchUuid}` : ''),
      ),
    enabled: !!params.serviceUuid && params.start > 0,
  });

  return { matches: Array.isArray(query.data?.data) ? query.data.data : [], loading: query.isFetching };
}

export function useWaitlist(status?: string) {
  const qc = useQueryClient();
  const key = [...WAITLIST_KEY, status ?? ''];

  const query = useQuery({
    queryKey: key,
    queryFn: () =>
      api.get<ApiResponse<WaitlistEntry[]>>(`/api/v1/waitlist${status ? `?status=${status}` : ''}`),
  });

  const remove = useMutation({
    mutationFn: (uuid: string) => api.delete<ApiResponse<null>>(`/api/v1/waitlist/${uuid}`),
    onSuccess: () => {
      toast.success('از لیست انتظار حذف شد');
      qc.invalidateQueries({ queryKey: WAITLIST_KEY });
    },
    onError: (e) => fail(e, 'حذف ناموفق بود'),
  });

  return { entries: query.data?.data ?? [], loading: query.isLoading, remove };
}

/** خلاصهٔ عدم حضور یک بیمار — نشان است نه مانع؛ مسدودسازی کارِ قانون `eligibility` است. */
export function usePatientNoShows(patientUuid: string | undefined) {
  const query = useQuery({
    queryKey: ['patient-no-shows', patientUuid],
    queryFn: () =>
      api.get<ApiResponse<{ count: number; threshold: number; window_days: number; at_risk: boolean }>>(
        `/api/v1/patient/${patientUuid}/no-shows`,
      ),
    enabled: !!patientUuid,
  });

  return { noShows: query.data?.data ?? null };
}
