'use client';

import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { api } from '@/lib/api';
import { skillsKeys, type SkillLevelValue, type SkillDepartment } from './use-skills';

/**
 * Employee in skill matrix
 */
export interface SkillMatrixEmployee {
  id: string;
  employeeNumber: string | null;
  position: string | null;
  user: {
    id: string;
    firstName: string;
    lastName: string;
    email: string;
  };
}

/**
 * Skill in matrix
 */
export interface SkillMatrixSkill {
  id: string;
  name: string;
  description: string | null;
  category: string | null;
  isGlobal: boolean;
}

/**
 * Skill entry details
 */
export interface SkillEntryDetails {
  level: SkillLevelValue;
  assessedAt: string | null;
  assessedBy: {
    id: string;
    firstName: string;
    lastName: string;
  } | null;
  notes: string | null;
}

/**
 * Employee row in matrix
 */
export interface SkillMatrixRow {
  employee: SkillMatrixEmployee;
  skills: Record<string, SkillEntryDetails>;
}

/**
 * Full skill matrix response
 */
export interface SkillMatrix {
  department: {
    id: string;
    name: string;
    code: string | null;
  };
  skills: SkillMatrixSkill[];
  matrix: SkillMatrixRow[];
}

/**
 * Skill gap analysis item
 */
export interface SkillGapAnalysis {
  skillId: string;
  skillName: string;
  category: string | null;
  targetLevel: number;
  averageLevel: number;
  gap: number;
  employeesBelow: number;
  employeesAtOrAbove: number;
  totalEmployees: number;
}

/**
 * Skill coverage data
 */
export interface SkillCoverage {
  skillId: string;
  skillName: string;
  levelDistribution: Record<number, number>;
  totalAssessed: number;
  coverage: number;
  averageLevel: number;
}

/**
 * Trainer info
 */
export interface TrainerInfo {
  employeeId: string;
  employeeNumber: string | null;
  position: string | null;
  user: {
    id: string;
    firstName: string;
    lastName: string;
    email: string;
    department?: SkillDepartment | null;
  };
  assessedAt: string;
}

/**
 * Trainers response
 */
export interface TrainersResponse {
  skill: {
    id: string;
    name: string;
    category: string | null;
  };
  trainers: TrainerInfo[];
  totalTrainers: number;
}

/**
 * Create skill entry DTO
 */
export interface CreateSkillEntryDto {
  employeeId: string;
  skillId: string;
  level: SkillLevelValue;
  notes?: string;
  nextReview?: string;
}

/**
 * Update skill entry DTO
 */
export interface UpdateSkillEntryDto {
  level?: SkillLevelValue;
  notes?: string;
  nextReview?: string;
}

/**
 * Bulk entry item
 */
export interface BulkEntryItem {
  employeeId: string;
  skillId: string;
  level: SkillLevelValue;
  notes?: string;
}

/**
 * Bulk entry DTO
 */
export interface BulkSkillEntryDto {
  entries: BulkEntryItem[];
}

/**
 * Bulk upsert response
 */
export interface BulkUpsertResponse {
  processed: number;
  created: number;
  updated: number;
  results: Array<{
    action: 'created' | 'updated';
    entry: unknown;
  }>;
}

/**
 * Query key factory for skill matrix
 */
export const skillMatrixKeys = {
  all: ['skill-matrix'] as const,
  matrix: (departmentId: string) => [...skillMatrixKeys.all, 'matrix', departmentId] as const,
  employee: (employeeId: string) => [...skillMatrixKeys.all, 'employee', employeeId] as const,
  gaps: (departmentId: string, targetLevel?: number) =>
    [...skillMatrixKeys.all, 'gaps', departmentId, targetLevel] as const,
  coverage: (skillId: string) => [...skillMatrixKeys.all, 'coverage', skillId] as const,
  trainers: (skillId: string) => [...skillMatrixKeys.all, 'trainers', skillId] as const,
};

/**
 * Fetch skill matrix for a department
 */
async function fetchMatrix(departmentId: string): Promise<SkillMatrix> {
  return api.get(`/lean/skill-matrix/${departmentId}`);
}

/**
 * Fetch skills for an employee
 */
async function fetchEmployeeSkills(employeeId: string): Promise<unknown> {
  return api.get(`/lean/skill-matrix/employee/${employeeId}`);
}

/**
 * Fetch skill gap analysis
 */
async function fetchGapAnalysis(
  departmentId: string,
  targetLevel?: number
): Promise<SkillGapAnalysis[]> {
  return api.get(`/lean/skill-matrix/gaps/${departmentId}`, {
    params: targetLevel !== undefined ? { targetLevel } : undefined,
  });
}

/**
 * Fetch skill coverage
 */
async function fetchSkillCoverage(skillId: string): Promise<SkillCoverage> {
  return api.get(`/lean/skill-matrix/coverage/${skillId}`);
}

/**
 * Fetch trainers for a skill
 */
async function fetchTrainers(skillId: string): Promise<TrainersResponse> {
  return api.get(`/lean/skill-matrix/trainers/${skillId}`);
}

/**
 * Create a skill entry
 */
async function createEntry(dto: CreateSkillEntryDto): Promise<unknown> {
  return api.post('/lean/skill-matrix/entries', dto);
}

/**
 * Update a skill entry
 */
async function updateEntry(id: string, dto: UpdateSkillEntryDto): Promise<unknown> {
  return api.put(`/lean/skill-matrix/entries/${id}`, dto);
}

/**
 * Delete a skill entry
 */
async function deleteEntry(id: string): Promise<void> {
  return api.delete(`/lean/skill-matrix/entries/${id}`);
}

/**
 * Bulk upsert skill entries
 */
async function bulkUpsert(dto: BulkSkillEntryDto): Promise<BulkUpsertResponse> {
  return api.post('/lean/skill-matrix/entries/bulk', dto);
}

/**
 * Hook to fetch skill matrix for a department
 */
export function useSkillMatrix(departmentId: string) {
  return useQuery({
    queryKey: skillMatrixKeys.matrix(departmentId),
    queryFn: () => fetchMatrix(departmentId),
    enabled: !!departmentId,
    staleTime: 30 * 1000,
  });
}

/**
 * Hook to fetch employee skills
 */
export function useEmployeeSkills(employeeId: string) {
  return useQuery({
    queryKey: skillMatrixKeys.employee(employeeId),
    queryFn: () => fetchEmployeeSkills(employeeId),
    enabled: !!employeeId,
    staleTime: 30 * 1000,
  });
}

/**
 * Hook to fetch skill gap analysis
 */
export function useSkillGapAnalysis(departmentId: string, targetLevel?: number) {
  return useQuery({
    queryKey: skillMatrixKeys.gaps(departmentId, targetLevel),
    queryFn: () => fetchGapAnalysis(departmentId, targetLevel),
    enabled: !!departmentId,
    staleTime: 30 * 1000,
  });
}

/**
 * Hook to fetch skill coverage
 */
export function useSkillCoverage(skillId: string) {
  return useQuery({
    queryKey: skillMatrixKeys.coverage(skillId),
    queryFn: () => fetchSkillCoverage(skillId),
    enabled: !!skillId,
    staleTime: 30 * 1000,
  });
}

/**
 * Hook to fetch trainers
 */
export function useTrainers(skillId: string) {
  return useQuery({
    queryKey: skillMatrixKeys.trainers(skillId),
    queryFn: () => fetchTrainers(skillId),
    enabled: !!skillId,
    staleTime: 30 * 1000,
  });
}

/**
 * Hook to create a skill entry
 */
export function useCreateSkillEntry() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: createEntry,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: skillMatrixKeys.all });
      queryClient.invalidateQueries({ queryKey: skillsKeys.all });
    },
  });
}

/**
 * Hook to update a skill entry
 */
export function useUpdateSkillEntry() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: ({ id, dto }: { id: string; dto: UpdateSkillEntryDto }) => updateEntry(id, dto),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: skillMatrixKeys.all });
    },
  });
}

/**
 * Hook to delete a skill entry
 */
export function useDeleteSkillEntry() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: deleteEntry,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: skillMatrixKeys.all });
    },
  });
}

/**
 * Hook to bulk upsert skill entries
 */
export function useBulkUpsertSkillEntries() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: bulkUpsert,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: skillMatrixKeys.all });
      queryClient.invalidateQueries({ queryKey: skillsKeys.all });
    },
  });
}
