'use client';

import { createContext, useContext, ReactNode, useMemo } from 'react';
import { useTasks } from '@/hooks/useTasks';
import { useTags } from '@/hooks/useTags';
import { useUserPreferences } from './UserPreferencesContext';
import { Task, Tag, TaskStats, TaskStatus } from '@/lib/types';
import { CreateTaskData, TaskFilters } from '@/clients/tasks-client';
import type { KanbanFilters } from '@/lib/types';
import { sortTasks, getSortOption, DEFAULT_SORT, createSortKey } from '@/lib/sort-config';

interface TasksContextType {
  tasks: Task[]; // Toutes les tâches
  regularTasks: Task[]; // Tâches sans les épinglées (pour Kanban)
  stats: TaskStats;
  loading: boolean;
  syncing: boolean;
  error: string | null;
  createTask: (data: CreateTaskData) => Promise<Task | null>;
  updateTaskOptimistic: (taskId: string, status: TaskStatus) => Promise<Task | null>;
  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)
  activeFiltersCount: number; // Nombre de filtres actifs
  // Tags
  tags: Tag[];
  tagsLoading: boolean;
  tagsError: string | null;
}

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

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

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

  const { tags, loading: tagsLoading, error: tagsError } = useTags(initialTags);
  const { preferences, updateKanbanFilters, updateViewPreferences } = useUserPreferences();

  // Construire l'objet KanbanFilters à partir des préférences
  const kanbanFilters: KanbanFilters = useMemo(() => ({
    search: preferences.kanbanFilters.search || '',
    tags: preferences.kanbanFilters.tags || [],
    priorities: preferences.kanbanFilters.priorities || [],
    showCompleted: preferences.kanbanFilters.showCompleted ?? true,
    sortBy: preferences.kanbanFilters.sortBy || createSortKey('priority', 'desc'),
    compactView: preferences.viewPreferences.compactView || false,
    swimlanesByTags: preferences.viewPreferences.swimlanesByTags || false,
    swimlanesMode: preferences.viewPreferences.swimlanesMode || 'tags',
    showWithDueDate: preferences.kanbanFilters.showWithDueDate || false,
    showCompletedLast7Days: preferences.kanbanFilters.showCompletedLast7Days || false,
    // Filtres Jira
    showJiraOnly: preferences.kanbanFilters.showJiraOnly || false,
    hideJiraTasks: preferences.kanbanFilters.hideJiraTasks || false,
    jiraProjects: preferences.kanbanFilters.jiraProjects || [],
    jiraTypes: preferences.kanbanFilters.jiraTypes || [],
    // Filtres TFS
    showTfsOnly: preferences.kanbanFilters.showTfsOnly || false,
    hideTfsTasks: preferences.kanbanFilters.hideTfsTasks || false,
    tfsProjects: preferences.kanbanFilters.tfsProjects || []
  }), [preferences]);

  // Fonction pour mettre à jour les filtres avec persistance
  const setKanbanFilters = async (newFilters: KanbanFilters) => {
    // Séparer les vrais filtres des préférences de vue
    const kanbanFilterUpdates = {
      search: newFilters.search || '',
      tags: newFilters.tags,
      priorities: newFilters.priorities,
      showCompleted: newFilters.showCompleted,
      sortBy: newFilters.sortBy,
      showWithDueDate: newFilters.showWithDueDate,
      showCompletedLast7Days: newFilters.showCompletedLast7Days,
      // Filtres Jira
      showJiraOnly: newFilters.showJiraOnly,
      hideJiraTasks: newFilters.hideJiraTasks,
      jiraProjects: newFilters.jiraProjects,
      jiraTypes: newFilters.jiraTypes,
      // Filtres TFS
      showTfsOnly: newFilters.showTfsOnly,
      hideTfsTasks: newFilters.hideTfsTasks,
      tfsProjects: newFilters.tfsProjects
    };
    
    const viewPreferenceUpdates = {
      compactView: newFilters.compactView as boolean,
      swimlanesByTags: newFilters.swimlanesByTags as boolean,
      swimlanesMode: newFilters.swimlanesMode as 'tags' | 'priority'
    };
    
    // Mettre à jour via UserPreferencesContext
    await Promise.all([
      updateKanbanFilters(kanbanFilterUpdates),
      updateViewPreferences(viewPreferenceUpdates)
    ]);
  };


  // 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]);

  // Calcul du nombre de filtres actifs
  const activeFiltersCount = useMemo(() => {
    return (kanbanFilters.tags?.filter(Boolean).length || 0) + 
           (kanbanFilters.priorities?.filter(Boolean).length || 0) + 
           (kanbanFilters.search ? 1 : 0) + 
           (kanbanFilters.showWithDueDate ? 1 : 0) +
           (kanbanFilters.showCompletedLast7Days ? 1 : 0) +
           (kanbanFilters.jiraProjects?.filter(Boolean).length || 0) + 
           (kanbanFilters.jiraTypes?.filter(Boolean).length || 0) + 
           (kanbanFilters.showJiraOnly ? 1 : 0) + 
           (kanbanFilters.hideJiraTasks ? 1 : 0) +
           (kanbanFilters.tfsProjects?.filter(Boolean).length || 0) +
           (kanbanFilters.showTfsOnly ? 1 : 0) + 
           (kanbanFilters.hideTfsTasks ? 1 : 0);
  }, [kanbanFilters]);

  // 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)
      );
    }

    // Filtres spécifiques Jira
    if (kanbanFilters.showJiraOnly) {
      filtered = filtered.filter(task => task.source === 'jira');
    } else if (kanbanFilters.hideJiraTasks) {
      filtered = filtered.filter(task => task.source !== 'jira');
    }

    // Filtre par projets Jira
    if (kanbanFilters.jiraProjects?.length) {
      filtered = filtered.filter(task =>
        task.source !== 'jira' || kanbanFilters.jiraProjects!.includes(task.jiraProject || '')
      );
    }

    // Filtre par types Jira
    if (kanbanFilters.jiraTypes?.length) {
      filtered = filtered.filter(task =>
        task.source !== 'jira' || kanbanFilters.jiraTypes!.includes(task.jiraType || '')
      );
    }

    // Filtres spécifiques TFS
    if (kanbanFilters.showTfsOnly) {
      filtered = filtered.filter(task => task.source === 'tfs');
    } else if (kanbanFilters.hideTfsTasks) {
      filtered = filtered.filter(task => task.source !== 'tfs');
    }

    // Filtre par projets TFS
    if (kanbanFilters.tfsProjects?.length) {
      filtered = filtered.filter(task =>
        task.source !== 'tfs' || kanbanFilters.tfsProjects!.includes(task.tfsProject || '')
      );
    }

    // Filtre par date de fin
    if (kanbanFilters.showWithDueDate) {
      filtered = filtered.filter(task => task.dueDate != null);
    }

    // Filtre par tâches complétées les 7 derniers jours
    if (kanbanFilters.showCompletedLast7Days) {
      const sevenDaysAgo = new Date();
      sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);
      
      filtered = filtered.filter(task => 
        task.status === 'done' && 
        task.completedAt && 
        task.completedAt >= sevenDaysAgo
      );
    }

    // 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,
    regularTasks,
    tags,
    tagsLoading,
    tagsError,
    kanbanFilters,
    setKanbanFilters,
    filteredTasks,
    pinnedTasks,
    activeFiltersCount
  };

  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;
}
