import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import * as ticketsApi from '../api/tickets'; // Import all functions from the API service
import { Ticket, TicketComment, TicketTemplate, CannedResponse, TicketStatus, TicketPriority, TicketCategory, TicketType } from '../types';

// Define interfaces for filters and mutation payloads if necessary
interface TicketFilters {
  status?: TicketStatus;
  priority?: TicketPriority;
  category?: TicketCategory;
  ticketType?: TicketType;
  assignee?: string;
}

/**
 * Hook to fetch a list of tickets with optional filters
 */
export const useTickets = (filters?: TicketFilters) => {
  return useQuery<Ticket[]>({
    queryKey: ['tickets', filters],
    queryFn: async () => {
      // Use the API filters
      const apiFilters: ticketsApi.TicketFilters = {};
      if (filters?.status) apiFilters.status = filters.status;
      if (filters?.priority) apiFilters.priority = filters.priority;
      if (filters?.category) apiFilters.category = filters.category;
      if (filters?.ticketType) apiFilters.ticketType = filters.ticketType;
      if (filters?.assignee) apiFilters.assignee = filters.assignee;

      const data = await ticketsApi.getTickets(apiFilters);
      // Transform data to match frontend types if necessary (e.g., snake_case to camelCase)
      return data.map((ticket: any) => ({
        id: String(ticket.id),
        tenant: ticket.tenant ? String(ticket.tenant) : undefined,
        creator: String(ticket.creator),
        creatorEmail: ticket.creator_email,
        creatorFullName: ticket.creator_full_name,
        assignee: ticket.assignee ? String(ticket.assignee) : undefined,
        assigneeEmail: ticket.assignee_email,
        assigneeFullName: ticket.assignee_full_name,
        ticketType: ticket.ticket_type,
        status: ticket.status,
        priority: ticket.priority,
        subject: ticket.subject,
        description: ticket.description,
        category: ticket.category,
        relatedAppointmentId: ticket.related_appointment_id || undefined,
        dueAt: ticket.due_at,
        firstResponseAt: ticket.first_response_at,
        isOverdue: ticket.is_overdue,
        createdAt: ticket.created_at,
        updatedAt: ticket.updated_at,
        resolvedAt: ticket.resolved_at,
        comments: ticket.comments,
      }));
    },
  });
};

/**
 * Hook to fetch a single ticket by ID
 */
export const useTicket = (id: string | undefined) => {
  return useQuery<Ticket>({
    queryKey: ['tickets', id],
    queryFn: async () => {
      const ticket: any = await ticketsApi.getTicket(id as string);
      return {
        id: String(ticket.id),
        tenant: ticket.tenant ? String(ticket.tenant) : undefined,
        creator: String(ticket.creator),
        creatorEmail: ticket.creator_email,
        creatorFullName: ticket.creator_full_name,
        assignee: ticket.assignee ? String(ticket.assignee) : undefined,
        assigneeEmail: ticket.assignee_email,
        assigneeFullName: ticket.assignee_full_name,
        ticketType: ticket.ticket_type,
        status: ticket.status,
        priority: ticket.priority,
        subject: ticket.subject,
        description: ticket.description,
        category: ticket.category,
        relatedAppointmentId: ticket.related_appointment_id || undefined,
        dueAt: ticket.due_at,
        firstResponseAt: ticket.first_response_at,
        isOverdue: ticket.is_overdue,
        createdAt: ticket.created_at,
        updatedAt: ticket.updated_at,
        resolvedAt: ticket.resolved_at,
        comments: ticket.comments,
      };
    },
    enabled: !!id, // Only run query if ID is provided
  });
};

/**
 * Hook to create a new ticket
 */
export const useCreateTicket = () => {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: async (ticketData: Partial<Omit<Ticket, 'id' | 'comments' | 'creator' | 'creatorEmail' | 'creatorFullName' | 'createdAt' | 'updatedAt' | 'resolvedAt'>>) => {
      // Map frontend naming to backend naming
      const dataToSend = {
        ...ticketData,
        ticket_type: ticketData.ticketType,
        assignee: ticketData.assignee || null,
        // No need to send creator or tenant, backend serializer handles it
      };
      const response = await ticketsApi.createTicket(dataToSend);
      return response;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['tickets'] }); // Invalidate tickets list to refetch
    },
  });
};

/**
 * Hook to update an existing ticket
 */
export const useUpdateTicket = () => {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: async ({ id, updates }: { id: string; updates: Partial<Ticket> }) => {
      const dataToSend = {
        ...updates,
        ticket_type: updates.ticketType,
        assignee: updates.assignee || null,
        // creator, tenant, comments are read-only on update
      };
      const response = await ticketsApi.updateTicket(id, dataToSend);
      return response;
    },
    onSuccess: (data, variables) => {
      queryClient.invalidateQueries({ queryKey: ['tickets'] });
      queryClient.invalidateQueries({ queryKey: ['tickets', variables.id] }); // Invalidate specific ticket
    },
  });
};

/**
 * Hook to delete a ticket
 */
export const useDeleteTicket = () => {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: async (id: string) => {
      await ticketsApi.deleteTicket(id);
      return id;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['tickets'] });
    },
  });
};

/**
 * Hook to fetch comments for a specific ticket
 */
export const useTicketComments = (ticketId: string | undefined) => {
  return useQuery<TicketComment[]>({
    queryKey: ['ticketComments', ticketId],
    queryFn: async () => {
      if (!ticketId) return [];
      const comments = await ticketsApi.getTicketComments(ticketId);
      return comments.map((comment: any) => ({
        ...comment,
        id: String(comment.id),
        ticket: String(comment.ticket),
        author: String(comment.author),
        createdAt: new Date(comment.created_at).toISOString(),
        commentText: comment.comment_text, // Map backend 'comment_text'
        isInternal: comment.is_internal, // Map backend 'is_internal'
      }));
    },
    enabled: !!ticketId, // Only run query if ticketId is provided
  });
};

/**
 * Hook to add a new comment to a ticket
 */
export const useCreateTicketComment = () => {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: async ({ ticketId, commentData }: { ticketId: string; commentData: Partial<TicketComment> }) => {
      const dataToSend = {
        ...commentData,
        comment_text: commentData.commentText,
        is_internal: commentData.isInternal,
        // ticket and author are handled by backend serializer
      };
      const response = await ticketsApi.createTicketComment(ticketId, dataToSend);
      return response;
    },
    onSuccess: (data, variables) => {
      queryClient.invalidateQueries({ queryKey: ['ticketComments', variables.ticketId] }); // Invalidate comments for this ticket
      queryClient.invalidateQueries({ queryKey: ['tickets', variables.ticketId] }); // Ticket might have a new comment count
    },
  });
};

/**
 * Hook to fetch ticket templates
 */
export const useTicketTemplates = () => {
  return useQuery<TicketTemplate[]>({
    queryKey: ['ticketTemplates'],
    queryFn: async () => {
      const data = await ticketsApi.getTicketTemplates();
      return data.map((template: any) => ({
        id: String(template.id),
        tenant: template.tenant ? String(template.tenant) : undefined,
        name: template.name,
        description: template.description,
        ticketType: template.ticket_type,
        category: template.category,
        defaultPriority: template.default_priority,
        subjectTemplate: template.subject_template,
        descriptionTemplate: template.description_template,
        isActive: template.is_active,
        createdAt: template.created_at,
      }));
    },
  });
};

/**
 * Hook to fetch a single ticket template by ID
 */
export const useTicketTemplate = (id: string | undefined) => {
  return useQuery<TicketTemplate>({
    queryKey: ['ticketTemplates', id],
    queryFn: async () => {
      const template: any = await ticketsApi.getTicketTemplate(id as string);
      return {
        id: String(template.id),
        tenant: template.tenant ? String(template.tenant) : undefined,
        name: template.name,
        description: template.description,
        ticketType: template.ticket_type,
        category: template.category,
        defaultPriority: template.default_priority,
        subjectTemplate: template.subject_template,
        descriptionTemplate: template.description_template,
        isActive: template.is_active,
        createdAt: template.created_at,
      };
    },
    enabled: !!id,
  });
};

/**
 * Hook to fetch canned responses
 */
export const useCannedResponses = () => {
  return useQuery<CannedResponse[]>({
    queryKey: ['cannedResponses'],
    queryFn: async () => {
      const data = await ticketsApi.getCannedResponses();
      return data.map((response: any) => ({
        id: String(response.id),
        tenant: response.tenant ? String(response.tenant) : undefined,
        title: response.title,
        content: response.content,
        category: response.category,
        isActive: response.is_active,
        useCount: response.use_count,
        createdBy: response.created_by ? String(response.created_by) : undefined,
        createdAt: response.created_at,
      }));
    },
  });
};

/**
 * Hook to manually refresh/check for new ticket emails
 */
export const useRefreshTicketEmails = () => {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: ticketsApi.refreshTicketEmails,
    onSuccess: (data) => {
      // Refresh tickets list if any emails were processed
      if (data.processed > 0) {
        queryClient.invalidateQueries({ queryKey: ['tickets'] });
      }
    },
  });
};
