import { useQuery } from '@tanstack/react-query';
import {
  createPolicyDocument,
  deletePolicyDocument,
  listPolicyDocuments,
  updatePolicyDocument,
} from '@/shared/api/policyDocuments';
import {
  acknowledgePolicyDocument,
  getPolicyAcknowledgmentReport,
  listMyPolicyAcknowledgments,
} from '@/shared/api/policyAcknowledgments';
import {
  POLICY_DOCUMENT_PAGE_CATEGORY,
  POLICY_QUERY_KEYS,
} from '@/shared/constants/policies';
import { ESA_FUNDING_POLICY_TAG } from '@/shared/constants/esaFunding';
import { toPolicyDocumentMutationDto, toPolicyViewModel } from '@/business/policies/mappers';
import type { PolicyFormInput } from '@/business/policies/types';
import { getApiListRows, mapApiListRows } from '@/shared/business/apiListRows';
import { useInvalidatingMutation } from '@/shared/business/queryMutations';

interface PolicyUpdateInput {
  readonly id: string;
  readonly policy: PolicyFormInput;
}

export function usePolicies(enabled = true) {
  return useQuery({
    queryKey: POLICY_QUERY_KEYS.documents,
    enabled,
    queryFn: () =>
      mapApiListRows(
        listPolicyDocuments(POLICY_DOCUMENT_PAGE_CATEGORY.handbookPolicies),
        toPolicyViewModel,
      ).then((policies) =>
        policies.filter((policy) => policy.tag !== ESA_FUNDING_POLICY_TAG),
      ),
  });
}

export function useEsaFundingPolicyDocument(enabled = true) {
  return useQuery({
    queryKey: POLICY_QUERY_KEYS.esaDocuments,
    enabled,
    queryFn: async () => {
      const rows = await getApiListRows(
        listPolicyDocuments(POLICY_DOCUMENT_PAGE_CATEGORY.handbookPolicies, {
          tag: ESA_FUNDING_POLICY_TAG,
        }),
      );
      return rows[0] ? toPolicyViewModel(rows[0]) : null;
    },
  });
}

export function useCreatePolicy() {
  return useInvalidatingMutation({
    mutationFn: (input: PolicyFormInput) =>
      createPolicyDocument(toPolicyDocumentMutationDto(input)),
    invalidateQueryKey: POLICY_QUERY_KEYS.documents,
    invalidateQueryKeys: [POLICY_QUERY_KEYS.acknowledgmentReport],
  });
}

export function useUpdatePolicy() {
  return useInvalidatingMutation({
    mutationFn: (input: PolicyUpdateInput) =>
      updatePolicyDocument(input.id, toPolicyDocumentMutationDto(input.policy)),
    invalidateQueryKey: POLICY_QUERY_KEYS.documents,
    invalidateQueryKeys: [
      POLICY_QUERY_KEYS.acknowledgments,
      POLICY_QUERY_KEYS.acknowledgmentReport,
    ],
  });
}

export function useDeletePolicy() {
  return useInvalidatingMutation({
    mutationFn: (id: string) => deletePolicyDocument(id),
    invalidateQueryKey: POLICY_QUERY_KEYS.documents,
    invalidateQueryKeys: [POLICY_QUERY_KEYS.acknowledgmentReport],
  });
}

/** The current user's persisted policy acknowledgments (replaces local state). */
export function usePolicyAcknowledgments(enabled = true) {
  return useQuery({
    queryKey: POLICY_QUERY_KEYS.acknowledgments,
    enabled,
    queryFn: () => getApiListRows(listMyPolicyAcknowledgments()),
  });
}

export function useAcknowledgePolicy() {
  return useInvalidatingMutation({
    mutationFn: (policyDocumentId: string) =>
      acknowledgePolicyDocument({ policyDocumentId }),
    invalidateQueryKey: POLICY_QUERY_KEYS.acknowledgments,
    invalidateQueryKeys: [POLICY_QUERY_KEYS.acknowledgmentReport],
  });
}

export function usePolicyAcknowledgmentReport() {
  return useQuery({
    queryKey: POLICY_QUERY_KEYS.acknowledgmentReport,
    queryFn: getPolicyAcknowledgmentReport,
  });
}
