'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';

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): string {
  if (!value) return '-';
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return value;
  return new Intl.DateTimeFormat('zh-CN', {
    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): string {
  return new Intl.DateTimeFormat('zh-CN', {
    month: '2-digit',
    day: '2-digit',
    weekday: 'short',
  }).format(value);
}

function formatTime(value?: string | null): string {
  if (!value) return '-';
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return value;
  return new Intl.DateTimeFormat('zh-CN', {
    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): string {
  return `<!DOCTYPE html>
<html lang="zh-CN">
  <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="text-primary underline underline-offset-2 break-all"
          >
            {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 [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 applyStatus = useCallback((nextStatus: OutlookStatus, forceFormSync = false) => {
    setStatus(nextStatus);
    if (forceFormSync || !formDirty) {
      setForm(toFormState(nextStatus));
      setFormDirty(false);
    }
  }, [formDirty]);

  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 || '加载 Outlook 概览失败');
    } finally {
      setOverviewLoading(false);
    }
  }, []);

  const loadMailboxPage = useCallback(async (view: OutlookMailboxView, skip = 0) => {
    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 || `加载${view === 'inbox' ? '收件箱' : '发件箱'}失败`);
    } finally {
      setMailboxLoading((current) => ({ ...current, [view]: false }));
    }
  }, []);

  const loadCalendarPage = useCallback(async (anchorKey: string) => {
    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 || '加载日程失败');
    } finally {
      setCalendarLoading(false);
    }
  }, []);

  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) {
        await loadOverview(options?.preserveOverview ?? background);
      } else {
        setOverview(null);
        setOverviewLoading(false);
      }
    } catch (err: any) {
      setError(err.message || '加载 Outlook 集成状态失败');
      setOverviewLoading(false);
    } finally {
      if (background) {
        setRefreshing(false);
      } else {
        setStatusLoading(false);
      }
    }
  }, [applyStatus, loadOverview]);

  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 || '加载邮件详情失败');
        }
      })
      .finally(() => {
        if (!cancelled) {
          setMessageLoading(false);
        }
      });

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

  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 inboxCount = overview?.recentInbox.length ?? 0;
  const sentCount = overview?.recentSent.length ?? 0;
  const eventCount = overview?.todayEvents.length ?? 0;
  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: '设置',
          hint: '配置 Outlook 连接',
          icon: Settings2,
          count: null,
        },
      ];
    }

    return [
      {
        id: 'inbox' as const,
        label: '收件箱',
        hint: '最近接收邮件',
        icon: Inbox,
        count: null,
      },
      {
        id: 'sent' as const,
        label: '发件箱',
        hint: '最近发送记录',
        icon: Send,
        count: null,
      },
      {
        id: 'calendar' as const,
        label: '日程',
        hint: '未来 7 天',
        icon: CalendarDays,
        count: overviewPending ? null : eventCount,
      },
      {
        id: 'settings' as const,
        label: '设置',
        hint: '连接与状态',
        icon: Settings2,
        count: null,
      },
    ];
  }, [eventCount, inboxCount, isConfigured, overviewPending, sentCount]);

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

  useEffect(() => {
    if (!isConfigured) {
      return;
    }
    if (activeView === 'inbox' && !inboxPage && !mailboxLoading.inbox) {
      void loadMailboxPage('inbox', 0);
    }
    if (activeView === 'sent' && !sentPage && !mailboxLoading.sent) {
      void loadMailboxPage('sent', 0);
    }
    if (activeView === 'calendar' && !calendarPage && !calendarLoading) {
      void loadCalendarPage(calendarAnchorKey);
    }
  }, [
    activeView,
    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 || '测试连接失败');
      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);
      setCalendarAnchorKey(toLocalDateKey(new Date()));
      await loadStatus(true, { forceFormSync: true });
      setActiveView('inbox');
    } catch (err: any) {
      setError(err.message || '保存 Outlook 配置失败');
    } finally {
      setSaving(false);
    }
  };

  const handleDisconnect = async () => {
    setDisconnecting(true);
    setError(null);
    try {
      await disconnectOutlook();
      setOverview(null);
      setTestResult(null);
      setSelectedMessageRef(null);
      setSelectedEvent(null);
      setInboxPage(null);
      setSentPage(null);
      setCalendarPage(null);
      setCalendarAnchorKey(toLocalDateKey(new Date()));
      setActiveView('settings');
      setFormDirty(false);
      await loadStatus(true, { forceFormSync: true });
    } catch (err: any) {
      setError(err.message || '断开 Outlook 连接失败');
    } finally {
      setDisconnecting(false);
    }
  };

  const refreshOverview = async () => {
    await loadStatus(true, { preserveOverview: 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-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 flex-wrap items-center gap-2 text-sm">
              <div className="mr-2 flex items-center gap-2 text-lg font-semibold text-foreground">
                <Mail className="h-5 w-5" />
                Outlook
              </div>
              {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 ? '已连通' : isConfigured ? '已配置' : '未配置'}
                  </Badge>
                  <Badge variant={status?.mcp_registered ? 'default' : 'secondary'}>
                    {status?.mcp_registered ? 'MCP 已注册' : 'MCP 未注册'}
                  </Badge>
                  <Badge variant="secondary">{status?.provider || 'ews'}</Badge>
                  <span className="text-muted-foreground">邮箱 {overview?.mailbox || status?.saved?.email || '-'}</span>
                  <span className="text-muted-foreground">时区 {status?.saved?.default_timezone || overview?.timezone || form.default_timezone}</span>
                  <span className="text-muted-foreground">
                    最近刷新 {formatDateTime((overview?.meta?.last_overview_refresh_at || status?.meta?.last_overview_refresh_at) as string | undefined)}
                  </span>
                </>
              )}
            </div>

            <div className="flex flex-wrap items-center gap-2">
              {isConfigured ? (
                <>
                  <TopStat label="收件箱" value={String(inboxCount)} loading={overviewPending} />
                  <TopStat label="发件箱" value={String(sentCount)} loading={overviewPending} />
                  <TopStat label="日程" value={String(eventCount)} loading={overviewPending} />
                </>
              ) : null}
              <Button variant="outline" size="sm" onClick={() => void refreshOverview()}>
                <RefreshCw className={`mr-2 h-4 w-4 ${refreshing ? 'animate-spin' : ''}`} />
                刷新
              </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>{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>{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="h-auto 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>
                        {typeof view.count === 'number' ? (
                          <p className="text-xs text-muted-foreground">{view.count} 条</p>
                        ) : null}
                      </div>
                    </div>
                  </div>
                </TabsTrigger>
              );
            })}
          </TabsList>

          <TabsContent value="inbox" className="mt-0">
            <MessageCard
              title="收件箱"
              icon={<MailOpen className="h-4 w-4" />}
              items={inboxPage?.value || []}
              page={inboxPage?.page || null}
              loading={mailboxLoading.inbox || (activeView === 'inbox' && !inboxPage)}
              emptyLabel="还没有读取到收件箱邮件"
              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="发件箱"
              icon={<Send className="h-4 w-4" />}
              items={sentPage?.value || []}
              page={sentPage?.page || null}
              loading={mailboxLoading.sent || (activeView === 'sent' && !sentPage)}
              emptyLabel="还没有读取到已发送邮件"
              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)}
              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">连接设置</CardTitle>
                </CardHeader>
                <CardContent className="space-y-5 pt-6">
                  <div className="grid gap-4 md:grid-cols-2">
                    <Field label="邮箱地址" required>
                      <Input
                        value={form.email}
                        onChange={(event) => updateField('email', event.target.value)}
                        placeholder="you@boardware.com"
                      />
                    </Field>
                    <Field label="用户名">
                      <Input
                        value={form.username}
                        onChange={(event) => updateField('username', event.target.value)}
                        placeholder="留空时默认取邮箱前缀"
                      />
                    </Field>
                    <Field label="密码" required>
                      <Input
                        type="password"
                        value={form.password}
                        onChange={(event) => updateField('password', event.target.value)}
                        placeholder="请输入邮箱密码"
                      />
                    </Field>
                    <Field label="域">
                      <Input
                        value={form.domain}
                        onChange={(event) => updateField('domain', event.target.value)}
                        placeholder="boardware.com.mo"
                      />
                    </Field>
                    <Field label="EWS URL">
                      <Input
                        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 label="Server Host">
                      <Input
                        value={form.server}
                        onChange={(event) => updateField('server', event.target.value)}
                        placeholder="mail.boardware.com.mo"
                        disabled={form.autodiscover}
                      />
                    </Field>
                    <Field label="时区">
                      <Input
                        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">
                            开启后优先使用 Exchange 自动发现，不再强依赖手填 EWS URL。
                          </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" onClick={handleTest} disabled={!canTest || testing}>
                      {testing ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <CheckCircle2 className="mr-2 h-4 w-4" />}
                      测试连接
                    </Button>
                    <Button onClick={handleConnect} disabled={!canTest || saving}>
                      {saving ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <Save className="mr-2 h-4 w-4" />}
                      保存并启用
                    </Button>
                    <Button
                      variant="outline"
                      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" />}
                      断开连接
                    </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">测试成功</Badge>
                        <span className="text-muted-foreground">{testResult.mailbox}</span>
                        <span className="text-muted-foreground">用户名: {testResult.resolved_username}</span>
                      </div>
                      <div className="mt-3 grid gap-3 md:grid-cols-3">
                        <MiniStat label="检测到文件夹" value={String(testResult.sample.folders.length)} />
                        <MiniStat label="收件箱样本" value={String(testResult.sample.inbox.length)} />
                        <MiniStat label="日程样本" 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>{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">连接状态</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 ? '已连通' : isConfigured ? '已配置' : '未配置'}
                        </Badge>
                        <Badge variant={status?.mcp_registered ? 'default' : 'secondary'}>
                          {status?.mcp_registered ? 'MCP 已注册' : 'MCP 未注册'}
                        </Badge>
                        <Badge variant="secondary">{status?.provider || 'ews'}</Badge>
                      </>
                    )}
                  </div>

                  <InfoRow label="邮箱" value={status?.saved?.email || '-'} loading={statusPending} />
                  <InfoRow label="用户名" value={status?.saved?.username || '-'} loading={statusPending} />
                  <InfoRow label="域" 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="时区" value={status?.saved?.default_timezone || status?.defaults.fields.default_timezone || '-'} loading={statusPending} />
                  <InfoRow label="最近验证" value={formatDateTime(status?.meta?.last_verified_at as string | undefined)} loading={statusPending} />
                  <InfoRow label="最近接入" value={formatDateTime(status?.meta?.last_connected_at as string | undefined)} loading={statusPending} />
                  <InfoRow
                    label="最近刷新"
                    value={formatDateTime((overview?.meta?.last_overview_refresh_at || status?.meta?.last_overview_refresh_at) as string | undefined)}
                    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">
                      当前存储位置
                    </p>
                    <p className="mt-2 text-sm font-medium text-foreground">
                      {status?.storage_mode === 'authz'
                        ? '当前为 AuthZ 模式。Outlook 凭据保存在 AuthZ Service，由外置 Outlook MCP 按 backend 身份读取。'
                        : <>当前为 workspace 模式。Outlook 状态文件会写入当前 workspace 的 <code>state/bw_outlook_mcp</code>。</>}
                    </p>
                  </div>
                </CardContent>
              </Card>
            </div>
          </TabsContent>
        </Tabs>

        <Dialog open={Boolean(selectedMessageRef)} onOpenChange={(open) => !open && setSelectedMessageRef(null)}>
          <DialogContent className="sm:max-w-5xl">
            <DialogHeader>
              <DialogTitle>{selectedMessage?.subject || '邮件详情'}</DialogTitle>
              <DialogDescription>
                {selectedMessage?.receivedDateTime ? formatDateTime(selectedMessage.receivedDateTime) : '正在加载'}
              </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 gap-4 lg:grid-cols-[280px,1fr]">
                <div className="space-y-4 rounded-2xl border bg-muted/20 p-4 text-sm">
                  <InfoRow label="发件人" value={mailboxLabel(selectedMessage.from)} />
                  <InfoRow
                    label="收件人"
                    value={(selectedMessage.toRecipients || []).map(mailboxLabel).filter(Boolean).join('；') || '-'}
                  />
                  <InfoRow
                    label="抄送"
                    value={(selectedMessage.ccRecipients || []).map(mailboxLabel).filter(Boolean).join('；') || '-'}
                  />
                  <InfoRow label="接收时间" value={formatDateTime(selectedMessage.receivedDateTime)} />
                  <div className="flex flex-wrap gap-2">
                    <Badge variant={selectedMessage.isRead ? 'secondary' : 'default'}>
                      {selectedMessage.isRead ? '已读' : '未读'}
                    </Badge>
                  </div>
                </div>

                <div className="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">
                    正文
                  </div>
                  {selectedMessage.body?.contentType?.toLowerCase() === 'html' ? (
                    <iframe
                      title="邮件正文"
                      srcDoc={buildEmailPreviewDocument(
                        selectedMessage.body?.content || selectedMessage.bodyPreview || ''
                      )}
                      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">未加载到邮件详情。</p>
            )}
          </DialogContent>
        </Dialog>

        <Dialog open={Boolean(selectedEvent)} onOpenChange={(open) => !open && setSelectedEvent(null)}>
          <DialogContent className="sm:max-w-2xl">
            <DialogHeader>
              <DialogTitle>{selectedEvent?.subject || '日程详情'}</DialogTitle>
              <DialogDescription>
                {selectedEvent
                  ? `${formatDateTime(selectedEvent.start?.dateTime)} - ${formatDateTime(selectedEvent.end?.dateTime)}`
                  : '日程详情'}
              </DialogDescription>
            </DialogHeader>
            {selectedEvent && (
              <div className="space-y-4 text-sm">
                <InfoRow label="组织者" value={mailboxLabel(selectedEvent.organizer)} />
                <InfoRow label="地点" value={selectedEvent.location?.displayName || '-'} />
                <InfoRow
                  label="参会人"
                  value={(selectedEvent.attendees || []).map(mailboxLabel).filter(Boolean).join('；') || '-'}
                />
                <Separator />
                <div className="space-y-2">
                  <p className="text-xs uppercase tracking-[0.18em] text-muted-foreground">说明</p>
                  <div className="rounded-lg border bg-muted/40 p-3 whitespace-pre-wrap">
                    {selectedEvent.bodyPreview || '没有更多说明。'}
                  </div>
                </div>
              </div>
            )}
          </DialogContent>
        </Dialog>
      </div>
    </div>
  );
}

function Field({
  label,
  required = false,
  children,
}: {
  label: string;
  required?: boolean;
  children: React.ReactNode;
}) {
  return (
    <div className="space-y-2">
      <Label 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 TopStat({ label, value, loading = false }: { label: string; value: string; loading?: boolean }) {
  return (
    <div className="rounded-full border bg-background px-3 py-1 text-sm">
      <span className="text-muted-foreground">{label}</span>
      {loading ? (
        <Skeleton className="ml-2 inline-flex h-4 w-8 align-middle" />
      ) : (
        <span className="ml-2 font-semibold text-foreground">{value}</span>
      )}
    </div>
  );
}

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

  return (
    <Card className="rounded-[28px] shadow-sm">
      <CardHeader className="flex flex-row items-center justify-between gap-4 border-b pb-5">
        <div className="space-y-1">
          <CardTitle className="flex items-center gap-2 text-base">
            {icon}
            {title}
          </CardTitle>
          <p className="text-sm text-muted-foreground">{loading ? '正在读取邮件…' : pageLabel}</p>
        </div>
        <div className="flex items-center gap-2">
          <Button variant="ghost" size="sm" onClick={onRefresh} disabled={refreshing}>
            <RefreshCw className={`h-4 w-4 ${refreshing ? 'animate-spin' : ''}`} />
          </Button>
          <Button variant="outline" size="sm" onClick={onPreviousPage} disabled={!page || page.skip === 0 || refreshing}>
            上一页
          </Button>
          <Button
            variant="outline"
            size="sm"
            onClick={onNextPage}
            disabled={!page || !page.has_more || refreshing}
          >
            下一页
          </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="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="truncate font-medium text-foreground">{item.subject || '(无主题)'}</p>
                    <p className="mt-1 truncate text-xs text-muted-foreground">{mailboxLabel(item.from)}</p>
                    <p className="mt-3 line-clamp-2 text-sm leading-6 text-muted-foreground">
                      {item.bodyPreview || '没有预览内容。'}
                    </p>
                  </div>
                  <div className="flex shrink-0 items-center gap-2 lg:flex-col lg:items-end">
                    <Badge variant={item.isRead ? 'secondary' : 'default'}>
                      {item.isRead ? '已读' : '未读'}
                    </Badge>
                    <span className="text-xs text-muted-foreground">{formatDateTime(item.receivedDateTime)}</span>
                  </div>
                </div>
              </button>
            ))}
          </div>
        )}
      </CardContent>
    </Card>
  );
}

function EventCard({
  items,
  startDate,
  loading = false,
  onOpen,
  onRefresh,
  refreshing,
  onPreviousWeek,
  onNextWeek,
  onCurrentWeek,
}: {
  items: OutlookEventSummary[];
  startDate?: string | null;
  loading?: boolean;
  onOpen: (item: OutlookEventSummary) => void;
  onRefresh: () => void;
  refreshing: boolean;
  onPreviousWeek: () => void;
  onNextWeek: () => void;
  onCurrentWeek: () => void;
}) {
  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),
      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="rounded-[28px] shadow-sm">
      <CardHeader className="flex flex-row items-center justify-between space-y-0 border-b pb-5">
        <div className="space-y-1">
          <CardTitle className="flex items-center gap-2 text-base">
            <CalendarDays className="h-4 w-4" />
            日程安排
          </CardTitle>
          <p className="text-sm text-muted-foreground">
            {formatDayLabel(weekDays[0])} - {formatDayLabel(weekDays[weekDays.length - 1])}
          </p>
        </div>
        <div className="flex items-center gap-2">
          <Button variant="outline" size="sm" onClick={onPreviousWeek} disabled={refreshing}>
            上一周
          </Button>
          <Button variant="outline" size="sm" onClick={onCurrentWeek} disabled={refreshing}>
            本周
          </Button>
          <Button variant="outline" size="sm" onClick={onNextWeek} disabled={refreshing}>
            下一周
          </Button>
          <Button variant="ghost" size="sm" 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="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">{day.items.length} 条安排</p>
                  </div>
                </div>
                {day.items.length === 0 ? (
                  <p className="mt-4 text-sm text-muted-foreground">暂无安排</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="w-full rounded-xl border bg-background p-3 text-left transition-colors hover:bg-muted/40"
                      >
                        <p className="font-medium text-foreground">{item.subject || '(无主题)'}</p>
                        <p className="mt-1 text-xs text-muted-foreground">
                          {formatTime(item.start?.dateTime)} - {formatTime(item.end?.dateTime)}
                        </p>
                        <p className="mt-2 text-sm text-muted-foreground">
                          {item.location?.displayName || '未设置地点'}
                        </p>
                      </button>
                    ))}
                  </div>
                )}
              </div>
            ))}
          </div>
        )}
      </CardContent>
    </Card>
  );
}
