/**
 * Mail page — folder tree + mail list + reading pane + compose.
 * Uses ResizablePanel for drag-to-resize columns.
 * Account selection is integrated into the folder tree (left pane).
 */

import React, { useState, useEffect, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
import { Card } from '@/components/ui/Card';
import { Button } from '@/components/ui/Button';
import { useToast } from '@/components/ui/Toast';
import { EmptyState } from '@/components/ui/EmptyState';
import { ResizablePanel } from '@/components/ui/ResizablePanel';
import { MailFolderTree } from '@/components/mail/MailFolderTree';
import { MailList } from '@/components/mail/MailList';
import { MailDetail } from '@/components/mail/MailDetail';
import { ComposeModal, type ComposeMode } from '@/components/mail/ComposeModal';
import { SharedMailboxSelector } from '@/components/mail/SharedMailboxSelector';
import { MailSearchBar } from '@/components/mail/MailSearchBar';
import { usePluginToolbarStore } from '@/store/pluginToolbarStore';
import {
  fetchAccounts,
  fetchFolders,
  fetchMails,
  getMail,
  sendMail,
  replyMail,
  forwardMail,
  updateFlags,
  createEventFromMail,
  downloadAttachment,
  fetchSignatures,
  searchMails,
  deleteMail,
  moveMail,
  saveDraft,
  updateDraft,
  type MailAccount,
  type MailFolder,
  type Mail,
  type MailSignature,
  type MailAttachment,
  type SendMailPayload,
  type ReplyPayload,
  type ForwardPayload,
  type CreateEventFromMailPayload,
  type MailDraftPayload,
} from '@/api/mail';

const PAGE_SIZE = 25;

export function MailPage() {
  const { t } = useTranslation();
  const toast = useToast();

  const [accounts, setAccounts] = useState<MailAccount[]>([]);
  const [selectedAccountId, setSelectedAccountId] = useState('');
  const [folders, setFolders] = useState<MailFolder[]>([]);
  const [selectedFolderId, setSelectedFolderId] = useState<string | null>(null);
  const [mails, setMails] = useState<Mail[]>([]);
  const [mailsTotal, setMailsTotal] = useState(0);
  const [mailsPage, setMailsPage] = useState(1);
  const [selectedMail, setSelectedMail] = useState<Mail | null>(null);
  const [loadingMail, setLoadingMail] = useState(false);
  const [loadingAccounts, setLoadingAccounts] = useState(true);
  const [loadingFolders, setLoadingFolders] = useState(false);
  const [loadingMails, setLoadingMails] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [signatures, setSignatures] = useState<MailSignature[]>([]);
  const [composeOpen, setComposeOpen] = useState(false);
  const [composeMode, setComposeMode] = useState<ComposeMode>('new');
  const [replyToMail, setReplyToMail] = useState<Mail | null>(null);
  const [forwardMailState, setForwardMailState] = useState<Mail | null>(null);
  const [draftMailState, setDraftMailState] = useState<Mail | null>(null);
  const [downloadingAttachmentId, setDownloadingAttachmentId] = useState<string | null>(null);
  const [searchQuery, setSearchQuery] = useState('');
  const [activeView, setActiveView] = useState<'folders' | 'list' | 'detail'>('folders');
  const [selectedMailIds, setSelectedMailIds] = useState<Set<string>>(new Set());
  const [showMoveDropdown, setShowMoveDropdown] = useState(false);
  const [sortBy, setSortBy] = useState<'date' | 'from' | 'subject'>('date');
  const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('desc');

  // Load accounts
  const loadAccounts = useCallback(async () => {
    setLoadingAccounts(true);
    try {
      const accs = await fetchAccounts();
      setAccounts(accs);
      if (accs.length > 0 && !selectedAccountId) {
        setSelectedAccountId(accs[0].id);
      }
    } catch (err) {
      const msg = err instanceof Error ? err.message : String(err);
      setError(msg);
    }
    setLoadingAccounts(false);
  }, [selectedAccountId]);

  // Load signatures
  const loadSignatures = useCallback(async () => {
    try {
      const sigs = await fetchSignatures();
      setSignatures(sigs);
    } catch {
      // non-critical
    }
  }, []);

  useEffect(() => {
    loadAccounts();
    loadSignatures();
  }, [loadAccounts, loadSignatures]);

  // Load folders for ALL accounts
  const loadAllFolders = useCallback(async () => {
    if (accounts.length === 0) return;
    setLoadingFolders(true);
    try {
      const allFolders: MailFolder[] = [];
      for (const acc of accounts) {
        const folderList = await fetchFolders(acc.id);
        allFolders.push(...folderList);
      }
      setFolders(allFolders);
    } catch (err) {
      const msg = err instanceof Error ? err.message : String(err);
      setError(msg);
    }
    setLoadingFolders(false);
  }, [accounts]);

  useEffect(() => {
    loadAllFolders();
  }, [loadAllFolders]);

  // Auto-select first folder when folders are loaded
  useEffect(() => {
    if (folders.length > 0 && !selectedFolderId) {
      setSelectedFolderId(folders[0].id);
      setSelectedAccountId(folders[0].account_id);
    }
  }, [folders, selectedFolderId]);

  // Load mails when folder or page changes
  const loadMails = useCallback(async () => {
    if (!selectedFolderId) return;
    setLoadingMails(true);
    try {
      if (searchQuery.trim()) {
        const result = await searchMails(searchQuery);
        setMails(result.mails);
        setMailsTotal(result.total);
      } else {
        const result = await fetchMails(selectedFolderId, mailsPage, sortBy, sortOrder);
        setMails(result.mails);
        setMailsTotal(result.total);
      }
    } catch (err) {
      const msg = err instanceof Error ? err.message : String(err);
      setError(msg);
      setMails([]);
    }
    setLoadingMails(false);
  }, [selectedFolderId, mailsPage, searchQuery, sortBy, sortOrder]);

  useEffect(() => {
    loadMails();
  }, [loadMails]);

  // Handle folder selection — derive account from folder
  const handleSelectFolder = useCallback(
    (folderId: string) => {
      setSelectedFolderId(folderId);
      const folder = folders.find((f) => f.id === folderId);
      if (folder) {
        setSelectedAccountId(folder.account_id);
      }
      setMailsPage(1);
      setSearchQuery('');
      setSelectedMail(null);
      setSelectedMailIds(new Set());
      setActiveView('list');
    },
    [folders],
  );

  // Handle mail selection
  const handleSelectMail = useCallback(
    async (mail: Mail) => {
      setActiveView('detail');
      setLoadingMail(true);
      try {
        const detail = await getMail(mail.id);
        setSelectedMail(detail);
        // Mark as seen if not seen
        if (!detail.is_seen) {
          await updateFlags(mail.id, { is_seen: true });
          setMails((prev) => prev.map((m) => (m.id === mail.id ? { ...m, is_seen: true } : m)));
        }
      } catch (err) {
        const msg = err instanceof Error ? err.message : String(err);
        toast.error(msg);
        setSelectedMail(mail);
      }
      setLoadingMail(false);
    },
    [toast],
  );

  // Handle compose
  const handleCompose = useCallback(() => {
    setComposeMode('new');
    setReplyToMail(null);
    setForwardMailState(null);
    setDraftMailState(null);
    setComposeOpen(true);
  }, []);

  // Handle reply
  const handleReply = useCallback((mail: Mail) => {
    setComposeMode('reply');
    setReplyToMail(mail);
    setForwardMailState(null);
    setDraftMailState(null);
    setComposeOpen(true);
  }, []);

  // Handle forward
  const handleForward = useCallback((mail: Mail) => {
    setComposeMode('forward');
    setForwardMailState(mail);
    setReplyToMail(null);
    setDraftMailState(null);
    setComposeOpen(true);
  }, []);

  // Handle delete single mail
  const handleDeleteMail = useCallback(
    async (mail: Mail) => {
      if (!window.confirm(t('mail.deleteConfirm'))) return;
      try {
        await deleteMail(mail.id);
        setMails((prev) => prev.filter((m) => m.id !== mail.id));
        setSelectedMail(null);
        toast.success(t('mail.delete'));
      } catch (err) {
        toast.error(err instanceof Error ? err.message : String(err));
      }
    },
    [toast, t],
  );

  // Handle bulk delete
  const handleBulkDelete = useCallback(async () => {
    if (!window.confirm(t('mail.bulkDeleteConfirm'))) return;
    const ids = Array.from(selectedMailIds);
    try {
      await Promise.all(ids.map((id) => deleteMail(id)));
      setMails((prev) => prev.filter((m) => !selectedMailIds.has(m.id)));
      setSelectedMailIds(new Set());
      setSelectedMail(null);
      toast.success(t('mail.delete'));
    } catch (err) {
      toast.error(err instanceof Error ? err.message : String(err));
    }
  }, [selectedMailIds, toast, t]);

  // Handle move single mail
  const handleMoveMail = useCallback(
    async (mail: Mail, targetFolderId: string) => {
      try {
        await moveMail(mail.id, targetFolderId);
        setMails((prev) => prev.filter((m) => m.id !== mail.id));
        setSelectedMail(null);
        setShowMoveDropdown(false);
        toast.success(t('mail.move'));
      } catch (err) {
        toast.error(err instanceof Error ? err.message : String(err));
      }
    },
    [toast, t],
  );

  // Handle bulk move
  const handleBulkMove = useCallback(
    async (targetFolderId: string) => {
      const ids = Array.from(selectedMailIds);
      try {
        await Promise.all(ids.map((id) => moveMail(id, targetFolderId)));
        setMails((prev) => prev.filter((m) => !selectedMailIds.has(m.id)));
        setSelectedMailIds(new Set());
        setShowMoveDropdown(false);
        toast.success(t('mail.move'));
      } catch (err) {
        toast.error(err instanceof Error ? err.message : String(err));
      }
    },
    [selectedMailIds, toast, t],
  );

  // Handle save draft (new or existing)
  const handleSaveDraft = useCallback(
    async (payload: MailDraftPayload) => {
      try {
        if (composeMode === 'draft' && draftMailState) {
          await updateDraft(draftMailState.id, payload);
        } else {
          await saveDraft(payload);
        }
        toast.success(t('mail.draftSaved'));
      } catch (err) {
        toast.error(err instanceof Error ? err.message : String(err));
        throw err;
      }
    },
    [composeMode, draftMailState, toast, t],
  );

  // Handle edit draft
  const handleEditDraft = useCallback((mail: Mail) => {
    setComposeMode('draft');
    setDraftMailState(mail);
    setReplyToMail(null);
    setForwardMailState(null);
    setComposeOpen(true);
  }, []);

  // Handle toggle flag
  const handleToggleFlag = useCallback(
    async (mail: Mail) => {
      try {
        await updateFlags(mail.id, { is_flagged: !mail.is_flagged });
        setSelectedMail((prev) => (prev ? { ...prev, is_flagged: !mail.is_flagged } : prev));
        setMails((prev) => prev.map((m) => (m.id === mail.id ? { ...m, is_flagged: !mail.is_flagged } : m)));
      } catch (err) {
        toast.error(err instanceof Error ? err.message : String(err));
      }
    },
    [toast],
  );

  // Handle toggle select for bulk operations
  const handleToggleSelect = useCallback((mailId: string) => {
    setSelectedMailIds((prev) => {
      const next = new Set(prev);
      if (next.has(mailId)) {
        next.delete(mailId);
      } else {
        next.add(mailId);
      }
      return next;
    });
  }, []);

  // Handle select all mails on current page
  const handleSelectAll = useCallback(() => {
    setSelectedMailIds((prev) => {
      const allSelected = mails.length > 0 && mails.every((m) => prev.has(m.id));
      if (allSelected) {
        // Deselect all on current page
        const next = new Set(prev);
        for (const m of mails) {
          next.delete(m.id);
        }
        return next;
      }
      // Select all on current page
      const next = new Set(prev);
      for (const m of mails) {
        next.add(m.id);
      }
      return next;
    });
  }, [mails]);

  // Handle bulk mark as read
  const handleBulkMarkRead = useCallback(async () => {
    const ids = Array.from(selectedMailIds);
    try {
      await Promise.all(ids.map((id) => updateFlags(id, { is_seen: true })));
      setMails((prev) => prev.map((m) => (selectedMailIds.has(m.id) ? { ...m, is_seen: true } : m)));
      setSelectedMailIds(new Set());
      toast.success(t('mail.markRead'));
    } catch (err) {
      toast.error(err instanceof Error ? err.message : String(err));
    }
  }, [selectedMailIds, toast, t]);

  // Handle bulk mark as unread
  const handleBulkMarkUnread = useCallback(async () => {
    const ids = Array.from(selectedMailIds);
    try {
      await Promise.all(ids.map((id) => updateFlags(id, { is_seen: false })));
      setMails((prev) => prev.map((m) => (selectedMailIds.has(m.id) ? { ...m, is_seen: false } : m)));
      setSelectedMailIds(new Set());
      toast.success(t('mail.markUnread'));
    } catch (err) {
      toast.error(err instanceof Error ? err.message : String(err));
    }
  }, [selectedMailIds, toast, t]);

  // Handle create event from mail
  const handleCreateEvent = useCallback(
    async (mail: Mail) => {
      const title = mail.subject || t('mail.noSubject');
      const now = new Date();
      const start = now.toISOString();
      const end = new Date(now.getTime() + 60 * 60 * 1000).toISOString();
      const payload: CreateEventFromMailPayload = {
        title,
        start,
        end,
        description: mail.body_text.slice(0, 500),
      };
      try {
        await createEventFromMail(mail.id, payload);
        toast.success(t('mail.eventCreated'));
      } catch (err) {
        toast.error(err instanceof Error ? err.message : String(err));
      }
    },
    [toast, t],
  );

  // Handle attachment download
  const handleDownloadAttachment = useCallback(
    async (mailId: string, attachment: MailAttachment) => {
      setDownloadingAttachmentId(attachment.id);
      try {
        const blob = await downloadAttachment(mailId, attachment.id);
        const url = window.URL.createObjectURL(blob);
        const a = window.document.createElement('a');
        a.href = url;
        a.download = attachment.filename;
        window.document.body.appendChild(a);
        a.click();
        window.document.body.removeChild(a);
        window.URL.revokeObjectURL(url);
      } catch (err) {
        toast.error(err instanceof Error ? err.message : String(err));
      } finally {
        setDownloadingAttachmentId(null);
      }
    },
    [toast],
  );

  // Handle send (compose)
  const handleSend = useCallback(
    async (payload: SendMailPayload | ReplyPayload | ForwardPayload, mode: ComposeMode) => {
      try {
        if (mode === 'reply' && replyToMail) {
          await replyMail(replyToMail.id, payload as ReplyPayload);
        } else if (mode === 'forward' && forwardMailState) {
          await forwardMail(forwardMailState.id, payload as ForwardPayload);
        } else {
          await sendMail(payload as SendMailPayload);
        }
        toast.success(t('mail.sent'));
      } catch (err) {
        toast.error(err instanceof Error ? err.message : String(err));
        throw err;
      }
    },
    [replyToMail, forwardMailState, toast, t],
  );

  // Handle search
  const handleSearch = useCallback((query: string) => {
    setSearchQuery(query);
    setMailsPage(1);
  }, []);

  // Register toolbar items (account-select removed — account is now in folder tree)
  const registerItems = usePluginToolbarStore((s) => s.registerItems);
  const unregisterPlugin = usePluginToolbarStore((s) => s.unregisterPlugin);
  const selectedMailId = selectedMail?.id;
  const selectedMailFlagged = selectedMail?.is_flagged;
  useEffect(() => {
    const hasMail = !!selectedMailId;
    const hasBulkSelection = selectedMailIds.size > 0;
    const items = [
      {
        id: 'search',
        plugin: 'mail',
        label: 'Suchen',
        type: 'search' as const,
        group: 'search',
        searchPlaceholder: 'E-Mails durchsuchen...',
        onSearch: handleSearch,
        onClick: () => {},
      },
      {
        id: 'compose',
        plugin: 'mail',
        label: 'Verfassen',
        group: 'compose',
        icon: (
          <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" />
          </svg>
        ),
        onClick: handleCompose,
      },
      {
        id: 'reply',
        plugin: 'mail',
        label: 'Antworten',
        group: 'mail-actions',
        disabled: !hasMail,
        icon: (
          <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" />
          </svg>
        ),
        onClick: () => selectedMail && handleReply(selectedMail),
      },
      {
        id: 'forward',
        plugin: 'mail',
        label: 'Weiterleiten',
        group: 'mail-actions',
        disabled: !hasMail,
        icon: (
          <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 10H11a8 8 0 00-8 8v2m18-10l-6 6m6-6l-6-6" />
          </svg>
        ),
        onClick: () => selectedMail && handleForward(selectedMail),
      },
      {
        id: 'flag',
        plugin: 'mail',
        label: 'Flagge',
        group: 'mail-actions',
        disabled: !hasMail,
        active: selectedMailFlagged,
        icon: (
          <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 21v-4m0 0V5a2 2 0 012-2h6.5l1 1H21l-3 6 3 6h-8.5l-1-1H5a2 2 0 00-2 2zm9-13.5V9" />
          </svg>
        ),
        onClick: () => selectedMail && handleToggleFlag(selectedMail),
      },
      {
        id: 'create-event',
        plugin: 'mail',
        label: 'Termin',
        group: 'mail-actions',
        disabled: !hasMail,
        icon: (
          <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
          </svg>
        ),
        onClick: () => selectedMail && handleCreateEvent(selectedMail),
      },
      {
        id: 'delete',
        plugin: 'mail',
        label: t('mail.delete'),
        group: 'mail-actions',
        disabled: !hasMail,
        icon: (
          <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
          </svg>
        ),
        onClick: () => selectedMail && handleDeleteMail(selectedMail),
      },
      {
        id: 'move',
        plugin: 'mail',
        label: t('mail.move'),
        group: 'mail-actions',
        disabled: !hasMail,
        icon: (
          <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 8l4 4m0 0l-4 4m4-4H3" />
          </svg>
        ),
        onClick: () => setShowMoveDropdown((v) => !v),
      },
      {
        id: 'sync',
        plugin: 'mail',
        label: 'Sync',
        group: 'tools',
        icon: (
          <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
          </svg>
        ),
        onClick: () => { /* sync trigger */ },
      },
    ];
    if (hasBulkSelection) {
      items.push(
        {
          id: 'bulk-mark-read',
          plugin: 'mail',
          label: t('mail.markRead'),
          group: 'bulk-actions',
          icon: (
            <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
            </svg>
          ),
          onClick: handleBulkMarkRead,
        },
        {
          id: 'bulk-mark-unread',
          plugin: 'mail',
          label: t('mail.markUnread'),
          group: 'bulk-actions',
          icon: (
            <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 19l6-6 4 4 8-8" />
            </svg>
          ),
          onClick: handleBulkMarkUnread,
        },
        {
          id: 'bulk-delete',
          plugin: 'mail',
          label: t('mail.bulkDelete'),
          group: 'bulk-actions',
          icon: (
            <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
            </svg>
          ),
          onClick: handleBulkDelete,
        },
        {
          id: 'bulk-move',
          plugin: 'mail',
          label: t('mail.bulkMove'),
          group: 'bulk-actions',
          icon: (
            <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 8l4 4m0 0l-4 4m4-4H3" />
            </svg>
          ),
          onClick: () => setShowMoveDropdown((v) => !v),
        },
      );
    }
    registerItems('mail', items);
    return () => unregisterPlugin('mail');
  }, [selectedMailId, selectedMailFlagged, selectedMailIds, handleSearch, handleCompose, handleReply, handleForward, handleToggleFlag, handleCreateEvent, handleDeleteMail, handleBulkDelete, handleBulkMarkRead, handleBulkMarkUnread, t]);

  if (loadingAccounts) {
    return (
      <div className="flex items-center justify-center py-12" data-testid="mail-page-loading">
        <svg className="animate-spin h-6 w-6 text-secondary-400" fill="none" viewBox="0 0 24 24" aria-hidden="true">
          <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
          <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
        </svg>
        <span className="ml-2 text-secondary-500">{t('common.loading')}</span>
      </div>
    );
  }

  if (accounts.length === 0) {
    return (
      <div className="p-6 max-w-7xl mx-auto" data-testid="mail-page">
        <EmptyState
          title={t('mail.noAccounts')}
          description={t('mail.noAccountsDesc')}
          action={<Link to="/settings/mail" className="text-primary-600 hover:text-primary-700">{t('mail.configureAccount')}</Link>}
        />
      </div>
    );
  }

  return (
    <div className="flex flex-col h-full" data-testid="mail-page">
      {error && (
        <div className="mb-2 p-3 bg-danger-50 border border-danger-200 rounded-md" role="alert" data-testid="mail-error">
          <p className="text-sm text-danger-700">{error}</p>
        </div>
      )}

      {/* Desktop: three-pane layout with resizable panels */}
      <div className="hidden md:flex flex-1 overflow-hidden">
        {/* Folder tree — resizable */}
        <ResizablePanel
          initialWidth={224}
          minWidth={150}
          maxWidth={400}
          className="border-r border-secondary-200 bg-white"
          data-testid="mail-folder-pane"
        >
          <div className="p-3">
            <MailFolderTree
              accounts={accounts}
              folders={folders}
              selectedFolderId={selectedFolderId}
              onSelect={handleSelectFolder}
              loading={loadingFolders}
            />
          </div>
        </ResizablePanel>

        {/* Mail list — resizable */}
        <ResizablePanel
          initialWidth={320}
          minWidth={200}
          maxWidth={500}
          className="border-r border-secondary-200 bg-white"
          data-testid="mail-list-pane"
        >
          <MailList
            mails={mails}
            selectedMailId={selectedMail?.id || null}
            onSelectMail={handleSelectMail}
            loading={loadingMails}
            currentPage={mailsPage}
            total={mailsTotal}
            pageSize={PAGE_SIZE}
            onPageChange={setMailsPage}
            selectedMailIds={selectedMailIds}
            onToggleSelect={handleToggleSelect}
            onSelectAll={handleSelectAll}
            sortBy={sortBy}
            sortOrder={sortOrder}
            onSortChange={(by, order) => {
              setSortBy(by);
              setSortOrder(order);
              setMailsPage(1);
            }}
          />
        </ResizablePanel>

        {/* Reading pane — flex-1, not resizable */}
        <ResizablePanel
          resizable={false}
          className="bg-white"
          data-testid="mail-detail-pane"
        >
          <MailDetail
            mail={selectedMail}
            loading={loadingMail}
            onReply={handleReply}
            onForward={handleForward}
            onCreateEvent={handleCreateEvent}
            onToggleFlag={handleToggleFlag}
            onDownloadAttachment={handleDownloadAttachment}
            downloadingAttachmentId={downloadingAttachmentId}
            onDelete={handleDeleteMail}
            onMove={(mail) => setShowMoveDropdown(true)}
            onEditDraft={handleEditDraft}
          />
        </ResizablePanel>
      </div>

      {/* Mobile: single-pane view switching */}
      <div className="flex md:hidden flex-1 overflow-hidden flex-col">
        {/* View 1: Folder tree */}
        {activeView === 'folders' && (
          <div className="flex-1 overflow-y-auto bg-white" data-testid="mobile-folder-pane">
            <div className="p-3">
              <MailFolderTree
                accounts={accounts}
                folders={folders}
                selectedFolderId={selectedFolderId}
                onSelect={handleSelectFolder}
                loading={loadingFolders}
              />
            </div>
          </div>
        )}

        {/* View 2: Mail list */}
        {activeView === 'list' && (
          <div className="flex-1 overflow-y-auto bg-white" data-testid="mobile-list-pane">
            <div className="flex items-center gap-2 px-3 py-2 border-b border-secondary-200 sticky top-0 bg-white z-10">
              <button
                onClick={() => setActiveView('folders')}
                className="inline-flex items-center gap-1 px-2 py-1 rounded text-sm text-secondary-700 hover:bg-secondary-100 min-h-touch"
                aria-label="Zurück zu Ordnern"
                data-testid="mobile-back-to-folders"
              >
                <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
                </svg>
                <span className="text-sm font-medium">Ordner</span>
              </button>
            </div>
            <MailList
              mails={mails}
              selectedMailId={selectedMail?.id || null}
              onSelectMail={handleSelectMail}
              loading={loadingMails}
              currentPage={mailsPage}
              total={mailsTotal}
              pageSize={PAGE_SIZE}
              onPageChange={setMailsPage}
              selectedMailIds={selectedMailIds}
              onToggleSelect={handleToggleSelect}
              onSelectAll={handleSelectAll}
              sortBy={sortBy}
              sortOrder={sortOrder}
              onSortChange={(by, order) => {
                setSortBy(by);
                setSortOrder(order);
                setMailsPage(1);
              }}
            />
          </div>
        )}

        {/* View 3: Mail detail */}
        {activeView === 'detail' && (
          <div className="flex-1 overflow-y-auto bg-white" data-testid="mobile-detail-pane">
            <div className="flex items-center gap-2 px-3 py-2 border-b border-secondary-200 sticky top-0 bg-white z-10">
              <button
                onClick={() => setActiveView('list')}
                className="inline-flex items-center gap-1 px-2 py-1 rounded text-sm text-secondary-700 hover:bg-secondary-100 min-h-touch"
                aria-label="Zurück zur Liste"
                data-testid="mobile-back-to-list"
              >
                <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
                </svg>
                <span className="text-sm font-medium">Zurück</span>
              </button>
            </div>
            <MailDetail
              mail={selectedMail}
              loading={loadingMail}
              onReply={handleReply}
              onForward={handleForward}
              onCreateEvent={handleCreateEvent}
              onToggleFlag={handleToggleFlag}
              onDownloadAttachment={handleDownloadAttachment}
              downloadingAttachmentId={downloadingAttachmentId}
              onDelete={handleDeleteMail}
              onMove={(mail) => setShowMoveDropdown(true)}
              onEditDraft={handleEditDraft}
            />
          </div>
        )}
      </div>

      {/* Floating bulk action bar */}
      {selectedMailIds.size > 0 && (
        <div
          className="fixed bottom-4 left-1/2 -translate-x-1/2 z-50 flex items-center gap-2 px-4 py-2 bg-white border border-secondary-200 rounded-lg shadow-lg"
          data-testid="mail-bulk-action-bar"
        >
          <span className="text-sm text-secondary-600">
            {t('mail.selectedCount', { count: selectedMailIds.size })}
          </span>
          <div className="w-px h-5 bg-secondary-200" />
          <Button variant="secondary" size="sm" onClick={handleBulkMarkRead}>
            {t('mail.markRead')}
          </Button>
          <Button variant="secondary" size="sm" onClick={handleBulkMarkUnread}>
            {t('mail.markUnread')}
          </Button>
          <Button variant="danger" size="sm" onClick={handleBulkDelete}>
            {t('mail.bulkDelete')}
          </Button>
          <div className="relative">
            <Button variant="secondary" size="sm" onClick={() => setShowMoveDropdown((v) => !v)}>
              {t('mail.bulkMove')}
            </Button>
            {showMoveDropdown && (
              <div className="absolute bottom-full mb-2 left-0 bg-white border border-secondary-200 rounded-lg shadow-lg max-h-60 overflow-y-auto min-w-48">
                {folders.map((folder) => (
                  <button
                    key={folder.id}
                    onClick={() => handleBulkMove(folder.id)}
                    className="block w-full text-left px-3 py-2 text-sm hover:bg-secondary-100 min-h-touch"
                  >
                    {folder.name}
                  </button>
                ))}
              </div>
            )}
          </div>
          <Button variant="ghost" size="sm" onClick={() => setSelectedMailIds(new Set())}>
            ✕
          </Button>
        </div>
      )}

      {/* Move dropdown for single mail */}
      {showMoveDropdown && selectedMail && selectedMailIds.size === 0 && (
        <div
          className="fixed bottom-4 right-4 z-50 bg-white border border-secondary-200 rounded-lg shadow-lg max-h-60 overflow-y-auto min-w-48"
          data-testid="mail-move-dropdown"
        >
          <div className="px-3 py-2 text-xs font-medium text-secondary-500 border-b border-secondary-100">
            {t('mail.moveTo')}
          </div>
          {folders
            .filter((f) => f.account_id === selectedMail.account_id)
            .map((folder) => (
              <button
                key={folder.id}
                onClick={() => handleMoveMail(selectedMail, folder.id)}
                className="block w-full text-left px-3 py-2 text-sm hover:bg-secondary-100 min-h-touch"
              >
                {folder.name}
              </button>
            ))}
        </div>
      )}

      <ComposeModal
        open={composeOpen}
        mode={composeMode}
        accountId={selectedAccountId}
        replyToMail={replyToMail}
        forwardMail={forwardMailState}
        draftMail={draftMailState}
        signatures={signatures}
        onSend={handleSend}
        onSaveDraft={handleSaveDraft}
        onClose={() => setComposeOpen(false)}
      />
    </div>
  );
}
