"use client";

import { useEffect, useState, useMemo } 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, MessageSquare, Mail, MailOpen, Loader2 } from "lucide-react";
import Link from 'next/link';
import { useUnifiedRefresh } from "@/hooks/use-unified-refresh";
import { REFRESH_INTERVALS } from "@/lib/constants/refresh-intervals";
import { Badge } from "@/components/ui/badge";

interface Email {
  id: string;
  subject: string;
  from: string;
  fromName?: string;
  date: string;
  read: boolean;
  starred: boolean;
  folder: string;
}

interface EmailResponse {
  emails: Email[];
  mailUrl: string;
  error?: string;
}

export function Email() {
  const { data: session, status } = useSession();
  const [emails, setEmails] = useState<Email[]>([]);
  const [loading, setLoading] = useState(false);
  const [refreshing, setRefreshing] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [mailUrl, setMailUrl] = useState<string | null>(null);
  const [accounts, setAccounts] = useState<Array<{ id: string; email: string; color?: string }>>([]);
  const [unreadCount, setUnreadCount] = useState<number>(0);
  const [accountErrors, setAccountErrors] = useState<Record<string, string>>({});
  
  // Create a map for quick account lookup by ID (recalculated when accounts change)
  const accountMap = useMemo(() => {
    return new Map(accounts.map(acc => [acc.id, acc]));
  }, [accounts]);

  useEffect(() => {
    if (status === 'authenticated') {
      loadAccounts();
    }
  }, [status]);

  useEffect(() => {
    if (accounts.length > 0 && status === 'authenticated') {
      fetchEmails(false);
      fetchUnreadCount();
    }
  }, [accounts, status]);

  const loadAccounts = async () => {
    try {
      const response = await fetch('/api/courrier/accounts');
      if (response.ok) {
        const data = await response.json();
        if (data.accounts) {
          const loadedAccounts = data.accounts.map((acc: any) => {
            // If no color is set, generate a consistent color based on account ID
            let accountColor = acc.color;
            if (!accountColor && acc.id) {
              // Generate a color hash from accountId
              let hash = 0;
              for (let i = 0; i < acc.id.length; i++) {
                hash = acc.id.charCodeAt(i) + ((hash << 5) - hash);
              }
              const hue = Math.abs(hash % 360);
              accountColor = `hsl(${hue}, 70%, 50%)`;
            }
            
            return {
              id: acc.id || acc.email,
              email: acc.email,
              color: accountColor || '#0082c9' // Fallback default color
            };
          });
          console.log('[Email Widget] Loaded accounts with colors:', loadedAccounts.map(acc => ({
            id: acc.id,
            email: acc.email,
            color: acc.color
          })));
          setAccounts(loadedAccounts);
        }
      }
    } catch (err) {
      console.error('Error loading accounts:', err);
    }
  };

  const fetchEmails = async (forceRefresh = false) => {
    // Only show loading spinner on initial load, not on auto-refresh
    if (!emails.length) {
      setLoading(true);
    }
    setRefreshing(true);
    setError(null);
    setAccountErrors({});

    try {
      // Fetch emails from all accounts in parallel
      const emailPromises = accounts.map(async (account) => {
        try {
          const url = `/api/courrier?folder=INBOX&page=1&perPage=33&accountId=${encodeURIComponent(account.id)}${forceRefresh ? '&refresh=true' : ''}`;
          const response = await fetch(url);
          if (!response.ok) {
            const errorMsg = `Failed to fetch emails for ${account.email}`;
            console.warn(errorMsg);
            setAccountErrors(prev => ({ ...prev, [account.id]: errorMsg }));
            return [];
          }
          const data = await response.json();
          if (data.error || !data.emails) {
            const errorMsg = data.error || `No emails returned for ${account.email}`;
            setAccountErrors(prev => ({ ...prev, [account.id]: errorMsg }));
            return [];
          }
          // Add accountId to each email for proper identification
          return data.emails.map((email: any) => ({
            ...email,
            accountId: account.id,
            _accountEmail: account.email // Debug: store account email for verification
          }));
        } catch (err) {
          const errorMsg = `Error fetching emails for ${account.email}: ${err instanceof Error ? err.message : 'Unknown error'}`;
          console.error(errorMsg, err);
          setAccountErrors(prev => ({ ...prev, [account.id]: errorMsg }));
          return [];
        }
      });

      const allEmailsArrays = await Promise.allSettled(emailPromises);
      const allEmails = allEmailsArrays
        .filter((result): result is PromiseFulfilledResult<any[]> => result.status === 'fulfilled')
        .flatMap(result => result.value);
      
      // Transform and sort all emails
      const transformedEmails = allEmails
        .map((email: any) => ({
          id: email.id,
          subject: email.subject,
          from: email.from[0]?.address || '',
          fromName: email.from[0]?.name || '',
          date: email.date,
          read: email.flags.seen,
          starred: email.flags.flagged,
          folder: email.folder,
          accountId: email.accountId,
          _accountEmail: email._accountEmail // Keep for debugging
        }))
        // Sort emails by date (most recent first)
        .sort((a: Email, b: Email) => new Date(b.date).getTime() - new Date(a.date).getTime())
        .slice(0, 33); // Show up to 33 emails
      
      console.log('[Email Widget] Transformed emails with accountIds:', transformedEmails.map(e => ({
        id: e.id,
        subject: e.subject,
        accountId: (e as any).accountId,
        accountEmail: (e as any)._accountEmail
      })));
      
      setEmails(transformedEmails);
      setMailUrl('/courrier');

      // Show error only if all accounts failed
      if (allEmails.length === 0 && accounts.length > 0 && Object.keys(accountErrors).length === accounts.length) {
        setError('Failed to load emails from all accounts');
      }
    } catch (error) {
      console.error('Error fetching emails:', error);
      setError(error instanceof Error ? error.message : 'Failed to load emails');
      setEmails([]);
    } finally {
      setLoading(false);
      setRefreshing(false);
    }
  };

  const fetchUnreadCount = async () => {
    try {
      const response = await fetch('/api/courrier/unread-counts');
      if (response.ok) {
        const data = await response.json();
        if (data && typeof data === 'object') {
          // Sum up unread counts from all accounts and folders
          let totalUnread = 0;
          Object.values(data).forEach((accountCounts: any) => {
            if (typeof accountCounts === 'object') {
              Object.values(accountCounts).forEach((count: any) => {
                if (typeof count === 'number') {
                  totalUnread += count;
                }
              });
            }
          });
          setUnreadCount(totalUnread);
        }
      }
    } catch (err) {
      console.error('Error fetching unread count:', err);
      // Don't set error state for unread count failures
    }
  };

  // Integrate unified refresh for automatic polling
  const { refresh } = useUnifiedRefresh({
    resource: 'email',
    interval: REFRESH_INTERVALS.EMAIL, // 1 minute
    enabled: status === 'authenticated',
    onRefresh: async () => {
      await fetchEmails(false); // Use cache for auto-refresh
      await fetchUnreadCount();
    },
    priority: 'medium',
  });

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

  const formatDate = (dateString: string) => {
    try {
      const date = new Date(dateString);
      return new Intl.DateTimeFormat('fr-FR', {
        month: 'short',
        day: 'numeric',
        hour: '2-digit',
        minute: '2-digit'
      }).format(date);
    } catch (e) {
      return '';
    }
  };

  return (
    <Card className="h-full">
      <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">
          <Mail className="h-5 w-5 text-gray-600" />
          Courrier
          {unreadCount > 0 && (
            <Badge variant="destructive" className="ml-1 text-xs">
              {unreadCount}
            </Badge>
          )}
        </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-4">
        {error ? (
          <div className="text-center py-4">
            <p className="text-red-500 text-sm mb-2">{error}</p>
            {Object.keys(accountErrors).length > 0 && (
              <div className="text-xs text-gray-500 space-y-1">
                {Object.entries(accountErrors).map(([accountId, errMsg]) => (
                  <p key={accountId}>{errMsg}</p>
                ))}
              </div>
            )}
          </div>
        ) : loading && emails.length === 0 ? (
          <div className="text-center py-6 flex flex-col items-center">
            <Loader2 className="h-6 w-6 animate-spin text-gray-400 mb-2" />
            <p className="text-gray-500">Chargement des emails...</p>
          </div>
        ) : emails.length === 0 ? (
          <div className="text-center py-6">
            <p className="text-gray-500">Aucun email</p>
          </div>
        ) : (
          <div className="space-y-3 max-h-[500px] overflow-y-auto pr-1 scrollbar-thin scrollbar-thumb-gray-200 scrollbar-track-transparent">
            {emails.map((email, index) => {
              // Find the account color for this email using the accountId
              const emailAccountId = (email as any).accountId;
              const account = emailAccountId ? accountMap.get(emailAccountId) : null;
              // Use account color, or generate a color based on accountId if not found
              let accountColor = account?.color || '#0082c9';
              
              // If no color is set, generate a consistent color based on accountId
              if (!account?.color && emailAccountId) {
                // Generate a color hash from accountId
                let hash = 0;
                for (let i = 0; i < emailAccountId.length; i++) {
                  hash = emailAccountId.charCodeAt(i) + ((hash << 5) - hash);
                }
                const hue = Math.abs(hash % 360);
                accountColor = `hsl(${hue}, 70%, 50%)`;
              }
              
              // Debug log for first few emails
              if (index < 3) {
                console.log('[Email Widget] Email account mapping', {
                  emailId: email.id,
                  emailAccountId,
                  accountFound: !!account,
                  accountEmail: account?.email,
                  accountColor: account?.color,
                  finalColor: accountColor,
                  allAccountIds: Array.from(accountMap.keys()),
                  allAccounts: Array.from(accountMap.values()).map(a => ({ id: a.id, email: a.email, color: a.color }))
                });
              }
              
              return (
                <div key={email.id} className="flex items-start gap-3 py-1 border-b border-gray-100 last:border-0">
                  <div className="pt-1 flex-shrink-0">
                    <div 
                      className="w-3 h-3 rounded-full border border-gray-300"
                      style={{ backgroundColor: accountColor }}
                      title={account?.email || (email as any)._accountEmail || `Account ID: ${emailAccountId || 'unknown'}`}
                    />
                  </div>
                  <div className="flex-1 min-w-0">
                    <div className="flex justify-between">
                      <p className="font-medium truncate" style={{maxWidth: '180px'}}>{email.fromName || email.from.split('@')[0]}</p>
                      <p className="text-xs text-gray-500">{formatDate(email.date)}</p>
                    </div>
                    <p className="text-sm text-gray-700 truncate">{email.subject}</p>
                  </div>
                </div>
              );
            })}
            
            {mailUrl && (
              <div className="pt-2">
                <Link href={mailUrl} className="text-sm text-blue-600 hover:text-blue-800">
                  Voir tous les emails →
                </Link>
              </div>
            )}
          </div>
        )}
      </CardContent>
    </Card>
  );
} 