import { AuditOutlined, ExclamationCircleOutlined, ReloadOutlined, SafetyCertificateOutlined } from '@ant-design/icons';
import { Alert, App, Button, Card, Col, Descriptions, Drawer, Empty, Flex, Form, Row, Space, Statistic, Tabs, Tag, Timeline, Typography } from 'antd';
import { useEffect, useMemo, useState } from 'react';
import { Link } from 'react-router';
import { apiRequest } from '../api/http';
import { pendingApproval } from '../api/platform-command';
import { platformOperations } from '../api/platform-operations.generated';
import type { OperationInput, PlatformOperation } from '../api/types';
import { BusinessTable, rowsFromPayload } from '../components/BusinessTable';
import { normalizeOperationInput, OperationForm } from '../components/OperationForm';
import { TenantOnboardingWorkbench } from './TenantOnboardingWorkbench';
import { useAuth } from '../auth/AuthProvider';

type WorkbenchKey = 'onboarding' | 'receivables' | 'dunning' | 'refunds';

const workbenches: Record<WorkbenchKey, {
  title: string;
  description: string;
  matches(operation: PlatformOperation): boolean;
  preferredRead: string;
}> = {
  onboarding: {
    title: '租户开通工作台',
    description: '在一个工作流中完成租户、Owner 激活、试用套餐和收款策略配置。激活令牌只显示一次，请通过安全渠道交付。',
    preferredRead: 'GET /api/platform/tenants',
    matches: (operation) => operation.path.startsWith('/api/platform/tenants') || operation.path === '/api/platform/saas/subscriptions/trial',
  },
  receivables: {
    title: '订阅与应收工作台',
    description: '统一查看商业指标、订阅、订单和应收，并执行暂停、恢复、取消、延长及人工收款。',
    preferredRead: 'GET /api/platform/saas/metrics',
    matches: (operation) => operation.path === '/api/platform/saas/metrics' || operation.path.startsWith('/api/platform/saas/subscriptions') || operation.path.startsWith('/api/platform/saas/orders') || operation.path === '/api/platform/saas/invoices' || operation.path.startsWith('/api/platform/saas/payments'),
  },
  dunning: {
    title: '催缴工作台',
    description: '跟踪提醒、外部投递、失败原因和重试状态；高风险渠道变更和人工重试均需要二次确认。',
    preferredRead: 'GET /api/platform/saas/dunning/events',
    matches: (operation) => operation.path.startsWith('/api/platform/saas/dunning') || operation.path.startsWith('/api/platform/saas/invoices/reminders'),
  },
  refunds: {
    title: '退款工作台',
    description: '按申请、审核、执行和失败重试处理 SaaS 退款；每次申请必须明确服务保持、期末取消或立即终止。',
    preferredRead: 'GET /api/platform/saas/refunds',
    matches: (operation) => operation.path.startsWith('/api/platform/saas/refunds'),
  },
};

function prefill(operation: PlatformOperation, record: Record<string, unknown> | null): OperationInput {
  if (!record) return {};
  const path = Object.fromEntries(operation.parameters
    .filter((parameter) => parameter.in === 'path')
    .map((parameter) => [parameter.name, record[parameter.name] ?? record.id]));
  return { path };
}

function isDangerous(operation: PlatformOperation) {
  return /cancel|suspend|refund|reject|retry|disable|terminate/i.test(`${operation.path} ${operation.summary}`);
}

function statusTimeline(record: Record<string, unknown> | null) {
  if (!record) return [];
  const items = [
    ['创建', record.createdAt],
    ['最近更新', record.updatedAt],
    ['最近尝试', record.lastAttemptAt],
    ['完成', record.completedAt ?? record.sentAt ?? record.paidAt],
  ].filter((item) => item[1]);
  return items.map(([label, value]) => ({ children: `${label}：${String(value)}` }));
}

function GenericCommercialWorkbenchPage({ workbenchKey }: { workbenchKey: Exclude<WorkbenchKey, 'onboarding'> }) {
  const auth = useAuth();
  const definition = workbenches[workbenchKey];
  const operations = useMemo(() => platformOperations.filter((operation) =>
    definition.matches(operation) && (!operation.requiredPermission || auth.hasPermission(operation.requiredPermission))), [auth, definition]);
  const reads = operations.filter((operation) => operation.method === 'GET');
  const writes = operations.filter((operation) => operation.method !== 'GET');
  const [activeReadId, setActiveReadId] = useState(reads.find((item) => item.id === definition.preferredRead)?.id || reads[0]?.id || '');
  const [payload, setPayload] = useState<unknown>();
  const [selected, setSelected] = useState<Record<string, unknown> | null>(null);
  const [action, setAction] = useState<PlatformOperation | null>(null);
  const [loading, setLoading] = useState(false);
  const [filterForm] = Form.useForm<OperationInput>();
  const [actionForm] = Form.useForm<OperationInput>();
  const { message, modal } = App.useApp();
  const activeRead = reads.find((operation) => operation.id === activeReadId) || reads[0];

  const load = async () => {
    if (!activeRead) return;
    setLoading(true);
    try {
      setPayload(await apiRequest(activeRead, normalizeOperationInput(activeRead, filterForm.getFieldsValue(true))));
    } catch (error) {
      message.error(error instanceof Error ? error.message : '工作台数据加载失败');
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    filterForm.resetFields();
    setSelected(null);
    void load();
  }, [activeReadId]);

  const open = (operation: PlatformOperation) => {
    setAction(operation);
    actionForm.resetFields();
    queueMicrotask(() => actionForm.setFieldsValue(prefill(operation, selected)));
  };

  const submit = async () => {
    if (!action) return;
    const input = normalizeOperationInput(action, await actionForm.validateFields());
    const danger = isDangerous(action);
    modal.confirm({
      title: `确认${action.summary}`,
      icon: danger ? <ExclamationCircleOutlined /> : <SafetyCertificateOutlined />,
      content: danger ? '这是商业状态高风险操作。请再次核对租户、金额、订阅影响和原因；执行结果会进入审计日志。' : '提交后会写入平台审计日志，请确认业务信息无误。',
      okText: danger ? '确认并执行' : '确认执行',
      okButtonProps: { danger },
      onOk: async () => {
        setLoading(true);
        try {
          const result = await apiRequest(action, input);
          const approval = pendingApproval(result);
          if (approval) message.info(`高风险操作已提交审批${approval.approvalRequest?.requestNo ? `：${String(approval.approvalRequest.requestNo)}` : ''}，批准后才会执行`);
          else message.success(`${action.summary}完成`);
          setAction(null);
          await load();
        } catch (error) {
          message.error(error instanceof Error ? error.message : '操作失败');
        } finally {
          setLoading(false);
        }
      },
    });
  };

  const metric = payload && typeof payload === 'object' && !Array.isArray(payload) ? payload as Record<string, unknown> : null;
  const rows = rowsFromPayload(payload);
  const failedReason = selected?.lastError ?? selected?.reviewReason;

  return (
    <div className="business-page commercial-workbench">
      <Flex justify="space-between" align="end" gap={16} wrap>
        <div><Typography.Text type="secondary">商业交付</Typography.Text><Typography.Title level={2}>{definition.title}</Typography.Title><Typography.Paragraph type="secondary">{definition.description}</Typography.Paragraph></div>
        <Space wrap>{writes.map((operation) => <Button key={operation.id} danger={isDangerous(operation)} type={isDangerous(operation) ? 'default' : 'primary'} onClick={() => open(operation)}>{operation.summary}</Button>)}</Space>
      </Flex>
      {workbenchKey === 'receivables' && metric && activeRead?.path.endsWith('/metrics') && (
        <Row gutter={[16, 16]}>{['mrrCents', 'arrCents', 'collectedCents', 'outstandingCents', 'overdueCents', 'refundedCents'].map((key) => <Col xs={12} lg={8} xl={4} key={key}><Card><Statistic title={key} value={Number(metric[key] || 0) / 100} prefix="¥" precision={2} /></Card></Col>)}</Row>
      )}
      <Card className="business-card">
        <Tabs activeKey={activeRead?.id} onChange={setActiveReadId} items={reads.map((operation) => ({ key: operation.id, label: operation.summary }))} />
        {activeRead ? <><Form form={filterForm} layout="inline" className="business-filter"><OperationForm operation={activeRead} /><Button icon={<ReloadOutlined />} onClick={() => void load()}>刷新</Button></Form><BusinessTable payload={payload} loading={loading} onSelect={setSelected} /></> : <Empty description="暂无查询接口" />}
      </Card>
      {selected && <Card title="业务状态与审计" extra={<Link to={`/audit?targetId=${String(selected.id ?? selected.tenantId ?? '')}`}><AuditOutlined /> 查看审计</Link>}>
        {Boolean(failedReason) && <Alert type="error" showIcon message="最近失败原因" description={String(failedReason)} />}
        <Row gutter={24}><Col xs={24} lg={14}><Descriptions column={2} size="small" items={Object.entries(selected).filter(([, value]) => value == null || ['string', 'number', 'boolean'].includes(typeof value)).slice(0, 10).map(([key, value]) => ({ key, label: key, children: /status/i.test(key) ? <Tag>{String(value ?? '-')}</Tag> : String(value ?? '-') }))} /></Col><Col xs={24} lg={10}><Timeline items={statusTimeline(selected)} /></Col></Row>
      </Card>}
      <Drawer title={action?.summary} width={640} open={Boolean(action)} onClose={() => setAction(null)} footer={<Flex justify="end" gap={8}><Button onClick={() => setAction(null)}>取消</Button><Button type="primary" danger={action ? isDangerous(action) : false} loading={loading} onClick={() => void submit()}>核对并提交</Button></Flex>}>
        {action && <Form form={actionForm} layout="vertical" requiredMark="optional"><OperationForm operation={action} /></Form>}
      </Drawer>
    </div>
  );
}

export function CommercialWorkbenchPage({ workbenchKey }: { workbenchKey: WorkbenchKey }) {
  return workbenchKey === 'onboarding'
    ? <TenantOnboardingWorkbench />
    : <GenericCommercialWorkbenchPage workbenchKey={workbenchKey} />;
}
