'use client';

import { createContext, useContext, ReactNode, useState, useMemo, useEffect } from 'react';
import { useTasks } from '@/hooks/useTasks';
import { useTags } from '@/hooks/useTags';
import { userPreferencesService } from '@/services/user-preferences';
import { Task, Tag } from '@/lib/types';
import { CreateTaskData, UpdateTaskData, TaskFilters } from '@/clients/tasks-client';
import { KanbanFilters } from '@/components/kanban/KanbanFilters';
import { sortTasks, getSortOption, DEFAULT_SORT, createSortKey } from '@/lib/sort-config';

interface TasksContextType {
  tasks: Task[];
  stats: {
    total: number;
    completed: number;
    inProgress: number;
    todo: number;
    cancelled: number;
    freeze: number;
    completionRate: number;
  };
  loading: boolean;
  syncing: boolean;
  error: string | null;
  createTask: (data: CreateTaskData) => Promise<Task | null>;
  updateTask: (data: UpdateTaskData) => Promise<Task | null>;
  updateTaskOptimistic: (data: UpdateTaskData) => Promise<Task | null>;
  deleteTask: (taskId: string) => Promise<void>;
  refreshTasks: () => Promise<void>;
  setFilters: (filters: TaskFilters) => void;
  // Kanban filters
  kanbanFilters: KanbanFilters;
  setKanbanFilters: (filters: KanbanFilters) => void;
  filteredTasks: Task[];
  pinnedTasks: Task[]; // Tâches avec tags épinglés (objectifs)
  // Tags
  tags: Tag[];
  tagsLoading: boolean;
  tagsError: string | null;
}

const TasksContext = createContext<TasksContextType | null>(null);

interface TasksProviderProps {
  children: ReactNode;
  initialTasks: Task[];
  initialStats: TasksContextType['stats'];
  initialTags?: (Tag & { usage: number })[];
}

export function TasksProvider({ children, initialTasks, initialStats, initialTags }: TasksProviderProps) {
  const tasksState = useTasks(
    { limit: 20 },
    { tasks: initialTasks, stats: initialStats }
  );

  const { tags, loading: tagsLoading, error: tagsError } = useTags(initialTags);
  
  // État des filtres Kanban avec persistance
  const [kanbanFilters, setKanbanFilters] = useState<KanbanFilters>({});

  // Charger les préférences au montage
  useEffect(() => {
    const savedFilters = userPreferencesService.getKanbanFilters();
    const savedViewPrefs = userPreferencesService.getViewPreferences();
    
    setKanbanFilters({
      search: savedFilters.search,
      tags: savedFilters.tags,
      priorities: savedFilters.priorities,
      showCompleted: savedFilters.showCompleted,
      sortBy: savedFilters.sortBy || createSortKey('priority', 'desc'), // Tri par défaut
      compactView: savedViewPrefs.compactView,
      swimlanesByTags: savedViewPrefs.swimlanesByTags
    });
  }, []);

  // Fonction pour mettre à jour les filtres avec persistance
  const updateKanbanFilters = (newFilters: KanbanFilters) => {
    setKanbanFilters(newFilters);
    
    // Sauvegarder les filtres
    userPreferencesService.saveKanbanFilters({
      search: newFilters.search,
      tags: newFilters.tags,
      priorities: newFilters.priorities,
      showCompleted: newFilters.showCompleted,
      sortBy: newFilters.sortBy
    });
    
    // Sauvegarder les préférences de vue
    userPreferencesService.saveViewPreferences({
      compactView: newFilters.compactView || false,
      swimlanesByTags: newFilters.swimlanesByTags || false,
      showObjectives: true // Toujours visible pour l'instant
    });
  };

  // Séparer les tâches épinglées (objectifs) des autres et les trier
  const { pinnedTasks, regularTasks } = useMemo(() => {
    const pinnedTagNames = tags.filter(tag => tag.isPinned).map(tag => tag.name);
    
    const pinned: Task[] = [];
    const regular: Task[] = [];
    
    tasksState.tasks.forEach(task => {
      const hasPinnedTag = task.tags?.some(tagName => pinnedTagNames.includes(tagName));
      if (hasPinnedTag) {
        pinned.push(task);
      } else {
        regular.push(task);
      }
    });
    
    // Trier les tâches épinglées avec le même tri que les autres
    const sortedPinned = kanbanFilters.sortBy ? 
      (() => {
        const sortOption = getSortOption(kanbanFilters.sortBy);
        return sortOption ? 
          sortTasks(pinned, [{ field: sortOption.field, direction: sortOption.direction }]) :
          sortTasks(pinned, DEFAULT_SORT);
      })() :
      sortTasks(pinned, DEFAULT_SORT);
    
    return { pinnedTasks: sortedPinned, regularTasks: regular };
  }, [tasksState.tasks, tags, kanbanFilters.sortBy]);

  // Filtrage et tri des tâches régulières (pas les épinglées)
  const filteredTasks = useMemo(() => {
    let filtered = regularTasks;

    // Filtre par recherche
    if (kanbanFilters.search) {
      const searchLower = kanbanFilters.search.toLowerCase();
      filtered = filtered.filter(task => 
        task.title.toLowerCase().includes(searchLower) ||
        task.description?.toLowerCase().includes(searchLower) ||
        task.tags?.some(tag => tag.toLowerCase().includes(searchLower))
      );
    }

    // Filtre par tags
    if (kanbanFilters.tags?.length) {
      filtered = filtered.filter(task =>
        kanbanFilters.tags!.some(filterTag =>
          task.tags?.includes(filterTag)
        )
      );
    }

    // Filtre par priorités
    if (kanbanFilters.priorities?.length) {
      filtered = filtered.filter(task =>
        kanbanFilters.priorities!.includes(task.priority)
      );
    }

    // Tri des tâches
    if (kanbanFilters.sortBy) {
      const sortOption = getSortOption(kanbanFilters.sortBy);
      if (sortOption) {
        filtered = sortTasks(filtered, [{ 
          field: sortOption.field, 
          direction: sortOption.direction 
        }]);
      }
    } else {
      // Tri par défaut (priorité desc + tags asc)
      filtered = sortTasks(filtered, DEFAULT_SORT);
    }

    return filtered;
  }, [regularTasks, kanbanFilters]);

  const contextValue: TasksContextType = {
    ...tasksState,
    tags,
    tagsLoading,
    tagsError,
    kanbanFilters,
    setKanbanFilters: updateKanbanFilters,
    filteredTasks,
    pinnedTasks
  };

  return (
    <TasksContext.Provider value={contextValue}>
      {children}
    </TasksContext.Provider>
  );
}

export function useTasksContext() {
  const context = useContext(TasksContext);
  if (!context) {
    throw new Error('useTasksContext must be used within a TasksProvider');
  }
  return context;
}
