import { PlusOutlined, ReloadOutlined, SearchOutlined } from '@ant-design/icons';
import { App, Button, Card, Drawer, Empty, Flex, Form, Segmented, Space, Tabs, Typography } from 'antd';
import { useEffect, useMemo, useState } from 'react';
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 } from '../components/BusinessTable';
import { OperationForm, normalizeOperationInput } from '../components/OperationForm';
import { businessPages } from './business-definitions';
import { useAuth } from '../auth/AuthProvider';

function prefillFromRecord(operation: PlatformOperation, record: Record<string, unknown> | null): OperationInput {
  if (!record) return {};
  const path: Record<string, unknown> = {};
  for (const parameter of operation.parameters.filter((item) => item.in === 'path')) path[parameter.name] = record[parameter.name] ?? record.id;
  const body: Record<string, unknown> = {};
  const properties = operation.requestSchema && '$ref' in operation.requestSchema ? {} : operation.requestSchema?.properties || {};
  for (const name of Object.keys(properties)) if (record[name] !== undefined) body[name] = record[name];
  return { path, body };
}

export function BusinessPage({ pageKey }: { pageKey: string }) {
  const definition = businessPages.find((page) => page.key === pageKey)!;
  const auth = useAuth();
  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[0]?.id || '');
  const [payload, setPayload] = useState<unknown>();
  const [selectedRecord, setSelectedRecord] = useState<Record<string, unknown> | null>(null);
  const [loading, setLoading] = useState(false);
  const [drawerOperation, setDrawerOperation] = useState<PlatformOperation | null>(null);
  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 runRead = 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(); setPayload(undefined); setSelectedRecord(null); if (activeRead) void runRead(); }, [activeReadId]);

  const openAction = (operation: PlatformOperation) => {
    setDrawerOperation(operation);
    actionForm.resetFields();
    queueMicrotask(() => actionForm.setFieldsValue(prefillFromRecord(operation, selectedRecord)));
  };

  const submitAction = async () => {
    if (!drawerOperation) return;
    const values = normalizeOperationInput(drawerOperation, await actionForm.validateFields());
    modal.confirm({
      title: `确认${drawerOperation.summary}`,
      content: selectedRecord ? '该操作将作用于当前选中的业务记录，并写入平台审计。' : '请确认表单内容无误。',
      okText: '确认执行', cancelText: '取消',
      onOk: async () => {
        setLoading(true);
        try {
          const result = await apiRequest(drawerOperation, values);
          const approval = pendingApproval(result);
          if (approval) message.info(`已提交审批${approval.approvalRequest?.requestNo ? `：${String(approval.approvalRequest.requestNo)}` : ''}，尚未执行`);
          else message.success(`${drawerOperation.summary}完成`);
          setDrawerOperation(null);
          await runRead();
        }
        catch (error) { message.error(error instanceof Error ? error.message : '操作失败'); }
        finally { setLoading(false); }
      },
    });
  };

  return (
    <div className="business-page">
      <Flex justify="space-between" align="end" gap={16} wrap>
        <div><Typography.Text type="secondary">{definition.eyebrow}</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} type={operation.method === 'PUT' || operation.method === 'POST' ? 'primary' : 'default'} icon={<PlusOutlined />} onClick={() => openAction(operation)}>{operation.summary}</Button>)}
        </Space>
      </Flex>
      <Card className="business-card">
        {reads.length > 1 && <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 type="primary" icon={<SearchOutlined />} onClick={() => void runRead()}>查询</Button><Button icon={<ReloadOutlined />} onClick={() => { filterForm.resetFields(); void runRead(); }}>重置</Button></Form>
            <BusinessTable payload={payload} loading={loading} onSelect={setSelectedRecord} />
          </>
        ) : <Empty description="当前业务暂时没有查询接口" />}
      </Card>
      <Drawer title={drawerOperation?.summary} width={600} open={Boolean(drawerOperation)} onClose={() => setDrawerOperation(null)} footer={<Flex justify="end" gap={8}><Button onClick={() => setDrawerOperation(null)}>取消</Button><Button type="primary" loading={loading} onClick={() => void submitAction()}>保存并执行</Button></Flex>}>
        {selectedRecord && <Typography.Paragraph type="secondary">已带入当前选中记录，可在提交前核对或修改。</Typography.Paragraph>}
        {drawerOperation && <Form form={actionForm} layout="vertical" requiredMark="optional"><OperationForm operation={drawerOperation} /></Form>}
      </Drawer>
    </div>
  );
}
