"use client";

import { Email, ThreadGroup } from "@/lib/jmap/types";
import { ThreadListItem } from "./thread-list-item";
import { EmailContextMenu } from "./email-context-menu";
import { cn } from "@/lib/utils";
import { Inbox, CheckSquare, Square, Trash2, Mail, MailOpen, Loader2 } from "lucide-react";
import { useState, useEffect, useRef, useCallback, useMemo } from "react";
import { Button } from "@/components/ui/button";
import { useEmailStore } from "@/stores/email-store";
import { useAuthStore } from "@/stores/auth-store";
import { groupEmailsByThread, sortThreadGroups } from "@/lib/thread-utils";
import { useContextMenu } from "@/hooks/use-context-menu";
import { useTranslations } from "next-intl";

interface EmailListProps {
  emails: Email[];
  selectedEmailId?: string;
  onEmailSelect?: (email: Email) => void;
  className?: string;
  isLoading?: boolean;
  // Mobile conversation view handler
  onOpenConversation?: (thread: ThreadGroup) => void;
  // Context menu actions
  onReply?: (email: Email) => void;
  onReplyAll?: (email: Email) => void;
  onForward?: (email: Email) => void;
  onMarkAsRead?: (email: Email, read: boolean) => void;
  onToggleStar?: (email: Email) => void;
  onDelete?: (email: Email) => void;
  onArchive?: (email: Email) => void;
  onSetColorTag?: (emailId: string, color: string | null) => void;
  onMoveToMailbox?: (emailId: string, mailboxId: string) => void;
  onMarkAsSpam?: (email: Email) => void;
  onUndoSpam?: (email: Email) => void;
}

export function EmailList({
  emails,
  selectedEmailId,
  onEmailSelect,
  className,
  isLoading = false,
  onOpenConversation,
  onReply,
  onReplyAll,
  onForward,
  onMarkAsRead,
  onToggleStar,
  onDelete,
  onArchive,
  onSetColorTag,
  onMarkAsSpam,
  onUndoSpam,
  onMoveToMailbox,
}: EmailListProps) {
  const t = useTranslations('email_list');
  const { client } = useAuthStore();
  const {
    selectedEmailIds,
    selectAllEmails,
    clearSelection,
    batchMarkAsRead,
    batchDelete,
    batchMoveToMailbox,
    batchMarkAsSpam,
    batchUndoSpam,
    loadMoreEmails,
    hasMoreEmails,
    isLoadingMore,
    totalEmails,
    mailboxes,
    selectedMailbox,
    expandedThreadIds,
    threadEmailsCache,
    isLoadingThread,
    toggleThreadExpansion,
    fetchThreadEmails,
  } = useEmailStore();

  // Group emails by thread
  const threadGroups = useMemo(() => {
    const groups = groupEmailsByThread(emails);
    return sortThreadGroups(groups);
  }, [emails]);

  // Context menu state
  const { contextMenu, openContextMenu, closeContextMenu, menuRef } = useContextMenu<Email>();

  const [isProcessing, setIsProcessing] = useState(false);
  const observerTarget = useRef<HTMLDivElement>(null);
  // Loading skeleton component - gentler, no pulsing
  const LoadingSkeleton = () => (
    <div className="animate-in fade-in duration-200">
      {[...Array(8)].map((_, i) => (
        <div key={i} className="border-b border-border px-4 py-4">
          <div className="flex items-start gap-3">
            <div className="w-10 h-10 bg-muted/50 rounded-full" />
            <div className="flex-1">
              <div className="flex items-center justify-between mb-2">
                <div className="h-4 bg-muted/50 rounded w-32" />
                <div className="h-3 bg-muted/50 rounded w-16" />
              </div>
              <div className="h-4 bg-muted/50 rounded w-3/4 mb-2" />
              <div className="h-3 bg-muted/50 rounded w-full" />
            </div>
          </div>
        </div>
      ))}
    </div>
  );

  const hasSelection = selectedEmailIds.size > 0;
  const allSelected = emails.length > 0 && emails.every(e => selectedEmailIds.has(e.id));

  const handleBatchMarkAsRead = async (read: boolean) => {
    if (!client || isProcessing) return;
    setIsProcessing(true);
    try {
      await batchMarkAsRead(client, read);
    } finally {
      setTimeout(() => setIsProcessing(false), 500); // Small delay for visual feedback
    }
  };

  const handleBatchDelete = async () => {
    if (!client || isProcessing || !confirm(`Delete ${selectedEmailIds.size} emails?`)) return;
    setIsProcessing(true);
    try {
      await batchDelete(client);
    } finally {
      setTimeout(() => setIsProcessing(false), 500);
    }
  };

  // Intersection observer for infinite scroll
  const handleLoadMore = useCallback(() => {
    if (client && hasMoreEmails && !isLoadingMore && !isLoading) {
      loadMoreEmails(client);
    }
  }, [client, hasMoreEmails, isLoadingMore, isLoading, loadMoreEmails]);

  // Handle thread expansion and fetch complete thread
  const handleToggleThreadExpansion = useCallback(async (threadId: string) => {
    const isExpanded = expandedThreadIds.has(threadId);

    if (!isExpanded && client) {
      // Expanding - fetch complete thread emails
      toggleThreadExpansion(threadId);
      await fetchThreadEmails(client, threadId);
    } else {
      // Collapsing - just toggle
      toggleThreadExpansion(threadId);
    }
  }, [client, expandedThreadIds, toggleThreadExpansion, fetchThreadEmails]);

  useEffect(() => {
    const observer = new IntersectionObserver(
      (entries) => {
        if (entries[0].isIntersecting) {
          handleLoadMore();
        }
      },
      { threshold: 0.1 }
    );

    const currentTarget = observerTarget.current;
    if (currentTarget) {
      observer.observe(currentTarget);
    }

    return () => {
      if (currentTarget) {
        observer.unobserve(currentTarget);
      }
    };
  }, [handleLoadMore]);

  return (
    <div className={cn("flex flex-col h-full", className)}>
      {/* Batch Actions Toolbar with smooth transition */}
      <div
        className={cn(
          "transition-all duration-300 ease-in-out overflow-hidden",
          hasSelection ? "max-h-16 opacity-100" : "max-h-0 opacity-0"
        )}
      >
        <div className="px-4 py-2 border-b bg-accent/30 border-border flex items-center justify-between">
          <div className="flex items-center gap-2 animate-in fade-in slide-in-from-left-3 duration-300">
            <span className="text-sm font-medium text-foreground">
              {selectedEmailIds.size} {selectedEmailIds.size === 1 ? 'email' : 'emails'} selected
            </span>
          </div>
          <div className="flex items-center gap-1 animate-in fade-in slide-in-from-right-3 duration-300">
            <Button
              variant="ghost"
              size="sm"
              onClick={() => handleBatchMarkAsRead(true)}
              title={t('batch_actions.mark_read')}
              disabled={isProcessing}
              className="hover:bg-accent transition-colors disabled:opacity-50"
            >
              {isProcessing ? (
                <Loader2 className="w-4 h-4 animate-spin" />
              ) : (
                <MailOpen className="w-4 h-4" />
              )}
            </Button>
            <Button
              variant="ghost"
              size="sm"
              onClick={() => handleBatchMarkAsRead(false)}
              title={t('batch_actions.mark_unread')}
              disabled={isProcessing}
              className="hover:bg-accent transition-colors disabled:opacity-50"
            >
              {isProcessing ? (
                <Loader2 className="w-4 h-4 animate-spin" />
              ) : (
                <Mail className="w-4 h-4" />
              )}
            </Button>
            <Button
              variant="ghost"
              size="sm"
              onClick={handleBatchDelete}
              title={t('batch_actions.delete')}
              disabled={isProcessing}
              className="text-red-600 dark:text-red-400 hover:bg-red-100/50 dark:hover:bg-red-950/30 transition-colors disabled:opacity-50"
            >
              {isProcessing ? (
                <Loader2 className="w-4 h-4 animate-spin" />
              ) : (
                <Trash2 className="w-4 h-4" />
              )}
            </Button>
            <div className="w-px h-6 bg-border mx-1" />
            <Button
              variant="ghost"
              size="sm"
              onClick={clearSelection}
              title={t('batch_actions.clear_selection')}
              disabled={isProcessing}
              className="text-muted-foreground hover:text-foreground transition-colors disabled:opacity-50"
            >
              Cancel
            </Button>
          </div>
        </div>
      </div>

      {/* List Header */}
      <div className="px-4 py-3 border-b bg-muted/50 border-border flex items-center justify-between">
        <div className="flex items-center gap-2">
          <button
            onClick={() => allSelected ? clearSelection() : selectAllEmails()}
            className={cn(
              "p-1 rounded transition-all duration-200",
              "hover:bg-muted hover:scale-110",
              "active:scale-95",
              allSelected && "text-primary"
            )}
            title={allSelected ? "Deselect all" : "Select all"}
          >
            {allSelected ? (
              <CheckSquare className="w-4 h-4 animate-in zoom-in-50 duration-200" />
            ) : (
              <Square className="w-4 h-4" />
            )}
          </button>
          <h2 className="text-sm font-medium text-foreground">
            {isLoading ? t('loading') : threadGroups.length > 0
              ? (totalEmails !== undefined && totalEmails > threadGroups.length
                  ? t('conversations_count', { count: threadGroups.length, total: totalEmails })
                  : hasMoreEmails
                    ? t('conversations_count_plus', { count: threadGroups.length })
                    : t('conversations_count_simple', { count: threadGroups.length }))
              : t('no_conversations')}
          </h2>
        </div>
      </div>

      {/* Email List */}
      <div className="flex-1 overflow-y-auto bg-background relative">
        {/* Loading overlay - shows on top of existing emails */}
        {isLoading && emails.length > 0 && (
          <div className="absolute inset-0 bg-background/50 z-10 flex items-center justify-center animate-in fade-in duration-150">
            <div className="flex items-center gap-2 text-sm text-muted-foreground bg-background/90 px-4 py-2 rounded-full shadow-sm border border-border">
              <Loader2 className="w-4 h-4 animate-spin" />
              <span>{t('loading')}</span>
            </div>
          </div>
        )}

        {/* Show skeleton only on initial load (no emails yet) */}
        {isLoading && emails.length === 0 ? (
          <LoadingSkeleton />
        ) : emails.length === 0 && !isLoading ? (
          <div className="flex flex-col items-center justify-center h-full py-12">
            <Inbox className="w-16 h-16 mb-4 text-muted-foreground/50" />
            <p className="text-base font-medium text-foreground">{t('no_emails')}</p>
            <p className="text-sm mt-1 text-muted-foreground">{t('no_emails_description')}</p>
          </div>
        ) : (
          <div className={cn("transition-opacity duration-200", isLoading && "opacity-50")}>
            {threadGroups.map((thread) => (
              <ThreadListItem
                key={thread.threadId}
                thread={thread}
                isExpanded={expandedThreadIds.has(thread.threadId)}
                selectedEmailId={selectedEmailId}
                isLoading={isLoadingThread === thread.threadId}
                expandedEmails={threadEmailsCache.get(thread.threadId)}
                onToggleExpand={() => handleToggleThreadExpansion(thread.threadId)}
                onEmailSelect={(email) => onEmailSelect?.(email)}
                onContextMenu={openContextMenu}
                onOpenConversation={onOpenConversation}
              />
            ))}

            {/* Intersection observer target for infinite scroll - always present */}
            <div ref={observerTarget} className="py-4 flex justify-center">
              {isLoadingMore && hasMoreEmails && (
                <div className="flex items-center gap-2 text-sm text-muted-foreground">
                  <Loader2 className="w-4 h-4 animate-spin" />
                  <span>{t('loading_more')}</span>
                </div>
              )}
              {!hasMoreEmails && emails.length > 0 && (
                <div className="text-sm text-muted-foreground border-t border-border pt-6">
                  {t('no_more_emails')}
                </div>
              )}
            </div>
          </div>
        )}
      </div>

      {/* Context Menu */}
      {contextMenu.data && (
        <EmailContextMenu
          email={contextMenu.data}
          position={contextMenu.position}
          isOpen={contextMenu.isOpen}
          onClose={closeContextMenu}
          menuRef={menuRef}
          mailboxes={mailboxes}
          selectedMailbox={selectedMailbox}
          currentMailboxRole={mailboxes.find(m => m.id === selectedMailbox)?.role}
          isMultiSelect={selectedEmailIds.has(contextMenu.data.id)}
          selectedCount={selectedEmailIds.size}
          // Single email actions
          onReply={() => onReply?.(contextMenu.data!)}
          onReplyAll={() => onReplyAll?.(contextMenu.data!)}
          onForward={() => onForward?.(contextMenu.data!)}
          onMarkAsRead={(read) => onMarkAsRead?.(contextMenu.data!, read)}
          onToggleStar={() => onToggleStar?.(contextMenu.data!)}
          onDelete={() => onDelete?.(contextMenu.data!)}
          onArchive={() => onArchive?.(contextMenu.data!)}
          onSetColorTag={(color) => onSetColorTag?.(contextMenu.data!.id, color)}
          onMoveToMailbox={(mailboxId) => onMoveToMailbox?.(contextMenu.data!.id, mailboxId)}
          onMarkAsSpam={() => onMarkAsSpam?.(contextMenu.data!)}
          onUndoSpam={() => onUndoSpam?.(contextMenu.data!)}
          // Batch actions
          onBatchMarkAsRead={(read) => client && batchMarkAsRead(client, read)}
          onBatchDelete={() => client && batchDelete(client)}
          onBatchMoveToMailbox={(mailboxId) => client && batchMoveToMailbox(client, mailboxId)}
          onBatchMarkAsSpam={async () => {
            if (client) {
              const emailIds = Array.from(selectedEmailIds);
              try {
                await batchMarkAsSpam(client, emailIds);
                const { toast } = await import('sonner');
                toast.success(
                  t('../email_viewer.spam.toast_batch', { count: emailIds.length })
                );
              } catch {
                const { toast } = await import('sonner');
                toast.error(t('../email_viewer.spam.error'));
              }
            }
          }}
          onBatchUndoSpam={async () => {
            if (client) {
              const emailIds = Array.from(selectedEmailIds);
              try {
                await batchUndoSpam(client, emailIds);
                const { toast } = await import('sonner');
                toast.success(
                  t('../email_viewer.spam.toast_not_spam_batch', { count: emailIds.length })
                );
              } catch {
                const { toast } = await import('sonner');
                toast.error(t('../email_viewer.spam.error_not_spam'));
              }
            }
          }}
        />
      )}
    </div>
  );
}