'use client';

import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { api } from '@/lib/api';
import type {
  MorningMeeting,
  MeetingsQueryParams,
  LeanPaginatedResponse,
  CreateMeetingDto,
  UpdateMeetingDto,
  CreateTopicDto,
  UpdateTopicDto,
  CreateActionDto,
  UpdateActionDto,
  MorningMeetingTopic,
  MorningMeetingAction,
  KpiTrendData,
  SQCDMCategory,
} from '@/types/lean';

// =============================================================================
// QUERY KEY FACTORY
// =============================================================================

export const meetingKeys = {
  all: ['meetings'] as const,
  lists: () => [...meetingKeys.all, 'list'] as const,
  list: (params?: MeetingsQueryParams) => [...meetingKeys.lists(), params] as const,
  details: () => [...meetingKeys.all, 'detail'] as const,
  detail: (id: string) => [...meetingKeys.details(), id] as const,
  today: (departmentId: string) => [...meetingKeys.all, 'today', departmentId] as const,
  history: (departmentId: string, days?: number) =>
    [...meetingKeys.all, 'history', departmentId, days] as const,
  kpiTrends: (departmentId: string, category?: SQCDMCategory, days?: number) =>
    [...meetingKeys.all, 'kpi-trends', departmentId, category, days] as const,
  openActions: (departmentId?: string) =>
    [...meetingKeys.all, 'open-actions', departmentId] as const,
};

// =============================================================================
// API FUNCTIONS
// =============================================================================

async function fetchMeetings(
  params?: MeetingsQueryParams
): Promise<LeanPaginatedResponse<MorningMeeting>> {
  return api.get('/lean/meetings', { params: params as Record<string, string | number | boolean | undefined> });
}

async function fetchMeeting(id: string): Promise<MorningMeeting> {
  return api.get(`/lean/meetings/${id}`);
}

async function fetchTodaysMeeting(
  departmentId: string,
  create = false
): Promise<MorningMeeting> {
  return api.get(`/lean/meetings/today/${departmentId}`, {
    params: { create: create ? 'true' : undefined },
  });
}

async function fetchMeetingHistory(
  departmentId: string,
  days = 30
): Promise<MorningMeeting[]> {
  return api.get(`/lean/meetings/history/${departmentId}`, { params: { days } });
}

async function fetchKpiTrends(
  departmentId: string,
  category?: SQCDMCategory,
  days = 30
): Promise<KpiTrendData> {
  return api.get(`/lean/meetings/kpi-trends/${departmentId}`, {
    params: { category, days },
  });
}

async function fetchOpenActions(departmentId?: string): Promise<MorningMeetingAction[]> {
  return api.get('/lean/meetings/actions/open', { params: { departmentId } });
}

async function createMeeting(dto: CreateMeetingDto): Promise<MorningMeeting> {
  return api.post('/lean/meetings', dto);
}

async function updateMeeting(
  id: string,
  dto: UpdateMeetingDto
): Promise<MorningMeeting> {
  return api.put(`/lean/meetings/${id}`, dto);
}

async function deleteMeeting(id: string): Promise<MorningMeeting> {
  return api.delete(`/lean/meetings/${id}`);
}

async function startMeeting(id: string): Promise<MorningMeeting> {
  return api.post(`/lean/meetings/${id}/start`);
}

async function endMeeting(id: string): Promise<MorningMeeting> {
  return api.post(`/lean/meetings/${id}/end`);
}

// Topic APIs
async function addTopic(
  meetingId: string,
  dto: CreateTopicDto
): Promise<MorningMeetingTopic> {
  return api.post(`/lean/meetings/${meetingId}/topics`, dto);
}

async function updateTopic(
  id: string,
  dto: UpdateTopicDto
): Promise<MorningMeetingTopic> {
  return api.put(`/lean/meetings/topics/${id}`, dto);
}

async function deleteTopic(id: string): Promise<MorningMeetingTopic> {
  return api.delete(`/lean/meetings/topics/${id}`);
}

// Action APIs
async function addAction(
  meetingId: string,
  dto: CreateActionDto
): Promise<MorningMeetingAction> {
  return api.post(`/lean/meetings/${meetingId}/actions`, dto);
}

async function updateAction(
  id: string,
  dto: UpdateActionDto
): Promise<MorningMeetingAction> {
  return api.put(`/lean/meetings/actions/${id}`, dto);
}

async function completeAction(id: string): Promise<MorningMeetingAction> {
  return api.put(`/lean/meetings/actions/${id}/complete`);
}

// =============================================================================
// QUERY HOOKS
// =============================================================================

/**
 * Fetch all meetings with pagination and filters
 */
export function useMeetings(params?: MeetingsQueryParams) {
  return useQuery({
    queryKey: meetingKeys.list(params),
    queryFn: () => fetchMeetings(params),
    staleTime: 30 * 1000,
  });
}

/**
 * Fetch a single meeting by ID
 */
export function useMeeting(id: string) {
  return useQuery({
    queryKey: meetingKeys.detail(id),
    queryFn: () => fetchMeeting(id),
    enabled: !!id,
    staleTime: 30 * 1000,
  });
}

/**
 * Fetch today's meeting for a department
 */
export function useTodaysMeeting(departmentId: string, create = false) {
  return useQuery({
    queryKey: meetingKeys.today(departmentId),
    queryFn: () => fetchTodaysMeeting(departmentId, create),
    enabled: !!departmentId,
    staleTime: 30 * 1000,
    retry: false,
  });
}

/**
 * Fetch meeting history for a department
 */
export function useMeetingHistory(departmentId: string, days = 30) {
  return useQuery({
    queryKey: meetingKeys.history(departmentId, days),
    queryFn: () => fetchMeetingHistory(departmentId, days),
    enabled: !!departmentId,
    staleTime: 60 * 1000,
  });
}

/**
 * Fetch KPI trends for a department
 */
export function useKpiTrends(
  departmentId: string,
  category?: SQCDMCategory,
  days = 30
) {
  return useQuery({
    queryKey: meetingKeys.kpiTrends(departmentId, category, days),
    queryFn: () => fetchKpiTrends(departmentId, category, days),
    enabled: !!departmentId,
    staleTime: 60 * 1000,
  });
}

/**
 * Fetch all open action items
 */
export function useOpenActions(departmentId?: string) {
  return useQuery({
    queryKey: meetingKeys.openActions(departmentId),
    queryFn: () => fetchOpenActions(departmentId),
    staleTime: 30 * 1000,
  });
}

// =============================================================================
// MUTATION HOOKS
// =============================================================================

/**
 * Create a new meeting
 */
export function useCreateMeeting() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: createMeeting,
    onSuccess: (data) => {
      queryClient.invalidateQueries({ queryKey: meetingKeys.lists() });
      queryClient.invalidateQueries({
        queryKey: meetingKeys.today(data.department.id),
      });
    },
  });
}

/**
 * Update a meeting
 */
export function useUpdateMeeting() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: ({ id, dto }: { id: string; dto: UpdateMeetingDto }) =>
      updateMeeting(id, dto),
    onSuccess: (data) => {
      queryClient.invalidateQueries({ queryKey: meetingKeys.detail(data.id) });
      queryClient.invalidateQueries({ queryKey: meetingKeys.lists() });
      queryClient.invalidateQueries({
        queryKey: meetingKeys.today(data.department.id),
      });
    },
  });
}

/**
 * Delete a meeting
 */
export function useDeleteMeeting() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: deleteMeeting,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: meetingKeys.lists() });
    },
  });
}

/**
 * Start a meeting
 */
export function useStartMeeting() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: startMeeting,
    onSuccess: (data) => {
      queryClient.invalidateQueries({ queryKey: meetingKeys.detail(data.id) });
      queryClient.invalidateQueries({
        queryKey: meetingKeys.today(data.department.id),
      });
    },
  });
}

/**
 * End a meeting
 */
export function useEndMeeting() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: endMeeting,
    onSuccess: (data) => {
      queryClient.invalidateQueries({ queryKey: meetingKeys.detail(data.id) });
      queryClient.invalidateQueries({
        queryKey: meetingKeys.today(data.department.id),
      });
    },
  });
}

// =============================================================================
// TOPIC MUTATION HOOKS
// =============================================================================

/**
 * Add a topic to a meeting
 */
export function useAddTopic() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: ({ meetingId, dto }: { meetingId: string; dto: CreateTopicDto }) =>
      addTopic(meetingId, dto),
    onSuccess: (_, { meetingId }) => {
      queryClient.invalidateQueries({ queryKey: meetingKeys.detail(meetingId) });
    },
  });
}

/**
 * Update a topic
 */
export function useUpdateTopic() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: ({ id, dto }: { id: string; dto: UpdateTopicDto }) =>
      updateTopic(id, dto),
    onSuccess: () => {
      // Invalidate all meeting details as we don't know which meeting the topic belongs to
      queryClient.invalidateQueries({ queryKey: meetingKeys.details() });
    },
  });
}

/**
 * Delete a topic
 */
export function useDeleteTopic() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: deleteTopic,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: meetingKeys.details() });
    },
  });
}

// =============================================================================
// ACTION MUTATION HOOKS
// =============================================================================

/**
 * Add an action item to a meeting
 */
export function useAddAction() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: ({ meetingId, dto }: { meetingId: string; dto: CreateActionDto }) =>
      addAction(meetingId, dto),
    onSuccess: (_, { meetingId }) => {
      queryClient.invalidateQueries({ queryKey: meetingKeys.detail(meetingId) });
      queryClient.invalidateQueries({ queryKey: meetingKeys.openActions() });
    },
  });
}

/**
 * Update an action item
 */
export function useUpdateAction() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: ({ id, dto }: { id: string; dto: UpdateActionDto }) =>
      updateAction(id, dto),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: meetingKeys.details() });
      queryClient.invalidateQueries({ queryKey: meetingKeys.openActions() });
    },
  });
}

/**
 * Complete an action item
 */
export function useCompleteAction() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: completeAction,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: meetingKeys.details() });
      queryClient.invalidateQueries({ queryKey: meetingKeys.openActions() });
    },
  });
}
