/**
 * Contract Management Hooks
 */

import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import apiClient from '../api/client';
import {
  ContractTemplate,
  Contract,
  ContractPublicView,
  ContractScope,
  ContractTemplateStatus,
} from '../types';

// --- Contract Templates ---

/**
 * Hook to fetch all contract templates for current business
 */
export const useContractTemplates = (status?: ContractTemplateStatus) => {
  return useQuery<ContractTemplate[]>({
    queryKey: ['contract-templates', status],
    queryFn: async () => {
      const params = status ? { status } : {};
      const { data } = await apiClient.get('/contracts/templates/', { params });

      return data.map((t: any) => ({
        id: String(t.id),
        name: t.name,
        description: t.description || '',
        content: t.content,
        scope: t.scope as ContractScope,
        status: t.status as ContractTemplateStatus,
        expires_after_days: t.expires_after_days,
        version: t.version,
        version_notes: t.version_notes || '',
        services: t.services || [],
        created_by: t.created_by ? String(t.created_by) : null,
        created_by_name: t.created_by_name || null,
        created_at: t.created_at,
        updated_at: t.updated_at,
      }));
    },
    retry: false,
  });
};

/**
 * Hook to get a single contract template
 */
export const useContractTemplate = (id: string) => {
  return useQuery<ContractTemplate>({
    queryKey: ['contract-templates', id],
    queryFn: async () => {
      const { data } = await apiClient.get(`/contracts/templates/${id}/`);

      return {
        id: String(data.id),
        name: data.name,
        description: data.description || '',
        content: data.content,
        scope: data.scope as ContractScope,
        status: data.status as ContractTemplateStatus,
        expires_after_days: data.expires_after_days,
        version: data.version,
        version_notes: data.version_notes || '',
        services: data.services || [],
        created_by: data.created_by ? String(data.created_by) : null,
        created_by_name: data.created_by_name || null,
        created_at: data.created_at,
        updated_at: data.updated_at,
      };
    },
    enabled: !!id,
    retry: false,
  });
};

interface ContractTemplateInput {
  name: string;
  description?: string;
  content: string;
  scope: ContractScope;
  status?: ContractTemplateStatus;
  expires_after_days?: number | null;
  version_notes?: string;
  services?: string[];
}

/**
 * Hook to create a contract template
 */
export const useCreateContractTemplate = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (templateData: ContractTemplateInput) => {
      const { data } = await apiClient.post('/contracts/templates/', templateData);
      return data;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['contract-templates'] });
    },
  });
};

/**
 * Hook to update a contract template
 */
export const useUpdateContractTemplate = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async ({
      id,
      updates,
    }: {
      id: string;
      updates: Partial<ContractTemplateInput>;
    }) => {
      const { data } = await apiClient.patch(`/contracts/templates/${id}/`, updates);
      return data;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['contract-templates'] });
    },
  });
};

/**
 * Hook to delete a contract template
 */
export const useDeleteContractTemplate = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (id: string) => {
      await apiClient.delete(`/contracts/templates/${id}/`);
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['contract-templates'] });
    },
  });
};

/**
 * Hook to duplicate a contract template
 */
export const useDuplicateContractTemplate = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (id: string) => {
      const { data } = await apiClient.post(`/contracts/templates/${id}/duplicate/`);
      return data;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['contract-templates'] });
    },
  });
};

/**
 * Hook to preview a contract template
 */
export const usePreviewContractTemplate = () => {
  return useMutation({
    mutationFn: async ({
      id,
      context,
    }: {
      id: string;
      context?: Record<string, any>;
    }) => {
      const { data } = await apiClient.post(
        `/contracts/templates/${id}/preview/`,
        context || {}
      );
      return data;
    },
  });
};

// --- Contracts ---

/**
 * Hook to fetch all contracts for current business
 */
export const useContracts = (filters?: {
  status?: string;
  customer?: string;
  appointment?: string;
}) => {
  return useQuery<Contract[]>({
    queryKey: ['contracts', filters],
    queryFn: async () => {
      const { data } = await apiClient.get('/contracts/', {
        params: filters,
      });

      return data.map((c: any) => ({
        id: String(c.id),
        template: String(c.template),
        template_name: c.template_name,
        template_version: c.template_version,
        scope: c.scope as ContractScope,
        status: c.status,
        content: c.content_html || c.content, // Backend returns content_html
        customer: c.customer ? String(c.customer) : undefined,
        customer_name: c.customer_name || undefined,
        customer_email: c.customer_email || undefined,
        appointment: c.appointment ? String(c.appointment) : undefined,
        appointment_service_name: c.appointment_service_name || undefined,
        appointment_start_time: c.appointment_start_time || undefined,
        service: c.service ? String(c.service) : undefined,
        service_name: c.service_name || undefined,
        sent_at: c.sent_at,
        signed_at: c.signed_at,
        expires_at: c.expires_at,
        voided_at: c.voided_at,
        voided_reason: c.voided_reason,
        public_token: c.signing_token || c.public_token, // Backend returns signing_token
        created_at: c.created_at,
        updated_at: c.updated_at,
      }));
    },
    retry: false,
  });
};

/**
 * Hook to get a single contract
 */
export const useContract = (id: string) => {
  return useQuery<Contract>({
    queryKey: ['contracts', id],
    queryFn: async () => {
      const { data } = await apiClient.get(`/contracts/${id}/`);

      return {
        id: String(data.id),
        template: String(data.template),
        template_name: data.template_name,
        template_version: data.template_version,
        scope: data.scope as ContractScope,
        status: data.status,
        content: data.content,
        customer: data.customer ? String(data.customer) : undefined,
        customer_name: data.customer_name || undefined,
        customer_email: data.customer_email || undefined,
        appointment: data.appointment ? String(data.appointment) : undefined,
        appointment_service_name: data.appointment_service_name || undefined,
        appointment_start_time: data.appointment_start_time || undefined,
        service: data.service ? String(data.service) : undefined,
        service_name: data.service_name || undefined,
        sent_at: data.sent_at,
        signed_at: data.signed_at,
        expires_at: data.expires_at,
        voided_at: data.voided_at,
        voided_reason: data.voided_reason,
        public_token: data.signing_token || data.public_token, // Backend returns signing_token
        created_at: data.created_at,
        updated_at: data.updated_at,
      };
    },
    enabled: !!id,
    retry: false,
  });
};

interface ContractInput {
  template: string;
  customer_id?: string;
  event_id?: string;
  send_email?: boolean;
}

/**
 * Hook to create a contract
 */
export const useCreateContract = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (contractData: ContractInput) => {
      const { data } = await apiClient.post('/contracts/', contractData);
      return data;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['contracts'] });
    },
  });
};

/**
 * Hook to send a contract to customer
 */
export const useSendContract = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (id: string) => {
      const { data } = await apiClient.post(`/contracts/${id}/send/`);
      return data;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['contracts'] });
    },
  });
};

/**
 * Hook to void a contract
 */
export const useVoidContract = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async ({ id, reason }: { id: string; reason: string }) => {
      const { data } = await apiClient.post(`/contracts/${id}/void/`, { reason });
      return data;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['contracts'] });
    },
  });
};

/**
 * Hook to resend a contract
 */
export const useResendContract = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (id: string) => {
      const { data } = await apiClient.post(`/contracts/${id}/resend/`);
      return data;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['contracts'] });
    },
  });
};

// --- Public Contract Access (no auth required) ---

/**
 * Hook to fetch public contract view by token (no auth required)
 */
export const usePublicContract = (token: string) => {
  return useQuery<ContractPublicView>({
    queryKey: ['public-contracts', token],
    queryFn: async () => {
      // Use the public signing endpoint
      const { data } = await apiClient.get(`/contracts/sign/${token}/`);
      return data;
    },
    enabled: !!token,
    retry: false,
  });
};

/**
 * Hook to sign a contract (no auth required)
 */
export const useSignContract = () => {
  return useMutation({
    mutationFn: async ({
      token,
      signer_name,
      consent_checkbox_checked,
      electronic_consent_given,
    }: {
      token: string;
      signer_name: string;
      consent_checkbox_checked: boolean;
      electronic_consent_given: boolean;
    }) => {
      const { data } = await apiClient.post(`/contracts/sign/${token}/`, {
        signer_name,
        consent_checkbox_checked,
        electronic_consent_given,
      });
      return data;
    },
  });
};

/**
 * Hook to export a legal compliance package for a signed contract
 */
export const useExportLegalPackage = () => {
  return useMutation({
    mutationFn: async (id: string) => {
      const response = await apiClient.get(`/contracts/${id}/export_legal/`, {
        responseType: 'blob',
      });

      // Create download link
      const url = window.URL.createObjectURL(new Blob([response.data]));
      const link = document.createElement('a');
      link.href = url;

      // Extract filename from Content-Disposition header if available
      const contentDisposition = response.headers['content-disposition'];
      let filename = `legal_export_${id}.zip`;
      if (contentDisposition) {
        const filenameMatch = contentDisposition.match(/filename="?([^";\n]+)"?/);
        if (filenameMatch && filenameMatch[1]) {
          filename = filenameMatch[1];
        }
      }

      link.setAttribute('download', filename);
      document.body.appendChild(link);
      link.click();
      link.remove();
      window.URL.revokeObjectURL(url);

      return { success: true };
    },
  });
};
