'use client';

import React, { useCallback, useEffect, useMemo, useState } from 'react';
import {
  AlertCircle,
  CalendarDays,
  CheckCircle2,
  Inbox,
  Loader2,
  Mail,
  MailOpen,
  RefreshCw,
  Save,
  Send,
  Settings2,
  Unplug,
} from 'lucide-react';

import {
  connectOutlook,
  disconnectOutlook,
  getOutlookEvents,
  getOutlookMessageDetail,
  getOutlookMessages,
  getOutlookOverview,
  getOutlookStatus,
  testOutlookConnection,
} from '@/lib/api';
import type {
  OutlookConnectionPayload,
  OutlookConnectionTestResult,
  OutlookEventListResponse,
  OutlookEventSummary,
  OutlookMessageDetail,
  OutlookMessageListResponse,
  OutlookMessageSummary,
  OutlookPageInfo,
  OutlookStatus,
} from '@/types';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Skeleton } from '@/components/ui/skeleton';
import { ScrollArea } from '@/components/ui/scroll-area';
import { Separator } from '@/components/ui/separator';
import { Switch } from '@/components/ui/switch';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import type { AppLocale } from '@/lib/i18n/core';
import { pickAppText } from '@/lib/i18n/core';
import { useAppI18n } from '@/lib/i18n/provider';
import { nextOutlookAutoLoadTarget, type OutlookAutoLoadView } from '@/lib/outlook-page-state';

type OutlookFormState = OutlookConnectionPayload;
type OutlookView = 'inbox' | 'sent' | 'calendar' | 'settings';
type OutlookMailboxView = 'inbox' | 'sent';

const MAILBOX_PAGE_SIZE = 20;
const CALENDAR_PAGE_SIZE = 100;

const EMPTY_FORM: OutlookFormState = {
  email: '',
  password: '',
  username: '',
  domain: '',
  service_endpoint: '',
  server: '',
  autodiscover: false,
  default_timezone: 'Asia/Shanghai',
};

function toFormState(status: OutlookStatus | null): OutlookFormState {
  const defaults = status?.defaults.fields;
  const saved = status?.saved;
  return {
    email: saved?.email || '',
    password: '',
    username: saved?.username || '',
    domain: saved?.domain || defaults?.domain || '',
    service_endpoint: saved?.service_endpoint || defaults?.service_endpoint || '',
    server: saved?.server || defaults?.server || '',
    autodiscover: saved?.autodiscover ?? defaults?.autodiscover ?? false,
    default_timezone: saved?.default_timezone || defaults?.default_timezone || 'Asia/Shanghai',
  };
}

function formatDateTime(value?: string | null, locale: AppLocale = 'zh-CN'): string {
  if (!value) return '-';
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return value;
  return new Intl.DateTimeFormat(locale, {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
  }).format(date);
}

function toLocalDateKey(date: Date): string {
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const day = String(date.getDate()).padStart(2, '0');
  return `${year}-${month}-${day}`;
}

function formatDateKey(value?: string | null): string | null {
  if (!value) return null;
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return null;
  return toLocalDateKey(date);
}

function formatDayLabel(value: Date, locale: AppLocale = 'zh-CN'): string {
  return new Intl.DateTimeFormat(locale, {
    month: '2-digit',
    day: '2-digit',
    weekday: 'short',
  }).format(value);
}

function formatTime(value?: string | null, locale: AppLocale = 'zh-CN'): string {
  if (!value) return '-';
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return value;
  return new Intl.DateTimeFormat(locale, {
    hour: '2-digit',
    minute: '2-digit',
  }).format(date);
}

function buildCalendarRange(anchorKey: string): { startTime: string; endTime: string } {
  const anchor = new Date(`${anchorKey}T00:00:00`);
  const start = Number.isNaN(anchor.getTime()) ? new Date() : anchor;
  start.setHours(0, 0, 0, 0);
  const end = new Date(start);
  end.setDate(end.getDate() + 7);
  return {
    startTime: start.toISOString(),
    endTime: end.toISOString(),
  };
}

function mailboxLabel(
  mailbox?:
    | {
        emailAddress?: {
          name?: string | null;
          address?: string | null;
        } | null;
      }
    | null
): string {
  const name = mailbox?.emailAddress?.name?.trim();
  const address = mailbox?.emailAddress?.address?.trim();
  if (name && address) return `${name} <${address}>`;
  return address || name || '-';
}

function statusVariant(connected: boolean): 'default' | 'secondary' {
  return connected ? 'default' : 'secondary';
}

function sanitizeEmailHtml(html: string): string {
  if (typeof window === 'undefined') return html;

  const parser = new DOMParser();
  const documentRef = parser.parseFromString(html, 'text/html');
  const blockedSelectors = [
    'script',
    'style',
    'iframe',
    'object',
    'embed',
    'form',
    'input',
    'button',
    'textarea',
    'select',
    'meta',
    'link',
    'base',
    'img',
  ];
  const removableFormattingAttrs = new Set([
    'style',
    'class',
    'id',
    'bgcolor',
    'color',
    'face',
    'width',
    'height',
    'cellpadding',
    'cellspacing',
    'align',
  ]);

  for (const selector of blockedSelectors) {
    documentRef.querySelectorAll(selector).forEach((node) => node.remove());
  }

  documentRef.querySelectorAll('*').forEach((element) => {
    for (const attr of Array.from(element.attributes)) {
      const name = attr.name.toLowerCase();
      const value = attr.value.trim();
      if (removableFormattingAttrs.has(name)) {
        element.removeAttribute(attr.name);
        continue;
      }
      if (name.startsWith('on')) {
        element.removeAttribute(attr.name);
        continue;
      }
      if (name === 'srcdoc') {
        element.removeAttribute(attr.name);
        continue;
      }
      if ((name === 'href' || name === 'src') && value) {
        const normalized = value.toLowerCase();
        if (
          normalized.startsWith('javascript:')
          || normalized.startsWith('data:')
          || normalized.startsWith('file:')
        ) {
          element.removeAttribute(attr.name);
        }
      }
    }

    if (element.tagName.toLowerCase() === 'a') {
      element.setAttribute('target', '_blank');
      element.setAttribute('rel', 'noreferrer noopener');
    }
  });

  return documentRef.body.innerHTML;
}

function buildEmailPreviewDocument(html: string, locale: AppLocale = 'zh-CN'): string {
  return `<!DOCTYPE html>
<html lang="${locale}">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style>
      :root {
        color-scheme: light;
      }
      * {
        box-sizing: border-box;
        max-width: 100%;
        word-break: break-word;
      }
      body {
        margin: 0;
        padding: 24px;
        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
        font-size: 14px;
        line-height: 1.75;
        color: #0f172a;
        background: #ffffff;
      }
      p, ul, ol, table, blockquote, pre {
        margin: 0 0 1em;
      }
      table {
        width: 100% !important;
        border-collapse: collapse;
      }
      td, th {
        border: 1px solid #e2e8f0;
        padding: 8px 10px;
        vertical-align: top;
      }
      a {
        color: #2563eb;
        text-decoration: underline;
      }
      blockquote {
        margin-left: 0;
        padding-left: 12px;
        border-left: 3px solid #cbd5e1;
        color: #475569;
      }
      pre {
        white-space: pre-wrap;
        border-radius: 12px;
        background: #f8fafc;
        padding: 12px;
      }
    </style>
  </head>
  <body>${sanitizeEmailHtml(html)}</body>
</html>`;
}

function renderPlainText(content: string): React.ReactNode[] {
  const urlPattern = /(https?:\/\/[^\s<]+|mailto:[^\s<]+)/gi;
  const lines = content.split(/\r?\n/);
  const nodes: React.ReactNode[] = [];

  lines.forEach((line, lineIndex) => {
    const parts = line.split(urlPattern);
    parts.forEach((part, partIndex) => {
      if (!part) return;
      if (urlPattern.test(part)) {
        nodes.push(
          <a
            key={`link-${lineIndex}-${partIndex}`}
            href={part}
            target="_blank"
            rel="noreferrer noopener"
            className="inline-block min-h-11 max-w-full break-all py-2 text-primary underline underline-offset-2"
          >
            {part}
          </a>
        );
      } else {
        nodes.push(<React.Fragment key={`text-${lineIndex}-${partIndex}`}>{part}</React.Fragment>);
      }
      urlPattern.lastIndex = 0;
    });
    if (lineIndex < lines.length - 1) {
      nodes.push(<br key={`br-${lineIndex}`} />);
    }
  });

  return nodes;
}

export default function OutlookPage() {
  const { locale } = useAppI18n();
  const t = useCallback((zh: string, en: string) => pickAppText(locale, zh, en), [locale]);
  const [status, setStatus] = useState<OutlookStatus | null>(null);
  const [form, setForm] = useState<OutlookFormState>(EMPTY_FORM);
  const [formDirty, setFormDirty] = useState(false);
  const [testResult, setTestResult] = useState<OutlookConnectionTestResult | null>(null);
  const [overview, setOverview] = useState<Awaited<ReturnType<typeof getOutlookOverview>> | null>(null);
  const [statusLoading, setStatusLoading] = useState(true);
  const [overviewLoading, setOverviewLoading] = useState(false);
  const [refreshing, setRefreshing] = useState(false);
  const [testing, setTesting] = useState(false);
  const [saving, setSaving] = useState(false);
  const [disconnecting, setDisconnecting] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [selectedMessageRef, setSelectedMessageRef] = useState<{
    id: string;
    changekey?: string | null;
  } | null>(null);
  const [selectedMessage, setSelectedMessage] = useState<OutlookMessageDetail | null>(null);
  const [messageLoading, setMessageLoading] = useState(false);
  const [selectedEvent, setSelectedEvent] = useState<OutlookEventSummary | null>(null);
  const [activeView, setActiveView] = useState<OutlookView>('settings');
  const [inboxPage, setInboxPage] = useState<OutlookMessageListResponse | null>(null);
  const [sentPage, setSentPage] = useState<OutlookMessageListResponse | null>(null);
  const [calendarPage, setCalendarPage] = useState<OutlookEventListResponse | null>(null);
  const [calendarAnchorKey, setCalendarAnchorKey] = useState<string>(toLocalDateKey(new Date()));
  const [mailboxLoading, setMailboxLoading] = useState<Record<OutlookMailboxView, boolean>>({
    inbox: false,
    sent: false,
  });
  const [calendarLoading, setCalendarLoading] = useState(false);
  const [autoLoadAttempted, setAutoLoadAttempted] = useState<Record<OutlookAutoLoadView, boolean>>({
    inbox: false,
    sent: false,
    calendar: false,
  });
  const formDirtyRef = React.useRef(formDirty);

  useEffect(() => {
    formDirtyRef.current = formDirty;
  }, [formDirty]);

  const applyStatus = useCallback((nextStatus: OutlookStatus, forceFormSync = false) => {
    setStatus(nextStatus);
    if (forceFormSync || !formDirtyRef.current) {
      setForm(toFormState(nextStatus));
      setFormDirty(false);
    }
  }, []);

  const loadOverview = useCallback(async (preserveExisting = false) => {
    setOverviewLoading(true);
    try {
      const nextOverview = await getOutlookOverview();
      setOverview(nextOverview);
      setError(null);
    } catch (err: any) {
      if (!preserveExisting) {
        setOverview(null);
      }
      setError(err.message || t('加载 Outlook 概览失败', 'Failed to load the Outlook overview'));
    } finally {
      setOverviewLoading(false);
    }
  }, [t]);

  const loadMailboxPage = useCallback(async (view: OutlookMailboxView, skip = 0) => {
    setAutoLoadAttempted((current) => ({ ...current, [view]: true }));
    setMailboxLoading((current) => ({ ...current, [view]: true }));
    try {
      const nextPage = await getOutlookMessages(view === 'inbox' ? 'inbox' : 'sentitems', {
        top: MAILBOX_PAGE_SIZE,
        skip,
      });
      if (view === 'inbox') {
        setInboxPage(nextPage);
      } else {
        setSentPage(nextPage);
      }
      setError(null);
    } catch (err: any) {
      setError(
        err.message
          || t(
            `加载${view === 'inbox' ? '收件箱' : '发件箱'}失败`,
            `Failed to load the ${view === 'inbox' ? 'inbox' : 'sent mailbox'}`
          )
      );
    } finally {
      setMailboxLoading((current) => ({ ...current, [view]: false }));
    }
  }, [t]);

  const loadCalendarPage = useCallback(async (anchorKey: string) => {
    setAutoLoadAttempted((current) => ({ ...current, calendar: true }));
    setCalendarLoading(true);
    try {
      const range = buildCalendarRange(anchorKey);
      const nextPage = await getOutlookEvents({
        ...range,
        top: CALENDAR_PAGE_SIZE,
        skip: 0,
      });
      setCalendarPage(nextPage);
      setError(null);
    } catch (err: any) {
      setError(err.message || t('加载日程失败', 'Failed to load calendar events'));
    } finally {
      setCalendarLoading(false);
    }
  }, [t]);

  const loadStatus = useCallback(async (
    background = false,
    options?: {
      forceFormSync?: boolean;
      preserveOverview?: boolean;
    }
  ) => {
    if (background) {
      setRefreshing(true);
    } else {
      setStatusLoading(true);
    }
    setError(null);
    try {
      const nextStatus = await getOutlookStatus();
      applyStatus(nextStatus, options?.forceFormSync);
      if (!background) {
        setStatusLoading(false);
      }
      if (!nextStatus.configured) {
        setOverview(null);
        setOverviewLoading(false);
      }
    } catch (err: any) {
      setError(err.message || t('加载 Outlook 集成状态失败', 'Failed to load Outlook integration status'));
      setOverviewLoading(false);
    } finally {
      if (background) {
        setRefreshing(false);
      } else {
        setStatusLoading(false);
      }
    }
  }, [applyStatus, loadOverview, t]);

  useEffect(() => {
    void loadStatus();
  }, [loadStatus]);

  useEffect(() => {
    if (!selectedMessageRef) {
      setSelectedMessage(null);
      return;
    }

    let cancelled = false;
    setMessageLoading(true);
    getOutlookMessageDetail(selectedMessageRef.id, selectedMessageRef.changekey)
      .then((message) => {
        if (!cancelled) {
          setSelectedMessage(message);
        }
      })
      .catch((err: any) => {
        if (!cancelled) {
          setError(err.message || t('加载邮件详情失败', 'Failed to load message details'));
        }
      })
      .finally(() => {
        if (!cancelled) {
          setMessageLoading(false);
        }
      });

    return () => {
      cancelled = true;
    };
  }, [selectedMessageRef, t]);

  const canTest = useMemo(
    () => Boolean(
      form.email.trim()
      && form.password
      && (form.autodiscover || (form.service_endpoint || '').trim() || (form.server || '').trim())
    ),
    [form.autodiscover, form.email, form.password, form.server, form.service_endpoint]
  );
  const isConfigured = Boolean(status?.configured);
  const isConnected = Boolean(status?.connected);
  const overviewWarnings = overview?.warnings || [];
  const testWarnings = testResult?.warnings || [];
  const statusPending = statusLoading && !status;
  const overviewPending = overviewLoading && !overview;
  const availableViews = useMemo(() => {
    if (!isConfigured) {
      return [
        {
          id: 'settings' as const,
          label: t('设置', 'Settings'),
          hint: t('配置 Outlook 连接', 'Configure the Outlook connection'),
          icon: Settings2,
        },
      ];
    }

    return [
      {
        id: 'inbox' as const,
        label: t('收件箱', 'Inbox'),
        hint: t('最近接收邮件', 'Recently received mail'),
        icon: Inbox,
      },
      {
        id: 'sent' as const,
        label: t('发件箱', 'Sent'),
        hint: t('最近发送记录', 'Recently sent messages'),
        icon: Send,
      },
      {
        id: 'calendar' as const,
        label: t('日程', 'Calendar'),
        hint: t('未来 7 天', 'Next 7 days'),
        icon: CalendarDays,
      },
      {
        id: 'settings' as const,
        label: t('设置', 'Settings'),
        hint: t('连接与状态', 'Connection and status'),
        icon: Settings2,
      },
    ];
  }, [isConfigured, t]);

  useEffect(() => {
    if (!availableViews.some((view) => view.id === activeView)) {
      setActiveView(availableViews[0].id);
    }
  }, [activeView, availableViews]);

  useEffect(() => {
    const target = nextOutlookAutoLoadTarget({
      isConfigured,
      activeView,
      loaded: {
        inbox: Boolean(inboxPage),
        sent: Boolean(sentPage),
        calendar: Boolean(calendarPage),
      },
      loading: {
        inbox: mailboxLoading.inbox,
        sent: mailboxLoading.sent,
        calendar: calendarLoading,
      },
      attempted: autoLoadAttempted,
    });
    if (target === 'inbox') {
      void loadMailboxPage('inbox', 0);
    } else if (target === 'sent') {
      void loadMailboxPage('sent', 0);
    } else if (target === 'calendar') {
      void loadCalendarPage(calendarAnchorKey);
    }
  }, [
    activeView,
    autoLoadAttempted,
    calendarAnchorKey,
    calendarLoading,
    calendarPage,
    inboxPage,
    isConfigured,
    loadCalendarPage,
    loadMailboxPage,
    mailboxLoading.inbox,
    mailboxLoading.sent,
    sentPage,
  ]);

  const updateField = <K extends keyof OutlookFormState>(key: K, value: OutlookFormState[K]) => {
    setFormDirty(true);
    setForm((current) => ({ ...current, [key]: value }));
  };

  const handleTest = async () => {
    setTesting(true);
    setError(null);
    try {
      const result = await testOutlookConnection(form);
      setTestResult(result);
    } catch (err: any) {
      setError(err.message || t('测试连接失败', 'Failed to test the connection'));
      setTestResult(null);
    } finally {
      setTesting(false);
    }
  };

  const handleConnect = async () => {
    setSaving(true);
    setError(null);
    try {
      await connectOutlook(form);
      setForm((current) => ({ ...current, password: '' }));
      setFormDirty(false);
      setTestResult(null);
      setInboxPage(null);
      setSentPage(null);
      setCalendarPage(null);
      setAutoLoadAttempted({ inbox: false, sent: false, calendar: false });
      setCalendarAnchorKey(toLocalDateKey(new Date()));
      await loadStatus(true, { forceFormSync: true });
      setActiveView('inbox');
    } catch (err: any) {
      setError(err.message || t('保存 Outlook 配置失败', 'Failed to save Outlook settings'));
    } finally {
      setSaving(false);
    }
  };

  const handleDisconnect = async () => {
    if (!window.confirm(t('确定断开 Outlook 连接吗？已保存的连接凭据会被移除。', 'Disconnect Outlook? Saved connection credentials will be removed.'))) {
      return;
    }
    setDisconnecting(true);
    setError(null);
    try {
      await disconnectOutlook();
      setOverview(null);
      setTestResult(null);
      setSelectedMessageRef(null);
      setSelectedEvent(null);
      setInboxPage(null);
      setSentPage(null);
      setCalendarPage(null);
      setAutoLoadAttempted({ inbox: false, sent: false, calendar: false });
      setCalendarAnchorKey(toLocalDateKey(new Date()));
      setActiveView('settings');
      setFormDirty(false);
      await loadStatus(true, { forceFormSync: true });
    } catch (err: any) {
      setError(err.message || t('断开 Outlook 连接失败', 'Failed to disconnect Outlook'));
    } finally {
      setDisconnecting(false);
    }
  };

  const refreshOverview = async () => {
    await loadStatus(true, { preserveOverview: true });
    await loadOverview(true);
    if (activeView === 'inbox') {
      await loadMailboxPage('inbox', inboxPage?.page.skip ?? 0);
    } else if (activeView === 'sent') {
      await loadMailboxPage('sent', sentPage?.page.skip ?? 0);
    } else if (activeView === 'calendar') {
      await loadCalendarPage(calendarAnchorKey);
    }
  };

  return (
    <div className="min-h-full">
      <div className="mx-auto max-w-7xl space-y-6 p-4 sm:p-6">
        <section className="rounded-2xl border bg-card px-4 py-4 shadow-sm">
          <div className="flex flex-col gap-3 xl:flex-row xl:items-center xl:justify-between">
            <div className="flex min-w-0 flex-wrap items-center gap-2 text-sm">
              <h1 className="mr-2 flex min-w-0 items-center gap-2 text-lg font-semibold text-foreground">
                <Mail className="h-5 w-5" />
                Outlook
              </h1>
              {statusPending ? (
                <>
                  <Skeleton className="h-6 w-20 rounded-full" />
                  <Skeleton className="h-6 w-24 rounded-full" />
                  <Skeleton className="h-6 w-14 rounded-full" />
                  <Skeleton className="h-4 w-40" />
                  <Skeleton className="h-4 w-28" />
                  <Skeleton className="h-4 w-36" />
                </>
              ) : (
                <>
                  <Badge variant={statusVariant(isConnected)}>
                    {isConnected ? t('已连通', 'Connected') : isConfigured ? t('已配置', 'Configured') : t('未配置', 'Not configured')}
                  </Badge>
                  <Badge variant={status?.mcp_registered ? 'default' : 'secondary'}>
                    {status?.mcp_registered ? t('MCP 已注册', 'MCP registered') : t('MCP 未注册', 'MCP not registered')}
                  </Badge>
                  <Badge variant="secondary">{status?.provider || 'ews'}</Badge>
                  <span className="min-w-0 break-all text-muted-foreground">{t('邮箱', 'Mailbox')} {overview?.mailbox || status?.saved?.email || '-'}</span>
                  <span className="min-w-0 break-all text-muted-foreground">{t('时区', 'Timezone')} {status?.saved?.default_timezone || overview?.timezone || form.default_timezone}</span>
                  <span className="min-w-0 break-words text-muted-foreground">
                    {t('最近刷新', 'Last refreshed')} {formatDateTime((overview?.meta?.last_overview_refresh_at || status?.meta?.last_overview_refresh_at) as string | undefined, locale)}
                  </span>
                </>
              )}
            </div>

            <div className="flex flex-wrap items-center gap-2">
              <Button variant="outline" size="sm" className="h-11" onClick={() => void refreshOverview()}>
                <RefreshCw className={`mr-2 h-4 w-4 ${refreshing ? 'animate-spin' : ''}`} />
                {t('刷新', 'Refresh')}
              </Button>
            </div>
          </div>
        </section>

        {error && (
          <Card className="border-destructive bg-destructive/5">
            <CardContent className="pt-6">
              <div className="flex items-start gap-3 text-sm text-destructive">
                <AlertCircle className="mt-0.5 h-4 w-4 shrink-0" />
                <span className="min-w-0 flex-1 break-all">{error}</span>
              </div>
            </CardContent>
          </Card>
        )}

        {!error && overviewWarnings.length > 0 && (
          <Card className="border-amber-300 bg-amber-50/70">
            <CardContent className="space-y-2 pt-6 text-sm text-amber-900">
              {overviewWarnings.map((warning, index) => (
                <div key={`${warning}-${index}`} className="flex items-start gap-3">
                  <AlertCircle className="mt-0.5 h-4 w-4 shrink-0" />
                  <span className="min-w-0 flex-1 break-all">{warning}</span>
                </div>
              ))}
            </CardContent>
          </Card>
        )}

        <Tabs value={activeView} onValueChange={(value) => setActiveView(value as OutlookView)} className="space-y-6">
          <TabsList
            className={`grid h-auto w-full gap-2 rounded-2xl border bg-muted/40 p-2 shadow-sm ${
              isConfigured ? 'grid-cols-2 lg:grid-cols-4' : 'max-w-xs grid-cols-1'
            }`}
          >
            {availableViews.map((view) => {
              const Icon = view.icon;
              return (
                <TabsTrigger
                  key={view.id}
                  value={view.id}
                  className="min-h-11 rounded-xl border border-transparent px-4 py-3 data-[state=active]:border-border data-[state=active]:shadow-sm"
                >
                  <div className="flex w-full items-center justify-between gap-3">
                    <div className="flex items-center gap-3">
                      <span className="flex h-9 w-9 items-center justify-center rounded-xl bg-muted text-muted-foreground">
                        <Icon className="h-4 w-4" />
                      </span>
                      <div className="text-left">
                        <p className="text-sm font-semibold">{view.label}</p>
                      </div>
                    </div>
                  </div>
                </TabsTrigger>
              );
            })}
          </TabsList>

          <TabsContent value="inbox" className="mt-0">
            <MessageCard
              title={t('收件箱', 'Inbox')}
              icon={<MailOpen className="h-4 w-4" />}
              items={inboxPage?.value || []}
              page={inboxPage?.page || null}
              loading={mailboxLoading.inbox || (activeView === 'inbox' && !inboxPage)}
              emptyLabel={t('还没有读取到收件箱邮件', 'No inbox messages have been loaded yet')}
              locale={locale}
              onOpen={(item) => setSelectedMessageRef(item.id ? { id: item.id, changekey: item.changekey } : null)}
              onRefresh={() => void loadMailboxPage('inbox', inboxPage?.page.skip ?? 0)}
              refreshing={mailboxLoading.inbox}
              onPreviousPage={() => void loadMailboxPage('inbox', Math.max(0, (inboxPage?.page.skip ?? 0) - MAILBOX_PAGE_SIZE))}
              onNextPage={() => {
                const nextSkip = inboxPage?.page.next_skip;
                if (typeof nextSkip === 'number') {
                  void loadMailboxPage('inbox', nextSkip);
                }
              }}
            />
          </TabsContent>

          <TabsContent value="sent" className="mt-0">
            <MessageCard
              title={t('发件箱', 'Sent')}
              icon={<Send className="h-4 w-4" />}
              items={sentPage?.value || []}
              page={sentPage?.page || null}
              loading={mailboxLoading.sent || (activeView === 'sent' && !sentPage)}
              emptyLabel={t('还没有读取到已发送邮件', 'No sent messages have been loaded yet')}
              locale={locale}
              onOpen={(item) => setSelectedMessageRef(item.id ? { id: item.id, changekey: item.changekey } : null)}
              onRefresh={() => void loadMailboxPage('sent', sentPage?.page.skip ?? 0)}
              refreshing={mailboxLoading.sent}
              onPreviousPage={() => void loadMailboxPage('sent', Math.max(0, (sentPage?.page.skip ?? 0) - MAILBOX_PAGE_SIZE))}
              onNextPage={() => {
                const nextSkip = sentPage?.page.next_skip;
                if (typeof nextSkip === 'number') {
                  void loadMailboxPage('sent', nextSkip);
                }
              }}
            />
          </TabsContent>

          <TabsContent value="calendar" className="mt-0">
            <EventCard
              items={calendarPage?.value || []}
              startDate={calendarAnchorKey}
              loading={calendarLoading || (activeView === 'calendar' && !calendarPage)}
              locale={locale}
              onOpen={(item) => setSelectedEvent(item)}
              onRefresh={() => void loadCalendarPage(calendarAnchorKey)}
              refreshing={calendarLoading}
              onPreviousWeek={() => {
                const next = new Date(`${calendarAnchorKey}T00:00:00`);
                next.setDate(next.getDate() - 7);
                setCalendarAnchorKey(toLocalDateKey(next));
                setCalendarPage(null);
              }}
              onNextWeek={() => {
                const next = new Date(`${calendarAnchorKey}T00:00:00`);
                next.setDate(next.getDate() + 7);
                setCalendarAnchorKey(toLocalDateKey(next));
                setCalendarPage(null);
              }}
              onCurrentWeek={() => {
                const nextKey = toLocalDateKey(new Date());
                setCalendarAnchorKey(nextKey);
                setCalendarPage(null);
              }}
            />
          </TabsContent>

          <TabsContent value="settings" className="mt-0">
            <div className="grid gap-6 xl:grid-cols-[1.08fr,0.92fr]">
              <Card className="rounded-[28px] shadow-sm">
                <CardHeader className="border-b pb-5">
                  <CardTitle className="text-xl text-foreground">{t('连接设置', 'Connection settings')}</CardTitle>
                </CardHeader>
                <CardContent className="space-y-5 pt-6">
                  <div className="grid gap-4 md:grid-cols-2">
                    <Field id="outlook-email" label={t('邮箱地址', 'Email address')} required>
                      <Input
                        id="outlook-email"
                        className="h-11"
                        value={form.email}
                        onChange={(event) => updateField('email', event.target.value)}
                        placeholder="you@boardware.com"
                      />
                    </Field>
                    <Field id="outlook-username" label={t('用户名', 'Username')}>
                      <Input
                        id="outlook-username"
                        className="h-11"
                        value={form.username}
                        onChange={(event) => updateField('username', event.target.value)}
                        placeholder={t('留空时默认取邮箱前缀', 'Leave blank to default to the email prefix')}
                      />
                    </Field>
                    <Field id="outlook-password" label={t('密码', 'Password')} required>
                      <Input
                        id="outlook-password"
                        className="h-11"
                        type="password"
                        value={form.password}
                        onChange={(event) => updateField('password', event.target.value)}
                        placeholder={t('请输入邮箱密码', 'Enter the mailbox password')}
                      />
                    </Field>
                    <Field id="outlook-domain" label={t('域', 'Domain')}>
                      <Input
                        id="outlook-domain"
                        className="h-11"
                        value={form.domain}
                        onChange={(event) => updateField('domain', event.target.value)}
                        placeholder="boardware.com.mo"
                      />
                    </Field>
                    <Field id="outlook-service-endpoint" label="EWS URL">
                      <Input
                        id="outlook-service-endpoint"
                        className="h-11"
                        value={form.service_endpoint}
                        onChange={(event) => updateField('service_endpoint', event.target.value)}
                        placeholder="https://mail.boardware.com.mo/EWS/Exchange.asmx"
                        disabled={form.autodiscover}
                      />
                    </Field>
                    <Field id="outlook-server" label="Server Host">
                      <Input
                        id="outlook-server"
                        className="h-11"
                        value={form.server}
                        onChange={(event) => updateField('server', event.target.value)}
                        placeholder="mail.boardware.com.mo"
                        disabled={form.autodiscover}
                      />
                    </Field>
                    <Field id="outlook-timezone" label={t('时区', 'Timezone')}>
                      <Input
                        id="outlook-timezone"
                        className="h-11"
                        value={form.default_timezone}
                        onChange={(event) => updateField('default_timezone', event.target.value)}
                        placeholder="Asia/Shanghai"
                      />
                    </Field>
                    <div className="rounded-2xl border border-dashed bg-muted/30 p-4">
                      <div className="flex items-center justify-between gap-3">
                        <div>
                          <Label htmlFor="autodiscover" className="text-sm font-medium">
                            Autodiscover
                          </Label>
                          <p className="mt-1 text-xs text-muted-foreground">
                            {t('开启后优先使用 Exchange 自动发现，不再强依赖手填 EWS URL。', 'When enabled, Exchange autodiscover is preferred so the EWS URL does not need to be entered manually.')}
                          </p>
                        </div>
                        <Switch
                          id="autodiscover"
                          checked={form.autodiscover}
                          onCheckedChange={(checked) => updateField('autodiscover', checked)}
                        />
                      </div>
                    </div>
                  </div>

                  <div className="flex flex-wrap justify-end gap-2">
                    <Button variant="outline" className="h-11" onClick={handleTest} disabled={!canTest || testing}>
                      {testing ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <CheckCircle2 className="mr-2 h-4 w-4" />}
                      {t('测试连接', 'Test connection')}
                    </Button>
                    <Button className="h-11" onClick={handleConnect} disabled={!canTest || saving}>
                      {saving ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <Save className="mr-2 h-4 w-4" />}
                      {t('保存并启用', 'Save and enable')}
                    </Button>
                    <Button
                      variant="outline"
                      className="h-11"
                      onClick={handleDisconnect}
                      disabled={!status?.configured || disconnecting}
                    >
                      {disconnecting ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <Unplug className="mr-2 h-4 w-4" />}
                      {t('断开连接', 'Disconnect')}
                    </Button>
                  </div>

                  {testResult && (
                    <div className="rounded-3xl border bg-muted/30 p-4 text-sm">
                      <div className="flex flex-wrap items-center gap-2">
                        <Badge variant="default">{t('测试成功', 'Test succeeded')}</Badge>
                        <span className="break-all text-muted-foreground">{testResult.mailbox}</span>
                        <span className="break-all text-muted-foreground">{t('用户名', 'Username')}: {testResult.resolved_username}</span>
                      </div>
                      <div className="mt-3 grid gap-3 md:grid-cols-3">
                        <MiniStat label={t('检测到文件夹', 'Detected folders')} value={String(testResult.sample.folders.length)} />
                        <MiniStat label={t('收件箱样本', 'Inbox samples')} value={String(testResult.sample.inbox.length)} />
                        <MiniStat label={t('日程样本', 'Calendar samples')} value={String(testResult.sample.events.length)} />
                      </div>
                      {testWarnings.length > 0 && (
                        <div className="mt-4 space-y-2 rounded-2xl border border-amber-300 bg-amber-50/80 p-3 text-amber-900">
                          {testWarnings.map((warning, index) => (
                            <div key={`${warning}-${index}`} className="flex items-start gap-2">
                              <AlertCircle className="mt-0.5 h-4 w-4 shrink-0" />
                              <span className="min-w-0 flex-1 break-all">{warning}</span>
                            </div>
                          ))}
                        </div>
                      )}
                    </div>
                  )}
                </CardContent>
              </Card>

              <Card className="rounded-[28px] shadow-sm">
                <CardHeader className="border-b pb-5">
                  <CardTitle className="text-xl text-foreground">{t('连接状态', 'Connection status')}</CardTitle>
                </CardHeader>
                <CardContent className="space-y-4 pt-6">
                  <div className="flex flex-wrap gap-2">
                    {statusPending ? (
                      <>
                        <Skeleton className="h-6 w-20 rounded-full" />
                        <Skeleton className="h-6 w-24 rounded-full" />
                        <Skeleton className="h-6 w-14 rounded-full" />
                      </>
                    ) : (
                      <>
                        <Badge variant={statusVariant(isConnected)}>
                          {isConnected ? t('已连通', 'Connected') : isConfigured ? t('已配置', 'Configured') : t('未配置', 'Not configured')}
                        </Badge>
                        <Badge variant={status?.mcp_registered ? 'default' : 'secondary'}>
                          {status?.mcp_registered ? t('MCP 已注册', 'MCP registered') : t('MCP 未注册', 'MCP not registered')}
                        </Badge>
                        <Badge variant="secondary">{status?.provider || 'ews'}</Badge>
                      </>
                    )}
                  </div>

                  <InfoRow label={t('邮箱', 'Email')} value={status?.saved?.email || '-'} loading={statusPending} />
                  <InfoRow label={t('用户名', 'Username')} value={status?.saved?.username || '-'} loading={statusPending} />
                  <InfoRow label={t('域', 'Domain')} value={status?.saved?.domain || '-'} loading={statusPending} />
                  <InfoRow label="EWS URL" value={status?.saved?.service_endpoint || '-'} loading={statusPending} />
                  <InfoRow label="Server Host" value={status?.saved?.server || '-'} loading={statusPending} />
                  <InfoRow label={t('时区', 'Timezone')} value={status?.saved?.default_timezone || status?.defaults.fields.default_timezone || '-'} loading={statusPending} />
                  <InfoRow label={t('最近验证', 'Last verified')} value={formatDateTime(status?.meta?.last_verified_at as string | undefined, locale)} loading={statusPending} />
                  <InfoRow label={t('最近接入', 'Last connected')} value={formatDateTime(status?.meta?.last_connected_at as string | undefined, locale)} loading={statusPending} />
                  <InfoRow
                    label={t('最近刷新', 'Last refreshed')}
                    value={formatDateTime((overview?.meta?.last_overview_refresh_at || status?.meta?.last_overview_refresh_at) as string | undefined, locale)}
                    loading={statusPending || overviewPending}
                  />

                  {status?.error && (
                    <div className="rounded-2xl border border-destructive/30 bg-destructive/5 p-3 text-sm text-destructive">
                      {status.error}
                    </div>
                  )}

                  <div className="rounded-3xl border bg-muted/30 p-4">
                    <p className="text-xs uppercase tracking-[0.18em] text-muted-foreground">
                      {t('当前存储位置', 'Current storage mode')}
                    </p>
                    <p className="mt-2 text-sm font-medium text-foreground">
                      {status?.storage_mode === 'authz'
                        ? t(
                          '当前为 AuthZ 模式。Outlook 凭据保存在 AuthZ Service，由外置 Outlook MCP 按 backend 身份读取。',
                          'AuthZ mode is active. Outlook credentials are stored in the AuthZ service and read by the external Outlook MCP using the backend identity.'
                        )
                        : <>{t('当前为 workspace 模式。Outlook 状态文件会写入当前 workspace 的', 'Workspace mode is active. Outlook state files are written to')} <code>state/bw_outlook_mcp</code>.</>}
                    </p>
                  </div>
                </CardContent>
              </Card>
            </div>
          </TabsContent>
        </Tabs>

        <Dialog open={Boolean(selectedMessageRef)} onOpenChange={(open) => !open && setSelectedMessageRef(null)}>
          <DialogContent className="bottom-4 left-4 right-4 top-4 max-h-none w-auto max-w-none translate-x-0 translate-y-0 overflow-y-auto data-[state=open]:slide-in-from-left-0 data-[state=open]:slide-in-from-top-0 data-[state=closed]:slide-out-to-left-0 data-[state=closed]:slide-out-to-top-0 sm:bottom-auto sm:left-[50%] sm:right-auto sm:top-[50%] sm:max-h-[calc(100dvh-2rem)] sm:w-[calc(100vw-2rem)] sm:max-w-5xl sm:translate-x-[-50%] sm:translate-y-[-50%] sm:data-[state=open]:slide-in-from-left-1/2 sm:data-[state=open]:slide-in-from-top-[48%] sm:data-[state=closed]:slide-out-to-left-1/2 sm:data-[state=closed]:slide-out-to-top-[48%]">
            <DialogHeader>
              <DialogTitle className="break-words pr-8 leading-6">{selectedMessage?.subject || t('邮件详情', 'Message details')}</DialogTitle>
              <DialogDescription className="break-words">
                {selectedMessage?.receivedDateTime ? formatDateTime(selectedMessage.receivedDateTime, locale) : t('正在加载', 'Loading')}
              </DialogDescription>
            </DialogHeader>
            {messageLoading ? (
              <div className="flex items-center justify-center py-12">
                <Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
              </div>
            ) : selectedMessage ? (
              <div className="grid min-w-0 gap-4 lg:grid-cols-[280px,1fr]">
                <div className="space-y-4 rounded-2xl border bg-muted/20 p-4 text-sm">
                  <InfoRow label={t('发件人', 'From')} value={mailboxLabel(selectedMessage.from)} />
                  <InfoRow
                    label={t('收件人', 'To')}
                    value={(selectedMessage.toRecipients || []).map(mailboxLabel).filter(Boolean).join(locale === 'en-US' ? '; ' : '；') || '-'}
                  />
                  <InfoRow
                    label={t('抄送', 'Cc')}
                    value={(selectedMessage.ccRecipients || []).map(mailboxLabel).filter(Boolean).join(locale === 'en-US' ? '; ' : '；') || '-'}
                  />
                  <InfoRow label={t('接收时间', 'Received at')} value={formatDateTime(selectedMessage.receivedDateTime, locale)} />
                  <div className="flex flex-wrap gap-2">
                    <Badge variant={selectedMessage.isRead ? 'secondary' : 'default'}>
                      {selectedMessage.isRead ? t('已读', 'Read') : t('未读', 'Unread')}
                    </Badge>
                  </div>
                </div>

                <div className="min-w-0 overflow-hidden rounded-2xl border bg-background">
                  <div className="border-b px-4 py-3 text-xs font-medium uppercase tracking-[0.18em] text-muted-foreground">
                    {t('正文', 'Body')}
                  </div>
                  {selectedMessage.body?.contentType?.toLowerCase() === 'html' ? (
                    <iframe
                      title={t('邮件正文', 'Message body')}
                      srcDoc={buildEmailPreviewDocument(
                        selectedMessage.body?.content || selectedMessage.bodyPreview || '',
                        locale
                      )}
                      className="h-[60vh] w-full bg-white"
                      sandbox="allow-popups allow-popups-to-escape-sandbox"
                    />
                  ) : (
                    <ScrollArea className="h-[60vh]">
                      <div className="p-5 text-sm leading-7 text-foreground whitespace-pre-wrap break-words">
                        {renderPlainText(selectedMessage.body?.content || selectedMessage.bodyPreview || '')}
                      </div>
                    </ScrollArea>
                  )}
                </div>
              </div>
            ) : (
              <p className="text-sm text-muted-foreground">{t('未加载到邮件详情。', 'Message details were not loaded.')}</p>
            )}
          </DialogContent>
        </Dialog>

        <Dialog open={Boolean(selectedEvent)} onOpenChange={(open) => !open && setSelectedEvent(null)}>
          <DialogContent className="bottom-4 left-4 right-4 top-4 max-h-none w-auto max-w-none translate-x-0 translate-y-0 overflow-y-auto data-[state=open]:slide-in-from-left-0 data-[state=open]:slide-in-from-top-0 data-[state=closed]:slide-out-to-left-0 data-[state=closed]:slide-out-to-top-0 sm:bottom-auto sm:left-[50%] sm:right-auto sm:top-[50%] sm:max-h-[calc(100dvh-2rem)] sm:w-[calc(100vw-2rem)] sm:max-w-2xl sm:translate-x-[-50%] sm:translate-y-[-50%] sm:data-[state=open]:slide-in-from-left-1/2 sm:data-[state=open]:slide-in-from-top-[48%] sm:data-[state=closed]:slide-out-to-left-1/2 sm:data-[state=closed]:slide-out-to-top-[48%]">
            <DialogHeader>
              <DialogTitle className="break-words pr-8 leading-6">{selectedEvent?.subject || t('日程详情', 'Event details')}</DialogTitle>
              <DialogDescription className="break-words">
                {selectedEvent
                  ? `${formatDateTime(selectedEvent.start?.dateTime, locale)} - ${formatDateTime(selectedEvent.end?.dateTime, locale)}`
                  : t('日程详情', 'Event details')}
              </DialogDescription>
            </DialogHeader>
            {selectedEvent && (
              <div className="space-y-4 text-sm">
                <InfoRow label={t('组织者', 'Organizer')} value={mailboxLabel(selectedEvent.organizer)} />
                <InfoRow label={t('地点', 'Location')} value={selectedEvent.location?.displayName || '-'} />
                <InfoRow
                  label={t('参会人', 'Attendees')}
                  value={(selectedEvent.attendees || []).map(mailboxLabel).filter(Boolean).join(locale === 'en-US' ? '; ' : '；') || '-'}
                />
                <Separator />
                <div className="space-y-2">
                  <p className="text-xs uppercase tracking-[0.18em] text-muted-foreground">{t('说明', 'Notes')}</p>
                  <div className="rounded-lg border bg-muted/40 p-3 whitespace-pre-wrap break-words">
                    {selectedEvent.bodyPreview || t('没有更多说明。', 'No additional notes.')}
                  </div>
                </div>
              </div>
            )}
          </DialogContent>
        </Dialog>
      </div>
    </div>
  );
}

function Field({
  id,
  label,
  required = false,
  children,
}: {
  id: string;
  label: string;
  required?: boolean;
  children: React.ReactNode;
}) {
  return (
    <div className="space-y-2">
      <Label htmlFor={id} className="text-sm font-medium">
        {label}
        {required ? <span className="ml-1 text-destructive">*</span> : null}
      </Label>
      {children}
    </div>
  );
}

function InfoRow({ label, value, loading = false }: { label: string; value: string; loading?: boolean }) {
  return (
    <div className="flex items-start justify-between gap-4 text-sm">
      <span className="text-muted-foreground">{label}</span>
      {loading ? (
        <Skeleton className="h-4 w-32 max-w-[70%]" />
      ) : (
        <span className="max-w-[70%] text-right break-all">{value}</span>
      )}
    </div>
  );
}

function MiniStat({ label, value }: { label: string; value: string }) {
  return (
    <div className="rounded-2xl border bg-card p-3">
      <p className="text-xs text-muted-foreground">{label}</p>
      <p className="mt-1 text-lg font-semibold text-foreground">{value}</p>
    </div>
  );
}

function MessageCard({
  title,
  icon,
  items,
  page,
  locale,
  loading = false,
  emptyLabel,
  onOpen,
  onRefresh,
  refreshing,
  onPreviousPage,
  onNextPage,
}: {
  title: string;
  icon: React.ReactNode;
  items: OutlookMessageSummary[];
  page: OutlookPageInfo | null;
  locale: AppLocale;
  loading?: boolean;
  emptyLabel: string;
  onOpen: (item: OutlookMessageSummary) => void;
  onRefresh: () => void;
  refreshing: boolean;
  onPreviousPage: () => void;
  onNextPage: () => void;
}) {
  const t = (zh: string, en: string) => pickAppText(locale, zh, en);
  const currentPage = page ? Math.floor(page.skip / Math.max(page.top, 1)) + 1 : 1;
  const pageLabel = page ? t(`第 ${currentPage} 页 · 本页 ${page.returned} 封`, `Page ${currentPage} · ${page.returned} messages`) : t('正在读取邮件…', 'Loading messages...');

  return (
    <Card className="min-w-0 rounded-[28px] shadow-sm">
      <CardHeader className="flex flex-col gap-4 border-b pb-5 sm:flex-row sm:items-center sm:justify-between">
        <div className="min-w-0 space-y-1">
          <CardTitle className="flex items-center gap-2 break-words text-base">
            {icon}
            {title}
          </CardTitle>
          <p className="text-sm text-muted-foreground">{loading ? t('正在读取邮件…', 'Loading messages...') : pageLabel}</p>
        </div>
        <div className="flex flex-wrap items-center gap-2">
          <Button variant="ghost" size="sm" className="h-11 w-11 p-0" aria-label={t('刷新邮件', 'Refresh mail')} title={t('刷新邮件', 'Refresh mail')} onClick={onRefresh} disabled={refreshing}>
            <RefreshCw className={`h-4 w-4 ${refreshing ? 'animate-spin' : ''}`} />
          </Button>
          <Button variant="outline" size="sm" className="h-11" onClick={onPreviousPage} disabled={!page || page.skip === 0 || refreshing}>
            {t('上一页', 'Previous')}
          </Button>
          <Button
            variant="outline"
            size="sm"
            className="h-11"
            onClick={onNextPage}
            disabled={!page || !page.has_more || refreshing}
          >
            {t('下一页', 'Next')}
          </Button>
        </div>
      </CardHeader>
      <CardContent className="pt-6">
        {loading ? (
          <div className="space-y-3">
            {Array.from({ length: 4 }).map((_, index) => (
              <div key={index} className="rounded-2xl border bg-card p-4">
                <Skeleton className="h-5 w-1/3" />
                <Skeleton className="mt-2 h-4 w-1/4" />
                <Skeleton className="mt-4 h-4 w-full" />
                <Skeleton className="mt-2 h-4 w-5/6" />
              </div>
            ))}
          </div>
        ) : items.length === 0 ? (
          <div className="rounded-3xl border border-dashed bg-muted/30 p-8 text-center text-sm text-muted-foreground">
            {emptyLabel}
          </div>
        ) : (
          <div className="space-y-3">
            {items.map((item) => (
              <button
                key={item.id || `${item.subject}-${item.receivedDateTime}`}
                type="button"
                onClick={() => item.id && onOpen(item)}
                className="min-h-11 w-full rounded-2xl border bg-card p-4 text-left transition-colors hover:bg-muted/40"
              >
                <div className="flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between">
                  <div className="min-w-0 flex-1">
                    <p className="break-words font-medium text-foreground">{item.subject || t('(无主题)', '(No subject)')}</p>
                    <p className="mt-1 break-all text-xs text-muted-foreground">{mailboxLabel(item.from)}</p>
                    <p className="mt-3 line-clamp-2 break-words text-sm leading-6 text-muted-foreground">
                      {item.bodyPreview || t('没有预览内容。', 'No preview available.')}
                    </p>
                  </div>
                  <div className="flex shrink-0 flex-wrap items-center gap-2 lg:flex-col lg:items-end">
                    <Badge variant={item.isRead ? 'secondary' : 'default'}>
                      {item.isRead ? t('已读', 'Read') : t('未读', 'Unread')}
                    </Badge>
                    <span className="text-xs text-muted-foreground">{formatDateTime(item.receivedDateTime, locale)}</span>
                  </div>
                </div>
              </button>
            ))}
          </div>
        )}
      </CardContent>
    </Card>
  );
}

function EventCard({
  items,
  startDate,
  locale,
  loading = false,
  onOpen,
  onRefresh,
  refreshing,
  onPreviousWeek,
  onNextWeek,
  onCurrentWeek,
}: {
  items: OutlookEventSummary[];
  startDate?: string | null;
  locale: AppLocale;
  loading?: boolean;
  onOpen: (item: OutlookEventSummary) => void;
  onRefresh: () => void;
  refreshing: boolean;
  onPreviousWeek: () => void;
  onNextWeek: () => void;
  onCurrentWeek: () => void;
}) {
  const t = (zh: string, en: string) => pickAppText(locale, zh, en);
  const initialAnchor = startDate ? new Date(startDate) : new Date();
  const anchor = Number.isNaN(initialAnchor.getTime()) ? new Date() : initialAnchor;
  const weekDays = Array.from({ length: 7 }, (_, index) => {
    const next = new Date(anchor);
    next.setDate(anchor.getDate() + index);
    return next;
  });
  const eventsByDay = weekDays.map((day) => {
    const key = toLocalDateKey(day);
    return {
      key,
      label: formatDayLabel(day, locale),
      items: items
        .filter((item) => formatDateKey(item.start?.dateTime) === key)
        .sort((left, right) => {
          const leftTime = new Date(left.start?.dateTime || '').getTime();
          const rightTime = new Date(right.start?.dateTime || '').getTime();
          return leftTime - rightTime;
        }),
    };
  });

  return (
    <Card className="min-w-0 rounded-[28px] shadow-sm">
      <CardHeader className="flex flex-col gap-4 space-y-0 border-b pb-5 sm:flex-row sm:items-center sm:justify-between">
        <div className="min-w-0 space-y-1">
          <CardTitle className="flex items-center gap-2 break-words text-base">
            <CalendarDays className="h-4 w-4" />
            {t('日程安排', 'Schedule')}
          </CardTitle>
          <p className="text-sm text-muted-foreground">
            {formatDayLabel(weekDays[0], locale)} - {formatDayLabel(weekDays[weekDays.length - 1], locale)}
          </p>
        </div>
        <div className="flex flex-wrap items-center gap-2">
          <Button variant="outline" size="sm" className="h-11" onClick={onPreviousWeek} disabled={refreshing}>
            {t('上一周', 'Previous week')}
          </Button>
          <Button variant="outline" size="sm" className="h-11" onClick={onCurrentWeek} disabled={refreshing}>
            {t('本周', 'This week')}
          </Button>
          <Button variant="outline" size="sm" className="h-11" onClick={onNextWeek} disabled={refreshing}>
            {t('下一周', 'Next week')}
          </Button>
          <Button variant="ghost" size="sm" className="h-11 w-11 p-0" aria-label={t('刷新日程', 'Refresh calendar')} title={t('刷新日程', 'Refresh calendar')} onClick={onRefresh} disabled={refreshing}>
            <RefreshCw className={`h-4 w-4 ${refreshing ? 'animate-spin' : ''}`} />
          </Button>
        </div>
      </CardHeader>
      <CardContent className="pt-6">
        {loading ? (
          <div className="grid gap-3 lg:grid-cols-2 2xl:grid-cols-3">
            {Array.from({ length: 6 }).map((_, index) => (
              <div key={index} className="rounded-2xl border bg-card p-4">
                <Skeleton className="h-5 w-24" />
                <Skeleton className="mt-2 h-4 w-16" />
                <Skeleton className="mt-6 h-16 w-full" />
              </div>
            ))}
          </div>
        ) : (
          <div className="grid gap-3 lg:grid-cols-2 2xl:grid-cols-3">
            {eventsByDay.map((day) => (
              <div key={day.key} className="min-w-0 rounded-2xl border bg-card p-4">
                <div className="flex items-center justify-between gap-3">
                  <div>
                    <p className="font-medium text-foreground">{day.label}</p>
                    <p className="text-xs text-muted-foreground">{t(`${day.items.length} 条安排`, `${day.items.length} events`)}</p>
                  </div>
                </div>
                {day.items.length === 0 ? (
                  <p className="mt-4 text-sm text-muted-foreground">{t('暂无安排', 'No events')}</p>
                ) : (
                  <div className="mt-4 space-y-3">
                    {day.items.map((item) => (
                      <button
                        key={item.id || `${item.subject}-${item.start?.dateTime}`}
                        type="button"
                        onClick={() => onOpen(item)}
                        className="min-h-11 w-full rounded-xl border bg-background p-3 text-left transition-colors hover:bg-muted/40"
                      >
                        <p className="break-words font-medium text-foreground">{item.subject || t('(无主题)', '(No subject)')}</p>
                        <p className="mt-1 text-xs text-muted-foreground">
                          {formatTime(item.start?.dateTime, locale)} - {formatTime(item.end?.dateTime, locale)}
                        </p>
                        <p className="mt-2 break-words text-sm text-muted-foreground">
                          {item.location?.displayName || t('未设置地点', 'No location set')}
                        </p>
                      </button>
                    ))}
                  </div>
                )}
              </div>
            ))}
          </div>
        )}
      </CardContent>
    </Card>
  );
}
