'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
  oldCompletedTasksCount: number; // Nombre de tâches terminées depuis +15j
  // 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();

  // Fonction utilitaire pour identifier les statuts terminés
  const isCompletedStatus = (status: TaskStatus): boolean => {
    return ['done', 'cancelled', 'archived'].includes(status);
  };

  // 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,
      hideCompletedOlderThan15Days:
        preferences.kanbanFilters.hideCompletedOlderThan15Days || 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 || [],
      // Filtres Manuel
      showManualOnly: preferences.kanbanFilters.showManualOnly || false,
      hideManualTasks: preferences.kanbanFilters.hideManualTasks || false,
    }),
    [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,
      hideCompletedOlderThan15Days: newFilters.hideCompletedOlderThan15Days,
      // 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,
      // Filtres Manuel
      showManualOnly: newFilters.showManualOnly,
      hideManualTasks: newFilters.hideManualTasks,
    };

    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.showManualOnly ? 1 : 0) +
      (kanbanFilters.hideManualTasks ? 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');
    }

    // Filtres spécifiques Manuel
    if (kanbanFilters.showManualOnly) {
      filtered = filtered.filter((task) => task.source === 'manual');
    } else if (kanbanFilters.hideManualTasks) {
      filtered = filtered.filter((task) => task.source !== 'manual');
    }

    // 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) =>
          isCompletedStatus(task.status) &&
          task.completedAt &&
          task.completedAt >= sevenDaysAgo
      );
    }

    // Filtre pour masquer les tâches terminées depuis plus de 7 jours
    if (kanbanFilters.hideCompletedOlderThan15Days) {
      const sevenDaysAgo = new Date();
      sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);

      filtered = filtered.filter(
        (task) =>
          !isCompletedStatus(task.status) ||
          !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]);

  // Calculer le nombre de tickets terminés depuis plus de 7 jours
  const oldCompletedTasksCount = useMemo(() => {
    if (!regularTasks || regularTasks.length === 0) return 0;

    const sevenDaysAgo = new Date();
    sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);

    const oldTasks = regularTasks.filter(
      (task) =>
        isCompletedStatus(task.status) &&
        task.completedAt &&
        task.completedAt < sevenDaysAgo
    );

    return oldTasks.length;
  }, [regularTasks]);

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

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