// =============================================================================
// 🧑‍💼 EMPLOYEE SCHEDULE HOOK V2
// =============================================================================
// Хук для управления табелем сотрудника

'use client'

import { useQuery, useMutation } from '@apollo/client'
import { useCallback, useMemo } from 'react'
import { toast } from 'sonner'

import { 
  GET_EMPLOYEE_SCHEDULE_V2,
  UPDATE_EMPLOYEE_SCHEDULE_V2, 
} from '@/graphql/queries/employees-v2'

import type { 
  UseEmployeeScheduleReturn,
  EmployeeScheduleV2,
  UpdateScheduleInput,
  ScheduleStatus, 
} from '../types'

interface UseEmployeeScheduleProps {
  employeeId: string
  year: number
  month: number
}

export function useEmployeeSchedule({
  employeeId,
  year,
  month,
}: UseEmployeeScheduleProps): UseEmployeeScheduleReturn {
  
  // Запрос данных табеля
  const { data, loading, error, refetch } = useQuery(GET_EMPLOYEE_SCHEDULE_V2, {
    variables: {
      input: { employeeId, year, month },
    },
    fetchPolicy: 'cache-and-network',
    errorPolicy: 'all',
  })

  // Мутация для обновления записи
  const [updateScheduleMutation] = useMutation(UPDATE_EMPLOYEE_SCHEDULE_V2, {
    onCompleted: () => {
      toast.success('Табель обновлен!')
    },
    onError: (error) => {
      console.error('Schedule update error:', error)
      toast.error('Ошибка при обновлении табеля')
    },
  })

  // Мемоизация данных
  const schedule = useMemo(() => {
    return data?.employeeScheduleV2?.records || []
  }, [data?.employeeScheduleV2?.records])

  const summary = useMemo(() => {
    return data?.employeeScheduleV2?.summary
  }, [data?.employeeScheduleV2?.summary])

  const employee = useMemo(() => {
    return data?.employeeScheduleV2?.employee
  }, [data?.employeeScheduleV2?.employee])

  // =============================================================================
  // ОПЕРАЦИИ С ТАБЕЛЕМ
  // =============================================================================

  const updateDay = useCallback(async (data: UpdateScheduleInput) => {
    try {
      const result = await updateScheduleMutation({
        variables: { input: data },
      })

      if (result.data?.updateEmployeeScheduleV2?.success) {
        // Оптимистичное обновление локального кеша
        await refetch()
      }
    } catch (error) {
      console.error('Error updating schedule day:', error)
      throw error
    }
  }, [updateScheduleMutation, refetch])

  // Быстрое переключение статуса дня
  const toggleDayStatus = useCallback(async (date: Date, currentStatus: ScheduleStatus) => {
    const statusCycle: ScheduleStatus[] = ['WORK', 'WEEKEND', 'VACATION', 'SICK', 'ABSENT']
    const currentIndex = statusCycle.indexOf(currentStatus)
    const nextStatus = statusCycle[(currentIndex + 1) % statusCycle.length]
    
    const hoursWorked = nextStatus === 'WORK' ? 8 : 0

    await updateDay({
      employeeId,
      date,
      status: nextStatus,
      hoursWorked,
    })
  }, [employeeId, updateDay])

  // Массовое обновление статуса
  const bulkUpdateStatus = useCallback(async (
    dates: Date[], 
    status: ScheduleStatus,
    hoursWorked?: number,
  ) => {
    try {
      const updates = dates.map(date => 
        updateDay({
          employeeId,
          date,
          status,
          hoursWorked: status === 'WORK' ? (hoursWorked || 8) : 0,
        }),
      )

      await Promise.all(updates)
      toast.success(`Обновлено ${dates.length} дней`)
    } catch (error) {
      console.error('Bulk update error:', error)
      toast.error('Ошибка при массовом обновлении')
    }
  }, [employeeId, updateDay])

  // Получение статуса дня
  const getDayStatus = useCallback((date: Date): ScheduleStatus | null => {
    const dateStr = date.toISOString().split('T')[0]
    const record = schedule.find(r => 
      new Date(r.date).toISOString().split('T')[0] === dateStr,
    )
    return record?.status || null
  }, [schedule])

  // Получение часов за день
  const getDayHours = useCallback((date: Date): number => {
    const dateStr = date.toISOString().split('T')[0]
    const record = schedule.find(r => 
      new Date(r.date).toISOString().split('T')[0] === dateStr,
    )
    return record?.hoursWorked || 0
  }, [schedule])

  // Календарные утилиты
  const getDaysInMonth = useCallback((): Date[] => {
    const daysInMonth = new Date(year, month + 1, 0).getDate()
    return Array.from({ length: daysInMonth }, (_, i) => 
      new Date(year, month, i + 1),
    )
  }, [year, month])

  const getWorkDays = useCallback((): Date[] => {
    return getDaysInMonth().filter(date => {
      const dayOfWeek = date.getDay()
      return dayOfWeek !== 0 && dayOfWeek !== 6 // не воскресенье и не суббота
    })
  }, [getDaysInMonth])

  return {
    // Основные данные
    schedule,
    loading,
    error,
    refetch,
    
    // Дополнительные данные
    employee,
    summary,
    
    // Операции
    updateDay,
    toggleDayStatus,
    bulkUpdateStatus,
    
    // Утилиты
    getDayStatus,
    getDayHours,
    getDaysInMonth,
    getWorkDays,
  }
}