import {
  ExportOutlined,
  InboxOutlined,
  ReloadOutlined,
  SettingOutlined
} from '@ant-design/icons';
import {
  Alert,
  App as AntApp,
  Button,
  Card,
  Descriptions,
  List,
  Skeleton,
  Space,
  Table,
  Tag,
  Tooltip,
  Typography
} from 'antd';
import type { ColumnsType } from 'antd/es/table';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { useNavigate } from 'react-router-dom';

import { EmptyState } from '../components/common/EmptyState';
import { PageHeader } from '../components/common/PageHeader';
import { SectionCard } from '../components/common/SectionCard';
import { MailboxPermissionTags } from '../components/mailbox/MailboxPermissionTags';
import { useAppContext } from '../frontend/app-context';
import { useI18n } from '../frontend/i18n/react';
import { api, submitWebmailLogin } from '../frontend/services/api';
import type { InboundMailbox, MailboxAccess } from '../frontend/types';
import { useMediaQuery } from '../frontend/use-media-query';

export default function Account() {
  const { message } = AntApp.useApp();
  const { config, user } = useAppContext();
  const { locale, t } = useI18n();
  const navigate = useNavigate();
  const isTableView = useMediaQuery('(min-width: 768px)');
  const [mailboxes, setMailboxes] = useState<InboundMailbox[]>([]);
  const [loading, setLoading] = useState(true);
  const [loadError, setLoadError] = useState('');
  const [webmailLoadingIds, setWebmailLoadingIds] = useState<Set<number>>(() => new Set());

  const loadMailboxes = useCallback(async () => {
    setLoading(true);
    setLoadError('');
    try {
      const result = await api.inboundMailboxes('effective');
      setMailboxes(result.mailboxes || []);
    } catch (error) {
      setLoadError(error instanceof Error ? error.message : t('common.error'));
    } finally {
      setLoading(false);
    }
  }, [t]);

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

  const counts = useMemo(() => ({
    owned: mailboxes.filter((mailbox) => mailboxAccess(mailbox).type === 'owner').length,
    assigned: mailboxes.filter((mailbox) => mailboxAccess(mailbox).type === 'assigned').length
  }), [mailboxes]);

  function openInbox(mailbox: InboundMailbox) {
    navigate(`/inbox?mailboxId=${mailbox.id}&folder=INBOX`);
  }

  function manageMailbox(mailbox: InboundMailbox) {
    navigate(`/inbox?workspace=routing&mailboxId=${mailbox.id}`);
  }

  async function openWebmail(mailbox: InboundMailbox) {
    if (config?.webmailSsoEnabled !== true || !canOpenWebmail(mailbox) || mailbox.status !== 'active' || webmailLoadingIds.has(mailbox.id)) return;
    setWebmailLoadingIds((current) => new Set(current).add(mailbox.id));
    try {
      const result = await api.createWebmailLogin(mailbox.id);
      submitWebmailLogin(result.webmailLogin);
    } catch (error) {
      message.error(error instanceof Error ? error.message : t('common.error'));
    } finally {
      setWebmailLoadingIds((current) => {
        const next = new Set(current);
        next.delete(mailbox.id);
        return next;
      });
    }
  }

  const columns: ColumnsType<InboundMailbox> = [
    {
      title: t('inbox.mailboxAddress'),
      render: (_, mailbox) => (
        <Space direction="vertical" size={0}>
          <Typography.Text strong>{mailbox.address}</Typography.Text>
          {mailbox.displayName ? <Typography.Text type="secondary">{mailbox.displayName}</Typography.Text> : null}
        </Space>
      )
    },
    {
      title: t('account.accessSource'),
      width: 160,
      render: (_, mailbox) => <AccessSource mailbox={mailbox} />
    },
    {
      title: t('account.permissions'),
      width: 280,
      render: (_, mailbox) => <MailboxPermissionTags permissions={mailboxAccess(mailbox).permissions} />
    },
    {
      title: t('common.actions'),
      width: 430,
      render: (_, mailbox) => (
        <Space wrap>
          {mailboxAccess(mailbox).permissions.receive ? (
            <Button aria-label={`${t('account.openInbox')} · ${mailbox.address}`} icon={<InboxOutlined />} style={{ minHeight: 44 }} onClick={() => openInbox(mailbox)}>
              {t('account.openInbox')}
            </Button>
          ) : null}
          {config?.webmailSsoEnabled === true && canOpenWebmail(mailbox) ? (
            <WebmailButton
              mailbox={mailbox}
              locale={locale}
              loading={webmailLoadingIds.has(mailbox.id)}
              onClick={() => void openWebmail(mailbox)}
            />
          ) : null}
          {mailboxAccess(mailbox).type === 'owner' ? (
            <Button aria-label={`${t('account.manageMailbox')} · ${mailbox.address}`} icon={<SettingOutlined />} style={{ minHeight: 44 }} onClick={() => manageMailbox(mailbox)}>
              {t('account.manageMailbox')}
            </Button>
          ) : null}
        </Space>
      )
    }
  ];

  return (
    <Space direction="vertical" size={20} className="full-width account-page">
      <PageHeader title={t('account.title')} subtitle={t('account.subtitle')} />
      <SectionCard title={t('account.summary')}>
        <Descriptions column={isTableView ? 2 : 1} bordered size="small">
          <Descriptions.Item label={t('auth.username')}>{user?.username || '—'}</Descriptions.Item>
          <Descriptions.Item label={t('auth.email')}>{user?.email || '—'}</Descriptions.Item>
          <Descriptions.Item label={t('account.role')}>{user?.role || '—'}</Descriptions.Item>
          <Descriptions.Item label={t('common.status')}>{user?.status || '—'}</Descriptions.Item>
        </Descriptions>
      </SectionCard>
      {loadError ? (
        <Alert
          type="error"
          showIcon
          message={loadError}
          action={<Button icon={<ReloadOutlined />} onClick={() => void loadMailboxes()}>{t('common.refresh')}</Button>}
        />
      ) : null}
      <SectionCard
        title={t('account.mailboxAccess')}
        extra={<Space wrap><Tag>{t('account.owned')} {counts.owned}</Tag><Tag>{t('account.assigned')} {counts.assigned}</Tag></Space>}
      >
        {loading && !mailboxes.length ? <Skeleton active paragraph={{ rows: 7 }} /> : mailboxes.length ? (
          isTableView ? (
            <Table rowKey="id" columns={columns} dataSource={mailboxes} scroll={{ x: 900 }} />
          ) : (
            <List
              dataSource={mailboxes}
              renderItem={(mailbox) => (
                <List.Item>
                  <Card size="small" title={mailbox.address} className="full-width account-mailbox-card">
                    <Space direction="vertical" size={12} className="full-width">
                      <AccessSource mailbox={mailbox} />
                      <MailboxPermissionTags permissions={mailboxAccess(mailbox).permissions} />
                      {mailboxAccess(mailbox).permissions.receive ? (
                        <Button block aria-label={`${t('account.openInbox')} · ${mailbox.address}`} icon={<InboxOutlined />} style={{ minHeight: 44 }} onClick={() => openInbox(mailbox)}>
                          {t('account.openInbox')}
                        </Button>
                      ) : null}
                      {config?.webmailSsoEnabled === true && canOpenWebmail(mailbox) ? (
                        <WebmailButton
                          block
                          mailbox={mailbox}
                          locale={locale}
                          loading={webmailLoadingIds.has(mailbox.id)}
                          onClick={() => void openWebmail(mailbox)}
                        />
                      ) : null}
                      {mailboxAccess(mailbox).type === 'owner' ? (
                        <Button block aria-label={`${t('account.manageMailbox')} · ${mailbox.address}`} icon={<SettingOutlined />} style={{ minHeight: 44 }} onClick={() => manageMailbox(mailbox)}>
                          {t('account.manageMailbox')}
                        </Button>
                      ) : null}
                    </Space>
                  </Card>
                </List.Item>
              )}
            />
          )
        ) : <EmptyState description={t('account.noMailboxes')} action={<Button onClick={() => navigate('/inbox?workspace=routing')}>{t('inbox.createMailbox')}</Button>} />}
      </SectionCard>
    </Space>
  );
}

function AccessSource({ mailbox }: { mailbox: InboundMailbox }) {
  const { t } = useI18n();
  const access = mailboxAccess(mailbox);
  if (access.type === 'owner') return <Tag color="blue">{t('account.ownedMailbox')}</Tag>;
  if (access.type === 'admin') return <Tag color="gold">{t('account.adminAccess')}</Tag>;
  return <Tag color="purple">{t('account.adminAssigned')}</Tag>;
}

function mailboxAccess(mailbox: InboundMailbox): MailboxAccess {
  return mailbox.access || {
    type: 'owner',
    permissions: { view: true, receive: true, send: true }
  };
}

function canOpenWebmail(mailbox: InboundMailbox) {
  const access = mailboxAccess(mailbox);
  return (access.type === 'owner' || access.type === 'assigned') && access.permissions.receive;
}

function WebmailButton({ block = false, mailbox, locale, loading, onClick }: {
  block?: boolean;
  mailbox: InboundMailbox;
  locale: string;
  loading: boolean;
  onClick: () => void;
}) {
  const label = locale.startsWith('en') ? 'Open Webmail' : '一键登录 Webmail';
  const disabledReason = mailbox.status === 'active'
    ? ''
    : (locale.startsWith('en') ? 'This mailbox is disabled and cannot sign in to Webmail.' : '该邮箱已停用，无法登录 Webmail。');
  const button = (
    <Button
      block={block}
      aria-label={`${label} · ${mailbox.address}${disabledReason ? ` · ${disabledReason}` : ''}`}
      disabled={Boolean(disabledReason)}
      icon={<ExportOutlined />}
      loading={loading}
      onClick={onClick}
      style={{ minHeight: 44 }}
      title={disabledReason || undefined}
    >
      {label}
    </Button>
  );
  return disabledReason ? <Tooltip title={disabledReason}><span style={block ? { display: 'block' } : undefined}>{button}</span></Tooltip> : button;
}
