'use client';

import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { api } from '@/lib/api';
import type {
  TimeEntry,
  TimeTrackingStatus,
  TimeSummary,
  TimeTrackingQueryParams,
  TimeEntryCorrectionDto,
} from '@/types/hr';

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

export const timeTrackingKeys = {
  all: ['timeTracking'] as const,
  status: (employeeId?: string) => [...timeTrackingKeys.all, 'status', employeeId] as const,
  entries: () => [...timeTrackingKeys.all, 'entries'] as const,
  entryList: (params?: TimeTrackingQueryParams) =>
    [...timeTrackingKeys.entries(), params] as const,
  summary: (employeeId: string, year: number, month: number) =>
    [...timeTrackingKeys.all, 'summary', employeeId, year, month] as const,
  detail: (id: string) => [...timeTrackingKeys.all, 'detail', id] as const,
};

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

async function fetchTimeStatus(employeeId?: string): Promise<TimeTrackingStatus> {
  return api.get('/hr/time/current', {
    params: employeeId ? { employeeId } : undefined,
  });
}

async function fetchTimeEntries(
  params?: TimeTrackingQueryParams
): Promise<TimeEntry[]> {
  return api.get('/hr/time/entries', {
    params: params as Record<string, string | number | boolean | undefined>,
  });
}

async function fetchTimeSummary(
  employeeId: string,
  year: number,
  month: number
): Promise<TimeSummary> {
  return api.get(`/hr/time/summary/${employeeId}/${year}/${month}`);
}

async function clockIn(): Promise<TimeTrackingStatus> {
  return api.post('/hr/time/clock-in');
}

async function clockOut(): Promise<TimeTrackingStatus> {
  return api.post('/hr/time/clock-out');
}

async function startBreak(): Promise<TimeTrackingStatus> {
  return api.post('/hr/time/break/start');
}

async function endBreak(): Promise<TimeTrackingStatus> {
  return api.post('/hr/time/break/end');
}

async function submitCorrection(dto: TimeEntryCorrectionDto): Promise<TimeEntry> {
  return api.post('/hr/time/entries', dto);
}

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

/**
 * Get current time tracking status
 */
export function useTimeTrackingStatus(employeeId?: string) {
  return useQuery({
    queryKey: timeTrackingKeys.status(employeeId),
    queryFn: () => fetchTimeStatus(employeeId),
    staleTime: 10 * 1000, // Refresh every 10 seconds
    refetchInterval: 30 * 1000, // Auto-refresh every 30 seconds
  });
}

/**
 * Get time entries with optional filters
 */
export function useTimeEntries(params?: TimeTrackingQueryParams) {
  return useQuery({
    queryKey: timeTrackingKeys.entryList(params),
    queryFn: () => fetchTimeEntries(params),
    staleTime: 30 * 1000,
  });
}

/**
 * Get monthly time summary for an employee
 */
export function useTimeSummary(employeeId: string, year: number, month: number) {
  return useQuery({
    queryKey: timeTrackingKeys.summary(employeeId, year, month),
    queryFn: () => fetchTimeSummary(employeeId, year, month),
    enabled: !!employeeId,
    staleTime: 60 * 1000,
  });
}

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

/**
 * Clock in mutation
 */
export function useClockIn() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: clockIn,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: timeTrackingKeys.status() });
      queryClient.invalidateQueries({ queryKey: timeTrackingKeys.entries() });
    },
  });
}

/**
 * Clock out mutation
 */
export function useClockOut() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: clockOut,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: timeTrackingKeys.status() });
      queryClient.invalidateQueries({ queryKey: timeTrackingKeys.entries() });
    },
  });
}

/**
 * Start break mutation
 */
export function useStartBreak() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: startBreak,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: timeTrackingKeys.status() });
    },
  });
}

/**
 * End break mutation
 */
export function useEndBreak() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: endBreak,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: timeTrackingKeys.status() });
    },
  });
}

/**
 * Submit time entry correction
 */
export function useSubmitCorrection() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: submitCorrection,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: timeTrackingKeys.entries() });
    },
  });
}
