'use client';

import { useEffect, useState, useMemo, useCallback } from 'react';
import { useRouter } from 'next/navigation';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import { Checkbox } from '@/components/ui/checkbox';
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import { Avatar, AvatarFallback } from '@/components/ui/avatar';
import { 
  MoreVertical, Settings, Plus as PlusIcon, Trash2, Edit, Mail, 
  Inbox, Send, Star, Trash, Plus, ChevronLeft, ChevronRight, 
  Search, ChevronDown, Folder, ChevronUp, Reply, Forward, ReplyAll, 
  MoreHorizontal, FolderOpen, X, Paperclip, MessageSquare, Copy, EyeOff, 
  AlertOctagon, Archive, RefreshCw
} from 'lucide-react';
import { ScrollArea } from '@/components/ui/scroll-area';
import { MailList } from "@/components/mail/mail-list";
import { MailToolbar } from "@/components/mail/mail-toolbar";
import { useMail } from "@/hooks/use-mail";

interface Account {
  id: number;
  name: string;
  email: string;
  color: string;
  folders?: string[];
}

interface Email {
  id: number;
  accountId: number;
  from: string;
  fromName?: string;
  to: string;
  subject: string;
  body: string;
  date: string;
  read: boolean;
  starred: boolean;
  folder: string;
  cc?: string;
  bcc?: string;
  flags?: string[];
}

interface Attachment {
  name: string;
  type: string;
  content: string;
  encoding: string;
}

// Improved MIME Decoder Implementation for Infomaniak
function extractBoundary(headers: string): string | null {
  const boundaryMatch = headers.match(/boundary="?([^"\r\n;]+)"?/i) || 
                       headers.match(/boundary=([^\r\n;]+)/i);
  
  return boundaryMatch ? boundaryMatch[1].trim() : null;
}

function decodeQuotedPrintable(text: string, charset: string): string {
  if (!text) return '';
  
  // Replace soft line breaks (=\r\n or =\n or =\r)
  let decoded = text.replace(/=(?:\r\n|\n|\r)/g, '');
  
  // Replace quoted-printable encoded characters (including non-ASCII characters)
  decoded = decoded.replace(/=([0-9A-F]{2})/gi, (match, p1) => {
    return String.fromCharCode(parseInt(p1, 16));
  });
  
  // Handle character encoding
  try {
    // For browsers with TextDecoder support
    if (typeof TextDecoder !== 'undefined') {
      // Convert string to array of byte values
      const bytes = new Uint8Array(Array.from(decoded).map(c => c.charCodeAt(0)));
      return new TextDecoder(charset).decode(bytes);
    }
    
    // Fallback for older browsers or when charset handling is not critical
    return decoded;
  } catch (e) {
    console.warn('Charset conversion error:', e);
    return decoded;
  }
}

function parseFullEmail(emailRaw: string) {
  // Check if this is a multipart message by looking for boundary definition
  const boundaryMatch = emailRaw.match(/boundary="?([^"\r\n;]+)"?/i) || 
                       emailRaw.match(/boundary=([^\r\n;]+)/i);
  
  if (boundaryMatch) {
    const boundary = boundaryMatch[1].trim();
    
    // Check if there's a preamble before the first boundary
    let mainHeaders = '';
    let mainContent = emailRaw;
    
    // Extract the headers before the first boundary if they exist
    const firstBoundaryPos = emailRaw.indexOf('--' + boundary);
    if (firstBoundaryPos > 0) {
      const headerSeparatorPos = emailRaw.indexOf('\r\n\r\n');
      if (headerSeparatorPos > 0 && headerSeparatorPos < firstBoundaryPos) {
        mainHeaders = emailRaw.substring(0, headerSeparatorPos);
      }
    }
    
    return processMultipartEmail(emailRaw, boundary, mainHeaders);
  } else {
    // This is a single part message
    return processSinglePartEmail(emailRaw);
  }
}

function processMultipartEmail(emailRaw: string, boundary: string, mainHeaders: string = ''): { 
  text: string; 
  html: string; 
  attachments: { filename: string; contentType: string; encoding: string; content: string; }[];
  headers?: string;
} {
  const result = {
    text: '',
    html: '',
    attachments: [] as { filename: string; contentType: string; encoding: string; content: string; }[],
    headers: mainHeaders
  };
  
  // Split by boundary (more robust pattern)
  const boundaryRegex = new RegExp(`--${boundary}(?:--)?(\\r?\\n|$)`, 'g');
  
  // Get all boundary positions
  const matches = Array.from(emailRaw.matchAll(boundaryRegex));
  const boundaryPositions = matches.map(match => match.index!);
  
  // Extract content between boundaries
  for (let i = 0; i < boundaryPositions.length - 1; i++) {
    const startPos = boundaryPositions[i] + matches[i][0].length;
    const endPos = boundaryPositions[i + 1];
    
    if (endPos > startPos) {
      const partContent = emailRaw.substring(startPos, endPos).trim();
      
      if (partContent) {
        const decoded = processSinglePartEmail(partContent);
        
        if (decoded.contentType.includes('text/plain')) {
          result.text = decoded.text || '';
        } else if (decoded.contentType.includes('text/html')) {
          result.html = cleanHtml(decoded.html || '');
        } else if (
          decoded.contentType.startsWith('image/') || 
          decoded.contentType.startsWith('application/')
        ) {
          const filename = extractFilename(partContent);
          result.attachments.push({
            filename,
            contentType: decoded.contentType,
            encoding: decoded.raw?.headers ? parseEmailHeaders(decoded.raw.headers).encoding : '7bit',
            content: decoded.raw?.body || ''
          });
        }
      }
    }
  }
  
  return result;
}

function processSinglePartEmail(rawEmail: string) {
  // Split headers and body
  const headerBodySplit = rawEmail.split(/\r?\n\r?\n/);
  const headers = headerBodySplit[0];
  const body = headerBodySplit.slice(1).join('\n\n');
  
  // Parse headers to get content type, encoding, etc.
  const emailInfo = parseEmailHeaders(headers);
  
  // Decode the body based on its encoding
  const decodedBody = decodeMIME(body, emailInfo.encoding, emailInfo.charset);
  
  return {
    subject: extractHeader(headers, 'Subject'),
    from: extractHeader(headers, 'From'),
    to: extractHeader(headers, 'To'),
    date: extractHeader(headers, 'Date'),
    contentType: emailInfo.contentType,
    text: emailInfo.contentType.includes('html') ? null : decodedBody,
    html: emailInfo.contentType.includes('html') ? decodedBody : null,
    raw: {
      headers,
      body
    }
  };
}

function extractHeader(headers: string, headerName: string): string {
  const regex = new RegExp(`^${headerName}:\\s*(.+?)(?:\\r?\\n(?!\\s)|$)`, 'im');
  const match = headers.match(regex);
  return match ? match[1].trim() : '';
}

function extractFilename(headers: string): string {
  const filenameMatch = headers.match(/filename="?([^"\r\n;]+)"?/i);
  return filenameMatch ? filenameMatch[1].trim() : 'attachment';
}

function parseEmailHeaders(headers: string): { contentType: string; encoding: string; charset: string } {
  const result = {
    contentType: 'text/plain',
    encoding: '7bit',
    charset: 'utf-8'
  };
  
  // Extract content type and charset
  const contentTypeMatch = headers.match(/Content-Type:\s*([^;]+)(?:;\s*charset=([^;"\r\n]+)|(?:;\s*charset="([^"]+)"))?/i);
  if (contentTypeMatch) {
    result.contentType = contentTypeMatch[1].trim().toLowerCase();
    if (contentTypeMatch[2]) {
      result.charset = contentTypeMatch[2].trim().toLowerCase();
    } else if (contentTypeMatch[3]) {
      result.charset = contentTypeMatch[3].trim().toLowerCase();
    }
  }
  
  // Extract content transfer encoding
  const encodingMatch = headers.match(/Content-Transfer-Encoding:\s*([^\s;\r\n]+)/i);
  if (encodingMatch) {
    result.encoding = encodingMatch[1].trim().toLowerCase();
  }
  
  return result;
}

function decodeMIME(text: string, encoding?: string, charset: string = 'utf-8'): string {
  if (!text) return '';
  
  // Normalize encoding and charset
  encoding = (encoding || '').toLowerCase();
  charset = (charset || 'utf-8').toLowerCase();
  
  try {
    // Handle different encoding types
    if (encoding === 'quoted-printable') {
      return decodeQuotedPrintable(text, charset);
    } else if (encoding === 'base64') {
      return decodeBase64(text, charset);
    } else if (encoding === '7bit' || encoding === '8bit' || encoding === 'binary') {
      // For these encodings, we still need to handle the character set
      return convertCharset(text, charset);
    } else {
      // Unknown encoding, return as is but still handle charset
      return convertCharset(text, charset);
    }
  } catch (error) {
    console.error('Error decoding MIME:', error);
    return text;
  }
}

function decodeBase64(text: string, charset: string): string {
  const cleanText = text.replace(/\s/g, '');
  
  let binaryString;
  try {
    binaryString = atob(cleanText);
  } catch (e) {
    console.error('Base64 decoding error:', e);
    return text;
  }
  
  return convertCharset(binaryString, charset);
}

function convertCharset(text: string, fromCharset: string): string {
  try {
    if (typeof TextDecoder !== 'undefined') {
      const bytes = new Uint8Array(text.length);
      for (let i = 0; i < text.length; i++) {
        bytes[i] = text.charCodeAt(i) & 0xFF;
      }
      
      let normalizedCharset = fromCharset.toLowerCase();
      
      // Normalize charset names
      if (normalizedCharset === 'iso-8859-1' || normalizedCharset === 'latin1') {
        normalizedCharset = 'iso-8859-1';
      } else if (normalizedCharset === 'windows-1252' || normalizedCharset === 'cp1252') {
        normalizedCharset = 'windows-1252';
      }
      
      const decoder = new TextDecoder(normalizedCharset);
      return decoder.decode(bytes);
    }
    
    // Fallback for older browsers or unsupported charsets
    if (fromCharset.toLowerCase() === 'iso-8859-1' || fromCharset.toLowerCase() === 'windows-1252') {
      return text
        .replace(/\xC3\xA0/g, 'à')
        .replace(/\xC3\xA2/g, 'â')
        .replace(/\xC3\xA9/g, 'é')
        .replace(/\xC3\xA8/g, 'è')
        .replace(/\xC3\xAA/g, 'ê')
        .replace(/\xC3\xAB/g, 'ë')
        .replace(/\xC3\xB4/g, 'ô')
        .replace(/\xC3\xB9/g, 'ù')
        .replace(/\xC3\xBB/g, 'û')
        .replace(/\xC3\x80/g, 'À')
        .replace(/\xC3\x89/g, 'É')
        .replace(/\xC3\x87/g, 'Ç')
        // Clean up HTML entities
        .replace(/&Atilde;&sect;/g, 'ç')
        .replace(/&Atilde;&copy;/g, 'é')
        .replace(/&Atilde;&uml;/g, 'ë')
        .replace(/&Atilde;&ordf;/g, 'ª')
        .replace(/&Atilde;&laquo;/g, '«')
        .replace(/&Atilde;&raquo;/g, '»')
        .replace(/&nbsp;/g, ' ')
        .replace(/\xA0/g, ' ');
    }
    
    return text;
  } catch (e) {
    console.error('Character set conversion error:', e, 'charset:', fromCharset);
    return text;
  }
}

function extractHtmlBody(htmlContent: string): string {
  const bodyMatch = htmlContent.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
  return bodyMatch ? bodyMatch[1] : htmlContent;
}

function cleanHtml(html: string): string {
  if (!html) return '';
  
  return html
    // Fix common Infomaniak-specific character encodings
    .replace(/=C2=A0/g, ' ')  // non-breaking space
    .replace(/=E2=80=93/g, '\u2013')  // en dash
    .replace(/=E2=80=94/g, '\u2014')  // em dash
    .replace(/=E2=80=98/g, '\u2018')  // left single quote
    .replace(/=E2=80=99/g, '\u2019')  // right single quote
    .replace(/=E2=80=9C/g, '\u201C')  // left double quote
    .replace(/=E2=80=9D/g, '\u201D')  // right double quote
    .replace(/=C3=A0/g, 'à')
    .replace(/=C3=A2/g, 'â')
    .replace(/=C3=A9/g, 'é')
    .replace(/=C3=A8/g, 'è')
    .replace(/=C3=AA/g, 'ê')
    .replace(/=C3=AB/g, 'ë')
    .replace(/=C3=B4/g, 'ô')
    .replace(/=C3=B9/g, 'ù')
    .replace(/=C3=xBB/g, 'û')
    .replace(/=C3=80/g, 'À')
    .replace(/=C3=89/g, 'É')
    .replace(/=C3=87/g, 'Ç')
    // Clean up HTML entities
    .replace(/&Atilde;&sect;/g, 'ç')
    .replace(/&Atilde;&copy;/g, 'é')
    .replace(/&Atilde;&uml;/g, 'ë')
    .replace(/&Atilde;&ordf;/g, 'ª')
    .replace(/&Atilde;&laquo;/g, '«')
    .replace(/&Atilde;&raquo;/g, '»')
    .replace(/&nbsp;/g, ' ')
    .replace(/\xA0/g, ' ');
}

function decodeMimeContent(content: string): string {
  if (!content) return '';

  // Check if this is an Infomaniak multipart message
  if (content.includes('Content-Type: multipart/')) {
    const boundary = content.match(/boundary="([^"]+)"/)?.[1];
    if (boundary) {
      const parts = content.split('--' + boundary);
      let htmlContent = '';
      let textContent = '';

      parts.forEach(part => {
        if (part.includes('Content-Type: text/html')) {
          const match = part.match(/\r?\n\r?\n([\s\S]+?)(?=\r?\n--)/);
          if (match) {
            htmlContent = cleanHtml(match[1]);
          }
        } else if (part.includes('Content-Type: text/plain')) {
          const match = part.match(/\r?\n\r?\n([\s\S]+?)(?=\r?\n--)/);
          if (match) {
            textContent = cleanHtml(match[1]);
          }
        }
      });

      // Prefer HTML content if available
      return htmlContent || textContent;
    }
  }

  // If not multipart or no boundary found, clean the content directly
  return cleanHtml(content);
}

// Add this helper function
const renderEmailContent = (email: Email) => {
  const decodedContent = decodeMimeContent(email.body);
  if (email.body.includes('Content-Type: text/html')) {
    return <div dangerouslySetInnerHTML={{ __html: decodedContent }} />;
  }
  return <div className="whitespace-pre-wrap">{decodedContent}</div>;
};

// Add this helper function
const decodeEmailContent = (content: string, charset: string = 'utf-8') => {
  return convertCharset(content, charset);
};

function cleanEmailContent(content: string): string {
  // Remove or fix malformed URLs
  return content.replace(/=3D"(http[^"]+)"/g, (match, url) => {
    try {
      return `"${decodeURIComponent(url)}"`;
    } catch {
      return '';
    }
  });
}

// Define the exact folder names from IMAP
type MailFolder = string;

// Map IMAP folders to sidebar items with icons
const getFolderIcon = (folder: string) => {
  switch (folder.toLowerCase()) {
    case 'inbox':
      return Inbox;
    case 'sent':
      return Send;
    case 'drafts':
      return Edit;
    case 'trash':
      return Trash;
    case 'spam':
      return AlertOctagon;
    case 'archive':
    case 'archives':
      return Archive;
    default:
      return Folder;
  }
};

// Initial sidebar items - only INBOX
const initialSidebarItems = [
  {
    view: 'INBOX' as MailFolder,
    label: 'Inbox',
    icon: Inbox,
    folder: 'INBOX'
  }
];

export default function MailPage() {
  const router = useRouter();
  const { mails, isLoading, error, fetchMails } = useMail();
  const [loading, setLoading] = useState(true);
  const [accounts, setAccounts] = useState<Account[]>([
    { id: 0, name: 'All', email: '', color: 'bg-gray-500' },
    { id: 1, name: 'Mail', email: 'alma@governance-labs.org', color: 'bg-blue-500' }
  ]);
  const [selectedAccount, setSelectedAccount] = useState<Account | null>(null);
  const [currentView, setCurrentView] = useState<MailFolder>('INBOX');
  const [showCompose, setShowCompose] = useState(false);
  const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
  const [selectedEmails, setSelectedEmails] = useState<string[]>([]);
  const [showBulkActions, setShowBulkActions] = useState(false);
  const [showBcc, setShowBcc] = useState(false);
  const [emails, setEmails] = useState<Email[]>([]);
  const [composeSubject, setComposeSubject] = useState('');
  const [composeTo, setComposeTo] = useState('');
  const [composeCc, setComposeCc] = useState('');
  const [composeBcc, setComposeBcc] = useState('');
  const [composeBody, setComposeBody] = useState('');
  const [selectedEmail, setSelectedEmail] = useState<Email | null>(null);
  const [sidebarOpen, setSidebarOpen] = useState(true);
  const [foldersOpen, setFoldersOpen] = useState(true);
  const [showSettings, setShowSettings] = useState(false);
  const [searchQuery, setSearchQuery] = useState('');
  const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false);
  const [composeOpen, setComposeOpen] = useState(false);
  const [accountsDropdownOpen, setAccountsDropdownOpen] = useState(false);
  const [foldersDropdownOpen, setFoldersDropdownOpen] = useState(false);
  const [showAccountActions, setShowAccountActions] = useState<number | null>(null);
  const [showEmailActions, setShowEmailActions] = useState(false);
  const [deleteType, setDeleteType] = useState<'email' | 'emails' | 'account'>('email');
  const [itemToDelete, setItemToDelete] = useState<number | null>(null);
  const [showCc, setShowCc] = useState(false);
  const [contentLoading, setContentLoading] = useState(false);
  const [attachments, setAttachments] = useState<Attachment[]>([]);
  const [folders, setFolders] = useState<string[]>([]);
  const [unreadCount, setUnreadCount] = useState(0);
  const [availableFolders, setAvailableFolders] = useState<string[]>([]);
  const [sidebarItems, setSidebarItems] = useState(initialSidebarItems);
  const [page, setPage] = useState(1);
  const [hasMore, setHasMore] = useState(true);
  const [isLoadingMore, setIsLoadingMore] = useState(false);
  const emailsPerPage = 24;

  useEffect(() => {
    // Check if we have mail credentials
    const checkCredentials = async () => {
      try {
        const response = await fetch("/api/mail/login");
        if (!response.ok) {
          // No credentials found, redirect to login
          router.push("/mail/login");
          return;
        }
        // We have credentials, fetch mails
        fetchMails();
      } catch (err) {
        console.error("Error checking credentials:", err);
        router.push("/mail/login");
      }
    };

    checkCredentials();
  }, [router, fetchMails]);

  const handleRefresh = () => {
    fetchMails();
  };

  const handleCompose = () => {
    // TODO: Implement compose functionality
    console.log('Compose clicked');
  };

  const handleSearch = (query: string) => {
    // TODO: Implement search functionality
    console.log('Search:', query);
  };

  const handleMailClick = (mail: any) => {
    // TODO: Implement mail view functionality
    console.log('Mail clicked:', mail);
  };

  if (isLoading) {
    return (
      <div className="flex items-center justify-center h-screen">
        <p>Loading emails...</p>
      </div>
    );
  }

  if (error) {
    return (
      <div className="flex items-center justify-center h-screen">
        <p className="text-red-500">Error: {error}</p>
      </div>
    );
  }

  return (
    <div className="flex flex-col h-screen">
      <MailToolbar 
        onRefresh={handleRefresh}
        onCompose={handleCompose}
        onSearch={handleSearch}
      />
      <div className="flex-1 overflow-hidden">
        <MailList 
          mails={mails} 
          onMailClick={handleMailClick}
        />
      </div>
    </div>
  );
}