"use client";

import { useEffect, useState, useRef } from "react";
import { useSession } from "next-auth/react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { RefreshCw, Share2, Folder } from "lucide-react";
import { Badge } from "@/components/ui/badge";
import { useUnifiedRefresh } from "@/hooks/use-unified-refresh";
import { REFRESH_INTERVALS } from "@/lib/constants/refresh-intervals";
import { useWidgetNotification } from "@/hooks/use-widget-notification";

interface Task {
  id: number;
  headline: string;
  description: string;
  dateToFinish: string | null;
  projectId: number;
  projectName: string;
  status: number;
  editorId?: string;
  editorFirstname?: string;
  editorLastname?: string;
  authorFirstname: string;
  authorLastname: string;
  milestoneHeadline?: string;
  editTo?: string;
  editFrom?: string;
  type?: string;
  dependingTicketId?: number | null;
}

interface ProjectSummary {
  name: string;
  tasks: {
    status: number;
    count: number;
  }[];
}

interface TaskWithDate extends Task {
  validDate?: Date;
}

export function Duties() {
  const { data: session, status } = useSession();
  const [tasks, setTasks] = useState<TaskWithDate[]>([]);
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);
  const [refreshing, setRefreshing] = useState(false);
  const { triggerNotification } = useWidgetNotification();
  const lastTaskCountRef = useRef<number>(-1);

  const getStatusLabel = (status: number): string => {
    switch (status) {
      case 1: return 'New';
      case 2: return 'Blocked';
      case 3: return 'In Progress';
      case 4: return 'Waiting for Approval';
      case 5: return 'Done';
      default: return 'Unknown';
    }
  };

  const getStatusColor = (status: number): string => {
    switch (status) {
      case 1: return 'bg-blue-500';   // New - blue
      case 2: return 'bg-red-500';    // Blocked - red
      case 3: return 'bg-yellow-500'; // In Progress - yellow
      case 4: return 'bg-purple-500'; // Waiting for Approval - purple
      case 5: return 'bg-gray-500';   // Done - gray
      default: return 'bg-gray-300';
    }
  };

  const formatDate = (dateStr: string): string => {
    if (!dateStr || dateStr === '0000-00-00 00:00:00') return '';
    try {
      const date = new Date(dateStr);
      if (isNaN(date.getTime())) return '';
      return date.toLocaleDateString('fr-FR', {
        day: '2-digit',
        month: '2-digit',
        year: 'numeric'
      });
    } catch {
      return '';
    }
  };

  const getValidDate = (task: Task): string | null => {
    if (task.dateToFinish && task.dateToFinish !== '0000-00-00 00:00:00') {
      return task.dateToFinish;
    }
    return null;
  };

  const fetchTasks = async (forceRefresh = false) => {
    // Only show loading spinner on initial load, not on auto-refresh
    if (!tasks.length) {
      setLoading(true);
    }
    setRefreshing(true);
    setError(null);
    try {
      // Fetch tasks from both Leantime and Twenty CRM in parallel
      const leantimeUrl = forceRefresh ? '/api/leantime/tasks?refresh=true' : '/api/leantime/tasks';
      const twentyCrmUrl = forceRefresh ? '/api/twenty-crm/tasks?refresh=true' : '/api/twenty-crm/tasks';
      
      const [leantimeResponse, twentyCrmResponse] = await Promise.allSettled([
        fetch(leantimeUrl),
        fetch(twentyCrmUrl),
      ]);

      // Process Leantime tasks
      let leantimeTasks: Task[] = [];
      if (leantimeResponse.status === 'fulfilled' && leantimeResponse.value.ok) {
        const leantimeData = await leantimeResponse.value.json();
        if (Array.isArray(leantimeData)) {
          leantimeTasks = leantimeData;
        }
      } else {
        console.warn('Failed to fetch Leantime tasks:', leantimeResponse);
      }

      // Process Twenty CRM tasks
      let twentyCrmTasks: Task[] = [];
      if (twentyCrmResponse.status === 'fulfilled' && twentyCrmResponse.value.ok) {
        const twentyCrmData = await twentyCrmResponse.value.json();
        if (Array.isArray(twentyCrmData)) {
          twentyCrmTasks = twentyCrmData;
        }
      } else {
        console.warn('Failed to fetch Twenty CRM tasks:', twentyCrmResponse);
      }

      // Combine tasks from both sources
      const allTasks = [...leantimeTasks, ...twentyCrmTasks];
      
      console.log('Combined tasks:', {
        leantime: leantimeTasks.length,
        twentyCrm: twentyCrmTasks.length,
        total: allTasks.length,
      });

      if (allTasks.length === 0) {
        setTasks([]);
        return;
      }

      // Backend already filters out status=5 (Done) and filters by editorId for Leantime
      // Backend also filters Twenty CRM tasks to include overdue and due today
      // Filter to keep only tasks with due date <= today (overdue or due today)
      const now = new Date();
      const todayYear = now.getFullYear();
      const todayMonth = now.getMonth();
      const todayDay = now.getDate();
      
      const filteredTasks = allTasks.filter((task: Task) => {
        // Exclude tasks with status Done (5)
        if (task.status === 5) {
          return false;
        }
        
        const dueDate = getValidDate(task);
        if (!dueDate) {
          return false; // Exclude tasks without a due date
        }
        
        // Use local date comparison to avoid timezone issues
        // Leantime dates with 'Z' are actually local time, not UTC - remove Z before parsing
        const dateStrForParsing = dueDate.endsWith('Z') ? dueDate.slice(0, -1) : dueDate;
        const taskDueDate = new Date(dateStrForParsing);
        const taskYear = taskDueDate.getFullYear();
        const taskMonth = taskDueDate.getMonth();
        const taskDay = taskDueDate.getDate();
        
        // Keep tasks with due date <= today (overdue or due today, not future)
        const isOverdueOrDueToday = taskYear < todayYear || 
                                   (taskYear === todayYear && taskMonth < todayMonth) ||
                                   (taskYear === todayYear && taskMonth === todayMonth && taskDay <= todayDay);
        
        return isOverdueOrDueToday;
      });

      // Sort by dateToFinish (oldest first)
      const sortedTasks = filteredTasks
        .sort((a: Task, b: Task) => {
          // First sort by dateToFinish (oldest first)
          const dateA = getValidDate(a);
          const dateB = getValidDate(b);
          
          // Both dates are guaranteed to exist after filtering
          if (dateA && dateB) {
            const timeA = new Date(dateA).getTime();
            const timeB = new Date(dateB).getTime();
            if (timeA !== timeB) {
              return timeA - timeB;
            }
          }
          
          // If dates are equal, sort by status (4 before others)
          if (a.status === 4 && b.status !== 4) return -1;
          if (b.status === 4 && a.status !== 4) return 1;
          
          // If status is also equal, maintain original order
          return 0;
        });

      console.log('Sorted tasks:', sortedTasks.map(t => ({
        id: t.id,
        date: t.dateToFinish,
        status: t.status,
        type: t.type || 'main',
        source: (t as any).source || 'leantime'
      })));
      
      // Calculate current task count
      const currentTaskCount = sortedTasks.length;
      
      // Always trigger notification to keep the count fresh in Redis
      // This prevents the count from expiring if it hasn't changed
      const shouldUpdate = currentTaskCount !== lastTaskCountRef.current || lastTaskCountRef.current === -1;
      
      if (shouldUpdate) {
        lastTaskCountRef.current = currentTaskCount;
      }
      
      // Prepare notification items (max 10)
      const notificationItems = sortedTasks
        .slice(0, 10)
        .map(task => ({
          id: task.id.toString(),
          title: task.headline,
          message: task.dateToFinish 
            ? `Due: ${formatDate(task.dateToFinish)}` 
            : 'Tâche en retard',
          link: (task as any).source === 'twenty-crm'
            ? (task as any).url
            : `https://agilite.slm-lab.net/tickets/showTicket/${String(task.id).replace('twenty-', '')}`,
          timestamp: task.dateToFinish 
            ? new Date(task.dateToFinish) 
            : new Date(),
          metadata: {
            source: (task as any).source || 'leantime',
            projectName: task.projectName,
            status: task.status,
          },
        }));

      // Always trigger notification update to keep count fresh in Redis
      // This ensures the count doesn't expire even if it hasn't changed
      await triggerNotification({
        source: 'leantime',
        count: currentTaskCount,
        items: notificationItems,
      });
      
      setTasks(sortedTasks);
      
      // Dispatch event for Outlook-style notifications (when tasks are due)
      const tasksForNotification = sortedTasks.map(task => ({
        id: task.id.toString(),
        headline: task.headline,
        dateToFinish: task.dateToFinish,
        source: (task as any).source || 'leantime',
        projectName: task.projectName,
        url: (task as any).url || null,
      }));
      
      console.log('[Devoirs Widget] 📋 Dispatching tasks update', {
        tasksCount: tasksForNotification.length,
        tasks: tasksForNotification.map(t => ({
          id: t.id,
          title: t.headline,
          dateToFinish: t.dateToFinish,
          source: t.source,
        })),
      });
      
      try {
        window.dispatchEvent(new CustomEvent('tasks-updated', {
          detail: {
            tasks: tasksForNotification,
          }
        }));
        console.log('[Devoirs Widget] ✅ Event dispatched successfully');
      } catch (error) {
        console.error('[Devoirs Widget] ❌ Error dispatching event', error);
      }
    } catch (error) {
      console.error('Error fetching tasks:', error);
      setError(error instanceof Error ? error.message : 'Failed to fetch tasks');
    } finally {
      setLoading(false);
      setRefreshing(false);
    }
  };

  // Initial fetch on mount
  useEffect(() => {
    if (status === 'authenticated') {
      fetchTasks(false); // Use cache on initial load
    }
  }, [status]);

  // Integrate unified refresh for automatic polling
  const { refresh } = useUnifiedRefresh({
    resource: 'duties',
    interval: REFRESH_INTERVALS.DUTIES, // 30 seconds (harmonized)
    enabled: status === 'authenticated',
    onRefresh: async () => {
      await fetchTasks(false); // Use cache for auto-refresh
    },
    priority: 'high',
  });

  // Manual refresh handler (bypasses cache)
  const handleManualRefresh = async () => {
    await fetchTasks(true); // Force refresh, bypass cache
  };

  // Update the TaskDate component to handle dates better
  const TaskDate = ({ task }: { task: TaskWithDate }) => {
    const dateStr = task.dateToFinish;
    if (!dateStr || dateStr === '0000-00-00 00:00:00') {
      return (
        <div className="flex flex-col items-center">
          <span className="text-[10px] text-gray-600 font-medium">NO</span>
          <span className="text-sm text-gray-700 font-bold">DATE</span>
        </div>
      );
    }

    try {
      const date = new Date(dateStr);
      if (isNaN(date.getTime())) {
        throw new Error('Invalid date');
      }

      const today = new Date();
      today.setHours(0, 0, 0, 0);
      const isPastDue = date < today;

      const month = date.toLocaleString('fr-FR', { month: 'short' }).toUpperCase();
      const day = date.getDate();
      const year = date.getFullYear();
      
      return (
        <div className="flex flex-col items-center">
          <div className="flex flex-col items-center">
            <span className={`text-[10px] font-medium uppercase ${isPastDue ? 'text-red-600' : 'text-blue-600'}`}>
              {month}
            </span>
            <span className={`text-sm font-bold ${isPastDue ? 'text-red-700' : 'text-blue-700'}`}>
              {day}
            </span>
          </div>
          <span className={`text-[8px] font-medium ${isPastDue ? 'text-red-500' : 'text-blue-500'}`}>
            {year}
          </span>
        </div>
      );
    } catch (error) {
      console.error('Error formatting date for task', task.id, error);
      return (
        <div className="flex flex-col items-center">
          <span className="text-[10px] text-gray-600 font-medium">ERR</span>
          <span className="text-sm text-gray-700 font-bold">DATE</span>
        </div>
      );
    }
  };

  return (
    <Card className="transition-transform duration-500 ease-in-out transform hover:scale-105 bg-white/95 backdrop-blur-sm border-0 shadow-lg">
      <CardHeader className="flex flex-row items-center justify-between pb-2 border-b border-gray-100">
        <CardTitle className="text-lg font-semibold text-gray-800 flex items-center gap-2">
          <Share2 className="h-5 w-5 text-gray-600" />
          Devoirs
        </CardTitle>
        <Button 
          variant="ghost" 
          size="icon" 
          onClick={handleManualRefresh}
          disabled={refreshing}
          className="h-7 w-7 p-0 hover:bg-gray-100/50 rounded-full"
        >
          <RefreshCw className={`h-3.5 w-3.5 text-gray-600 ${refreshing ? 'animate-spin' : ''}`} />
        </Button>
      </CardHeader>
      <CardContent className="p-3">
        {loading ? (
          <div className="flex items-center justify-center py-6">
            <div className="h-4 w-4 animate-spin rounded-full border-2 border-blue-500 border-t-transparent" />
          </div>
        ) : error ? (
          <div className="text-xs text-red-500 text-center py-3">{error}</div>
        ) : tasks.length === 0 ? (
          <div className="text-xs text-gray-500 text-center py-6">Aucune tâche en retard</div>
        ) : (
          <div className="space-y-2 max-h-[400px] overflow-y-auto pr-1 scrollbar-thin scrollbar-thumb-gray-200 scrollbar-track-transparent">
            {tasks.map((task) => (
              <div 
                key={task.id}
                className="p-2 rounded-lg bg-white shadow-sm hover:shadow-md transition-all duration-200 border border-gray-100"
              >
                <div className="flex gap-2">
                  <div className="flex-shrink-0 w-12 h-12 rounded-lg bg-blue-50 flex flex-col items-center justify-center border border-blue-100">
                    <TaskDate task={task} />
                  </div>
                  <div className="flex-1 min-w-0 space-y-1">
                    <a 
                      href={(task as any).url || `https://agilite.slm-lab.net/tickets/showTicket/${task.id.replace('twenty-', '')}`}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="text-blue-600 hover:text-blue-700 font-medium block text-sm line-clamp-2"
                    >
                      {task.headline}
                    </a>
                    <div className="flex items-center text-gray-500 text-[10px] bg-gray-50 px-1.5 py-0.5 rounded-md">
                      <Folder className="h-2.5 w-2.5 mr-1 opacity-70" />
                      {(task as any).source === 'twenty-crm' ? (
                        <>
                          <span className="truncate">SLM IF</span>
                          <span className="ml-1 text-[9px] text-purple-600 font-medium">(Médiation)</span>
                        </>
                      ) : (
                        <>
                          <span className="truncate">{task.projectName}</span>
                          <span className="ml-1 text-[9px] text-blue-600 font-medium">(Agilité)</span>
                        </>
                      )}
                    </div>
                  </div>
                </div>
              </div>
            ))}
          </div>
        )}
      </CardContent>
    </Card>
  );
}