'use client';

import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { api } from '@/lib/api';
import type { LeanPaginatedResponse } from '@/types/lean';

/**
 * S3 Status Types
 */
export type S3StatusType = 'GREEN' | 'YELLOW' | 'RED' | 'NOT_APPLICABLE';

/**
 * S3 Type (Category Type)
 */
export type S3Type = 'SEIRI' | 'SEITON' | 'SEISO';

/**
 * S3 Status Entry
 */
export interface S3Status {
  id: string;
  week: number;
  status: S3StatusType;
  photo: string | null;
  note: string | null;
  completedAt: string | null;
  completedBy: {
    id: string;
    firstName: string;
    lastName: string;
  } | null;
  createdAt: string;
  updatedAt: string;
}

/**
 * S3 Category
 */
export interface S3Category {
  id: string;
  name: string;
  s3Type: S3Type;
  sortOrder: number;
  statuses: S3Status[];
  createdAt: string;
  updatedAt: string;
}

/**
 * S3 Plan
 */
export interface S3Plan {
  id: string;
  year: number;
  month: number;
  isActive: boolean;
  departmentId: string;
  department: {
    id: string;
    name: string;
    code: string | null;
  };
  createdBy: {
    id: string;
    firstName: string;
    lastName: string;
    email: string;
  };
  categories: S3Category[];
  progress: number;
  createdAt: string;
  updatedAt: string;
  /** Category count from Prisma aggregation (optional) */
  _count?: {
    categories: number;
  };
}

/**
 * Query parameters for plans
 */
export interface QueryS3PlansParams {
  page?: number;
  limit?: number;
  departmentId?: string;
  year?: number;
  month?: number;
  isActive?: boolean;
  sortBy?: string;
  sortOrder?: 'asc' | 'desc';
}

/**
 * Create plan DTO
 */
export interface CreateS3PlanDto {
  departmentId: string;
  year: number;
  month: number;
  isActive?: boolean;
  categories?: {
    name: string;
    s3Type: S3Type;
    sortOrder?: number;
  }[];
}

/**
 * Update status DTO
 */
export interface UpdateS3StatusDto {
  status: S3StatusType;
  photo?: string;
  note?: string;
}

/**
 * Add category DTO
 */
export interface AddS3CategoryDto {
  name: string;
  s3Type: S3Type;
  sortOrder?: number;
}

/**
 * Query key factory for S3 queries
 */
export const s3Keys = {
  all: ['s3'] as const,
  plans: () => [...s3Keys.all, 'plans'] as const,
  plansList: (params?: QueryS3PlansParams) =>
    [...s3Keys.plans(), 'list', params] as const,
  plan: (id: string) => [...s3Keys.plans(), id] as const,
  categories: (planId: string) =>
    [...s3Keys.plans(), planId, 'categories'] as const,
  dashboard: (departmentId: string, year?: number, month?: number) =>
    [...s3Keys.all, 'dashboard', departmentId, year, month] as const,
  statistics: (year?: number, departmentIds?: string[]) =>
    [...s3Keys.all, 'statistics', year, departmentIds] as const,
};

/**
 * Fetch all S3 plans with filters
 */
async function fetchS3Plans(
  params?: QueryS3PlansParams,
): Promise<LeanPaginatedResponse<S3Plan>> {
  return api.get('/lean/s3/plans', { params: params as Record<string, string | number | boolean | undefined> });
}

/**
 * Fetch a single S3 plan
 */
async function fetchS3Plan(id: string): Promise<S3Plan> {
  return api.get(`/lean/s3/plans/${id}`);
}

/**
 * Create a new S3 plan
 */
async function createS3Plan(dto: CreateS3PlanDto): Promise<S3Plan> {
  return api.post('/lean/s3/plans', dto);
}

/**
 * Update a S3 plan
 */
async function updateS3Plan(
  id: string,
  dto: { isActive?: boolean },
): Promise<S3Plan> {
  return api.put(`/lean/s3/plans/${id}`, dto);
}

/**
 * Delete a S3 plan
 */
async function deleteS3Plan(id: string): Promise<void> {
  return api.delete(`/lean/s3/plans/${id}`);
}

/**
 * Add a category to a plan
 */
async function addCategory(
  planId: string,
  dto: AddS3CategoryDto,
): Promise<S3Category> {
  return api.post(`/lean/s3/plans/${planId}/categories`, dto);
}

/**
 * Update a category
 */
async function updateCategory(
  id: string,
  dto: { name?: string; sortOrder?: number },
): Promise<S3Category> {
  return api.put(`/lean/s3/categories/${id}`, dto);
}

/**
 * Delete a category
 */
async function deleteCategory(id: string): Promise<void> {
  return api.delete(`/lean/s3/categories/${id}`);
}

/**
 * Update a status entry
 */
async function updateStatus(
  id: string,
  dto: UpdateS3StatusDto,
): Promise<S3Status> {
  return api.put(`/lean/s3/status/${id}`, dto);
}

/**
 * Hook to fetch all S3 plans
 */
export function useS3Plans(params?: QueryS3PlansParams) {
  return useQuery({
    queryKey: s3Keys.plansList(params),
    queryFn: () => fetchS3Plans(params),
    staleTime: 30 * 1000,
  });
}

/**
 * Hook to fetch a single S3 plan
 */
export function useS3Plan(id: string) {
  return useQuery({
    queryKey: s3Keys.plan(id),
    queryFn: () => fetchS3Plan(id),
    enabled: !!id,
    staleTime: 30 * 1000,
  });
}

/**
 * Hook to create a new S3 plan
 */
export function useCreateS3Plan() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: createS3Plan,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: s3Keys.plans() });
    },
  });
}

/**
 * Hook to update a S3 plan
 */
export function useUpdateS3Plan() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: ({ id, dto }: { id: string; dto: { isActive?: boolean } }) =>
      updateS3Plan(id, dto),
    onSuccess: (_, { id }) => {
      queryClient.invalidateQueries({ queryKey: s3Keys.plan(id) });
      queryClient.invalidateQueries({ queryKey: s3Keys.plans() });
    },
  });
}

/**
 * Hook to delete a S3 plan
 */
export function useDeleteS3Plan() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: deleteS3Plan,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: s3Keys.plans() });
    },
  });
}

/**
 * Hook to add a category
 */
export function useAddCategory() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: ({ planId, dto }: { planId: string; dto: AddS3CategoryDto }) =>
      addCategory(planId, dto),
    onSuccess: (_, { planId }) => {
      queryClient.invalidateQueries({ queryKey: s3Keys.plan(planId) });
    },
  });
}

/**
 * Hook to update a category
 */
export function useUpdateCategory() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: ({
      id,
      dto,
    }: {
      id: string;
      dto: { name?: string; sortOrder?: number };
    }) => updateCategory(id, dto),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: s3Keys.plans() });
    },
  });
}

/**
 * Hook to delete a category
 */
export function useDeleteCategory() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: deleteCategory,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: s3Keys.plans() });
    },
  });
}
