import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { toast } from 'sonner';
import { api, ApiError, type ApiResponse } from '../lib/api';
import type {
  Policy,
  PolicyCategory,
  PolicySchema,
  PolicySimulationRun,
  PolicyTemplate,
} from '../types';

/**
 * قوانین کلینیک.
 *
 * دو نکتهٔ قراردادی که فرم به آن‌ها وابسته است:
 * ۱. schema و الگوها از سرور می‌آیند، نه از فهرستی در فرانت — یک حقیقت، نه دو تا.
 * ۲. فعال‌سازی بدون آزمایشِ همان نسخه ۴۲۲ می‌گیرد؛ UI باید کاربر را اول به آزمایش ببرد.
 */
const POLICIES_KEY = ['policies'];

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

/** schema تقریباً هرگز عوض نمی‌شود؛ نگه‌داشتن طولانی‌اش هزینه‌ای ندارد. */
export function usePolicySchema() {
  const query = useQuery({
    queryKey: ['policy-schema'],
    queryFn: () => api.get<ApiResponse<PolicySchema>>('/api/v1/policy-schema'),
    staleTime: 300_000,
  });

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

export function usePolicyTemplates() {
  const query = useQuery({
    queryKey: ['policy-templates'],
    queryFn: () => api.get<ApiResponse<PolicyTemplate[]>>('/api/v1/policy-templates'),
    staleTime: 300_000,
  });

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

export function usePolicies(category?: PolicyCategory | '') {
  const qc = useQueryClient();
  const key = [...POLICIES_KEY, category ?? ''];

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

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

  const activate = useMutation({
    mutationFn: (uuid: string) => api.post<ApiResponse<Policy>>(`/api/v1/policy/${uuid}/activate`, {}),
    onSuccess: () => {
      toast.success('قانون فعال شد');
      invalidate();
    },
    onError: (e) => fail(e, 'فعال‌سازی ناموفق بود'),
  });

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

  return {
    policies: query.data?.data ?? [],
    loading: query.isLoading,
    activate,
    deactivate,
  };
}

export function usePolicy(uuid: string | undefined) {
  const query = useQuery({
    queryKey: ['policy', uuid],
    queryFn: () => api.get<ApiResponse<Policy>>(`/api/v1/policy/${uuid}`),
    enabled: !!uuid,
  });

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

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

  const create = useMutation({
    mutationFn: (body: Record<string, unknown>) =>
      api.post<ApiResponse<Policy>>('/api/v1/policy', body),
    onSuccess: () => {
      toast.success('قانون ساخته شد — حالا آزمایشش کنید');
      qc.invalidateQueries({ queryKey: POLICIES_KEY });
    },
    onError: (e) => fail(e, 'ساخت قانون ناموفق بود'),
  });

  const newVersion = useMutation({
    mutationFn: ({ uuid, body }: { uuid: string; body: Record<string, unknown> }) =>
      api.post<ApiResponse<Policy>>(`/api/v1/policy/${uuid}/version`, body),
    onSuccess: (_d, v) => {
      toast.success('نسخهٔ تازه ثبت شد');
      qc.invalidateQueries({ queryKey: POLICIES_KEY });
      qc.invalidateQueries({ queryKey: ['policy', v.uuid] });
    },
    onError: (e) => fail(e, 'ثبت نسخه ناموفق بود'),
  });

  return { create, newVersion };
}

export function usePolicySimulation(uuid: string | undefined) {
  const qc = useQueryClient();
  const key = ['policy-simulations', uuid];

  const history = useQuery({
    queryKey: key,
    queryFn: () => api.get<ApiResponse<PolicySimulationRun[]>>(`/api/v1/policy/${uuid}/simulations`),
    enabled: !!uuid,
  });

  const run = useMutation({
    mutationFn: (sampleSize?: number) =>
      api.post<ApiResponse<PolicySimulationRun>>(`/api/v1/policy/${uuid}/simulate`, {
        sample_size: sampleSize ?? 50,
      }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: key });
      qc.invalidateQueries({ queryKey: POLICIES_KEY });
    },
    onError: (e) => fail(e, 'اجرای آزمایشی ناموفق بود'),
  });

  return { runs: history.data?.data ?? [], loading: history.isLoading, run };
}
