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

/**
 * پروتکل دوره و دورهٔ بیمار.
 *
 * `progress` هرگز در فرانت حساب نمی‌شود — سرور می‌دهدش، چون همان‌جاست که وضعیت جلسات
 * منبع حقیقت است.
 */
const PROTOCOLS_KEY = ['course-protocols'];

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

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

  const query = useQuery({
    queryKey: PROTOCOLS_KEY,
    queryFn: () => api.get<ApiResponse<CourseProtocol[]>>('/api/v1/course-protocols'),
  });

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

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

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

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

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

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

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

  const start = useMutation({
    mutationFn: (body: { protocol_uuid: string; patient_package_uuid?: string }) =>
      api.post<ApiResponse<TreatmentCourse>>('/api/v1/treatment-course', {
        patient_uuid: patientUuid,
        ...body,
      }),
    onSuccess: () => {
      toast.success('دوره شروع شد');
      qc.invalidateQueries({ queryKey: key });
    },
    onError: (e) => fail(e, 'شروع دوره ناموفق بود'),
  });

  return { courses: query.data?.data ?? [], loading: query.isLoading, start };
}

export function useTreatmentCourse(courseUuid: string | undefined) {
  const qc = useQueryClient();
  const key = ['treatment-course', courseUuid];

  const query = useQuery({
    queryKey: key,
    queryFn: () => api.get<ApiResponse<TreatmentCourse>>(`/api/v1/treatment-course/${courseUuid}`),
    enabled: !!courseUuid,
  });

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

  const abandon = useMutation({
    mutationFn: (reason: string) =>
      api.post<ApiResponse<TreatmentCourse>>(`/api/v1/treatment-course/${courseUuid}/abandon`, { reason }),
    onSuccess: () => {
      toast.success('دوره رها شد');
      invalidate();
    },
    onError: (e) => fail(e, 'رهاکردن دوره ناموفق بود'),
  });

  const bookAll = useMutation({
    mutationFn: (body: { branch_uuid: string; doctor_uuid: string }) =>
      api.post<ApiResponse<{ booked: number; remaining: number; message: string | null }>>(
        `/api/v1/treatment-course/${courseUuid}/book-all`,
        body,
      ),
    onSuccess: (res) => {
      toast.success(res.data.message ?? `${res.data.booked} جلسه رزرو شد`);
      invalidate();
    },
    onError: (e) => fail(e, 'رزرو جلسات ناموفق بود'),
  });

  return { course: query.data?.data, loading: query.isLoading, abandon, bookAll };
}

export function useNextSlotSuggestion(courseUuid: string | undefined, branchUuid: string | undefined) {
  const query = useQuery({
    queryKey: ['course-next-slot', courseUuid, branchUuid],
    queryFn: () =>
      api.get<ApiResponse<NextSlotSuggestion>>(
        `/api/v1/treatment-course/${courseUuid}/next-slot-suggestion?branch_uuid=${branchUuid}`,
      ),
    enabled: !!courseUuid && !!branchUuid,
  });

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