// 采购管理 · 任务工单（业管发起端）
// 设计规范：vm-shared/DESIGN.md · vm-page

import React, { useCallback, useMemo, useState } from 'react';
import dayjs from 'dayjs';
import {
  Alert,
  Button,
  DatePicker,
  Drawer,
  Form,
  Input,
  Modal,
  Progress,
  Select,
  Space,
  Steps,
  Table,
  Tag,
  Timeline,
  Tooltip,
  message,
} from 'antd';
import { TablePagination, DEFAULT_PAGE_SIZE } from '../../common/TablePagination';
import { OperationActions } from '../../common/OperationActions';
import { DateRangeFilterField } from '../vehicle-management/components/DateRangeFilterField';
import {
  EXPORT_ICON,
  KpiCardButton,
  SEARCH_ICON,
  STATUS_KPI_ICONS,
  VIEW_KPI_ICONS,
} from './components/task-work-order-kpi.jsx';
import {
  buildInitialTasks,
  computeMileageProgress,
  CURRENT_USER,
  MOCK_OWNERS,
  MOCK_PURCHASE_CONTRACTS,
  MOCK_VEHICLES,
  ownerName,
  TASK_STATUS_META,
  TASK_TYPE_META,
  vehicleSummary,
} from './data/task-work-order-seed.js';

const { RangePicker } = DatePicker;
const { TextArea } = Input;

const ONEOS_ANT_TABLE_GLOBAL_FIX = [
  '.ant-table-container .ant-table-header { margin-bottom: 0 !important; }',
  '.ant-table-container .ant-table-body { margin-top: 0 !important; }',
  '.ant-table-container .ant-table-body > table, .ant-table-content table { margin-top: 0 !important; }',
  '.ant-table-tbody > tr.ant-table-measure-row, .ant-table-tbody > tr.ant-table-measure-row > td, .ant-table-tbody > tr.ant-table-measure-row > th { display: none !important; height: 0 !important; max-height: 0 !important; min-height: 0 !important; padding: 0 !important; margin: 0 !important; border: none !important; line-height: 0 !important; font-size: 0 !important; overflow: hidden !important; visibility: hidden !important; pointer-events: none !important; }',
  '.vm-list-table .ant-table-thead th,.vm-list-table .ant-table-tbody td{white-space:nowrap;}',
];

const VIEW_KPI_CARDS = [
  { key: 'all', title: '全部', desc: '显示全部任务工单' },
  { key: 'published', title: '我发布的', desc: '仅显示由我发起的任务' },
  { key: 'supervise', title: '我督办的', desc: '仅显示归口责任人为我的任务' },
];

const STATUS_KPI_CARDS = [
  { key: 'pending', title: '待处理', desc: '尚未开始执行的任务' },
  { key: 'overdue', title: '已超时', desc: '超过计划周期或 SLA 的任务' },
  { key: 'in_progress', title: '进行中', desc: '正在执行的任务' },
  { key: 'mileage', title: '里程类', desc: '里程履约类，自动统计车机/GPS 进度' },
];

const CLAUSE_TYPE_OPTIONS = [
  { value: 'mileage', label: '里程履约' },
  { value: 'maintenance', label: '维保履约' },
  { value: 'policy', label: '政策兑现' },
  { value: 'payment', label: '付款节点' },
  { value: 'penalty', label: '条款跟进' },
  { value: 'general', label: '自定义事宜' },
];

function nextTaskCode(tasks) {
  const n = tasks.length + 1;
  return `WO-2026-${String(n).padStart(4, '0')}`;
}

export default function TaskWorkOrderPage() {
  const [tasks, setTasks] = useState(() => buildInitialTasks());
  const [viewTab, setViewTab] = useState('all');
  const [statusKpi, setStatusKpi] = useState(null);
  const [page, setPage] = useState(1);
  const [pageSize, setPageSize] = useState(DEFAULT_PAGE_SIZE);
  const [filterType, setFilterType] = useState(undefined);
  const [filterStatus, setFilterStatus] = useState(undefined);
  const [filterContract, setFilterContract] = useState(undefined);
  const [filterOwner, setFilterOwner] = useState(undefined);
  const [filterKeyword, setFilterKeyword] = useState('');
  const [filterDateRange, setFilterDateRange] = useState({ startDate: '', endDate: '' });
  const [detailTask, setDetailTask] = useState(null);
  const [contractModalOpen, setContractModalOpen] = useState(false);
  const [standaloneModalOpen, setStandaloneModalOpen] = useState(false);
  const [contractStep, setContractStep] = useState(0);
  const [contractForm] = Form.useForm();
  const [standaloneForm] = Form.useForm();

  const enrichedTasks = useMemo(
    () =>
      tasks.map((t) => {
        const progress = computeMileageProgress(t);
        return { ...t, progressInfo: progress };
      }),
    [tasks],
  );

  const filteredTasks = useMemo(() => {
    return enrichedTasks.filter((t) => {
      if (viewTab === 'published' && t.initiatorId !== CURRENT_USER.id) return false;
      if (viewTab === 'supervise' && t.accountableOwnerId !== CURRENT_USER.id) return false;
      if (filterType && t.taskType !== filterType) return false;
      if (filterStatus && t.status !== filterStatus) return false;
      if (filterContract && t.contractId !== filterContract) return false;
      if (filterOwner && t.currentOwnerId !== filterOwner) return false;
      if (filterKeyword) {
        const kw = filterKeyword.trim().toLowerCase();
        if (
          !t.title.toLowerCase().includes(kw) &&
          !t.code.toLowerCase().includes(kw) &&
          !(t.contractCode || '').toLowerCase().includes(kw)
        ) {
          return false;
        }
      }
      if (filterDateRange.startDate && (t.createdAt || '').slice(0, 10) < filterDateRange.startDate) return false;
      if (filterDateRange.endDate && (t.createdAt || '').slice(0, 10) > filterDateRange.endDate) return false;
      if (statusKpi === 'pending' && t.status !== 'pending') return false;
      if (statusKpi === 'overdue' && t.status !== 'overdue') return false;
      if (statusKpi === 'in_progress' && t.status !== 'in_progress') return false;
      if (statusKpi === 'mileage' && t.taskType !== 'mileage') return false;
      return true;
    });
  }, [enrichedTasks, viewTab, filterType, filterStatus, filterContract, filterOwner, filterKeyword, filterDateRange, statusKpi]);

  const viewKpiCounts = useMemo(
    () => ({
      all: enrichedTasks.length,
      published: enrichedTasks.filter((t) => t.initiatorId === CURRENT_USER.id).length,
      supervise: enrichedTasks.filter((t) => t.accountableOwnerId === CURRENT_USER.id).length,
    }),
    [enrichedTasks],
  );

  const statusKpiCounts = useMemo(() => {
    const base = enrichedTasks.filter((t) => {
      if (viewTab === 'published' && t.initiatorId !== CURRENT_USER.id) return false;
      if (viewTab === 'supervise' && t.accountableOwnerId !== CURRENT_USER.id) return false;
      return true;
    });
    return {
      pending: base.filter((t) => t.status === 'pending').length,
      overdue: base.filter((t) => t.status === 'overdue').length,
      in_progress: base.filter((t) => t.status === 'in_progress').length,
      mileage: base.filter((t) => t.taskType === 'mileage').length,
    };
  }, [enrichedTasks, viewTab]);

  const pagedTasks = useMemo(() => {
    const start = (page - 1) * pageSize;
    return filteredTasks.slice(start, start + pageSize);
  }, [filteredTasks, page, pageSize]);

  const resetFilters = useCallback(() => {
    setFilterType(undefined);
    setFilterStatus(undefined);
    setFilterContract(undefined);
    setFilterOwner(undefined);
    setFilterKeyword('');
    setFilterDateRange({ startDate: '', endDate: '' });
    setStatusKpi(null);
    setPage(1);
  }, []);

  const handleUrge = useCallback((task) => {
    const now = dayjs().format('YYYY-MM-DD HH:mm');
    setTasks((prev) =>
      prev.map((t) =>
        t.id === task.id
          ? {
              ...t,
              timeline: [
                ...(t.timeline || []),
                { at: now, action: '催办', operator: CURRENT_USER.name, remark: '已向执行人发送催办，并同步工作台待办' },
              ],
            }
          : t,
      ),
    );
    message.success(`已催办「${task.title}」，执行人将收到待办提醒（原型）`);
  }, []);

  const openContractWizard = useCallback(() => {
    setContractStep(0);
    contractForm.resetFields();
    contractForm.setFieldsValue({
      accountableOwnerId: 'u_chen',
      currentOwnerId: 'u_zhang',
      mileageMode: 'period_avg',
    });
    setContractModalOpen(true);
  }, [contractForm]);

  const openStandalone = useCallback(() => {
    standaloneForm.resetFields();
    standaloneForm.setFieldsValue({
      taskType: 'general',
      accountableOwnerId: CURRENT_USER.id,
      currentOwnerId: 'u_zhao',
    });
    setStandaloneModalOpen(true);
  }, [standaloneForm]);

  const submitContractTask = useCallback(() => {
    contractForm.validateFields().then((values) => {
      const contract = MOCK_PURCHASE_CONTRACTS.find((c) => c.id === values.contractId);
      if (!contract) return;
      const clauseKey = values.clauseType === 'general' ? null : values.clauseType;
      const requirement =
        values.requirement ||
        (clauseKey && contract.clauses[clauseKey]) ||
        values.customRequirement ||
        '—';
      const period = values.period || [];
      const id = `wo-${Date.now()}`;
      const newTask = {
        id,
        code: nextTaskCode(tasks),
        taskType: values.clauseType === 'general' ? 'general' : values.clauseType,
        title: values.title || `${TASK_TYPE_META[values.clauseType]?.label || '任务'} · ${contract.code}`,
        requirement,
        source: 'contract',
        contractId: contract.id,
        contractCode: contract.code,
        vehicleIds: values.vehicleIds || [],
        periodStart: period[0] ? dayjs(period[0]).format('YYYY-MM-DD') : '',
        periodEnd: period[1] ? dayjs(period[1]).format('YYYY-MM-DD') : '',
        mileageTarget: values.mileageTarget,
        mileageMode: values.mileageMode || 'period_avg',
        initiatorId: CURRENT_USER.id,
        accountableOwnerId: values.accountableOwnerId,
        currentOwnerId: values.currentOwnerId,
        status: 'pending',
        createdAt: dayjs().format('YYYY-MM-DD HH:mm'),
        feedbacks: [],
        timeline: [
          {
            at: dayjs().format('YYYY-MM-DD HH:mm'),
            action: '发布任务',
            operator: CURRENT_USER.name,
            remark: `自采购合同 ${contract.code} 发起`,
          },
        ],
        syncWorkbench: true,
      };
      setTasks((prev) => [newTask, ...prev]);
      setContractModalOpen(false);
      message.success('任务已发布，已同步至执行人工作台待办（原型）');
    });
  }, [contractForm, tasks]);

  const submitStandaloneTask = useCallback(() => {
    standaloneForm.validateFields().then((values) => {
      const contract = values.contractId
        ? MOCK_PURCHASE_CONTRACTS.find((c) => c.id === values.contractId)
        : null;
      const period = values.period || [];
      const newTask = {
        id: `wo-${Date.now()}`,
        code: nextTaskCode(tasks),
        taskType: values.taskType,
        title: values.title,
        requirement: values.requirement,
        source: 'standalone',
        contractId: contract?.id,
        contractCode: contract?.code,
        vehicleIds: values.vehicleIds || [],
        periodStart: period[0] ? dayjs(period[0]).format('YYYY-MM-DD') : '',
        periodEnd: period[1] ? dayjs(period[1]).format('YYYY-MM-DD') : '',
        mileageTarget: values.mileageTarget,
        mileageMode: values.mileageMode,
        initiatorId: CURRENT_USER.id,
        accountableOwnerId: values.accountableOwnerId,
        currentOwnerId: values.currentOwnerId,
        status: 'pending',
        createdAt: dayjs().format('YYYY-MM-DD HH:mm'),
        feedbacks: [],
        timeline: [
          {
            at: dayjs().format('YYYY-MM-DD HH:mm'),
            action: '独立新增',
            operator: CURRENT_USER.name,
            remark: contract ? `反向关联 ${contract.code}` : '未关联合同',
          },
        ],
        syncWorkbench: true,
      };
      setTasks((prev) => [newTask, ...prev]);
      setStandaloneModalOpen(false);
      message.success('独立任务已创建，已同步工作台待办（原型）');
    });
  }, [standaloneForm, tasks]);

  const contractWatchId = Form.useWatch('contractId', contractForm);
  const contractWatchType = Form.useWatch('clauseType', contractForm);
  const standaloneWatchType = Form.useWatch('taskType', standaloneForm);

  const contractVehicles = useMemo(
    () => MOCK_VEHICLES.filter((v) => !contractWatchId || v.contractId === contractWatchId),
    [contractWatchId],
  );

  const selectedContract = MOCK_PURCHASE_CONTRACTS.find((c) => c.id === contractWatchId);

  const columns = [
    {
      title: '工单号',
      dataIndex: 'code',
      width: 130,
      fixed: 'left',
      render: (v) => <span style={{ fontVariantNumeric: 'tabular-nums', fontWeight: 600 }}>{v}</span>,
    },
    {
      title: '类型',
      dataIndex: 'taskType',
      width: 96,
      render: (v) => {
        const m = TASK_TYPE_META[v] || { label: v, color: 'default' };
        return <Tag color={m.color}>{m.label}</Tag>;
      },
    },
    {
      title: '任务摘要',
      dataIndex: 'title',
      ellipsis: true,
      render: (v, r) => (
        <Tooltip title={r.requirement}>
          <span>{v}</span>
        </Tooltip>
      ),
    },
    {
      title: '关联合同',
      dataIndex: 'contractCode',
      width: 150,
      render: (v, r) =>
        v ? (
          <Tooltip title="业管可见；执行人不可查看合同原文">
            <Tag>{v}</Tag>
          </Tooltip>
        ) : (
          <span style={{ color: '#94a3b8' }}>—</span>
        ),
    },
    {
      title: '绑定车辆',
      dataIndex: 'vehicleIds',
      width: 120,
      render: (ids) => vehicleSummary(ids),
    },
    {
      title: '执行周期',
      width: 180,
      render: (_, r) =>
        r.periodStart && r.periodEnd ? (
          <span style={{ fontSize: 12, fontVariantNumeric: 'tabular-nums' }}>
            {r.periodStart} 至 {r.periodEnd}
          </span>
        ) : (
          '—'
        ),
    },
    {
      title: '当前执行人',
      dataIndex: 'currentOwnerId',
      width: 96,
      render: (id) => ownerName(id),
    },
    {
      title: '归口负责',
      dataIndex: 'accountableOwnerId',
      width: 96,
      render: (id) => ownerName(id),
    },
    {
      title: '进度',
      width: 140,
      render: (_, r) => {
        if (r.taskType === 'mileage' && r.progressInfo) {
          return (
            <div className="two-progress-cell">
              <Progress
                percent={r.progressInfo.percent}
                size="small"
                status={r.status === 'overdue' ? 'exception' : undefined}
                aria-label={`里程进度 ${r.progressInfo.percent}%`}
              />
              <div className="two-progress-meta">{r.progressInfo.label}</div>
            </div>
          );
        }
        return <span style={{ color: '#94a3b8' }}>手动跟踪</span>;
      },
    },
    {
      title: '状态',
      dataIndex: 'status',
      width: 88,
      render: (v) => {
        const m = TASK_STATUS_META[v] || { label: v, color: 'default' };
        return <Tag color={m.color}>{m.label}</Tag>;
      },
    },
    {
      title: '操作',
      width: 168,
      fixed: 'right',
      render: (_, r) => (
        <OperationActions
          view={{ label: '详情', onClick: () => setDetailTask(r) }}
          more={
            r.status !== 'completed' && r.status !== 'closed'
              ? [{ key: 'urge', label: '催办', onClick: () => handleUrge(r) }]
              : []
          }
        />
      ),
    },
  ];

  const handleStatusKpiClick = useCallback((key) => {
    setStatusKpi((prev) => (prev === key ? null : key));
    setPage(1);
  }, []);

  return (
    <div
      className="vm-page lc-page lc-page--list-dense two-page"
      style={{ '--lc-list-chrome-offset': '434px', '--two-list-chrome-offset': '434px' }}
      data-annotation-id="two-list"
    >
      <style>{ONEOS_ANT_TABLE_GLOBAL_FIX.join('\n')}</style>
      <section className="vm-filter-card ldb-filter-card" data-annotation-id="two-filter" aria-label="筛选条件">
        <header className="vm-filter-header">
          <h2 className="vm-filter-title">筛选条件</h2>
        </header>
        <div className="ldb-filter-body">
        <div className="vm-filter-grid ldb-filter-grid ldb-filter-grid--primary">
          <div className="vm-filter-field">
            <label className="vm-filter-label">任务类型</label>
            <Select
              allowClear
              placeholder="全部"
              value={filterType}
              onChange={setFilterType}
              options={Object.entries(TASK_TYPE_META).map(([value, m]) => ({ value, label: m.label }))}
              className="vm-filter-control"
            />
          </div>
          <div className="vm-filter-field">
            <label className="vm-filter-label">状态</label>
            <Select
              allowClear
              placeholder="全部"
              value={filterStatus}
              onChange={setFilterStatus}
              options={Object.entries(TASK_STATUS_META).map(([value, m]) => ({ value, label: m.label }))}
              className="vm-filter-control"
            />
          </div>
          <div className="vm-filter-field">
            <label className="vm-filter-label">采购合同</label>
            <Select
              allowClear
              placeholder="全部"
              value={filterContract}
              onChange={setFilterContract}
              options={MOCK_PURCHASE_CONTRACTS.map((c) => ({ value: c.id, label: c.code }))}
              className="vm-filter-control"
            />
          </div>
          <div className="vm-filter-field">
            <label className="vm-filter-label">当前执行人</label>
            <Select
              allowClear
              placeholder="全部"
              value={filterOwner}
              onChange={setFilterOwner}
              options={MOCK_OWNERS.map((o) => ({ value: o.id, label: `${o.name}（${o.dept}）` }))}
              className="vm-filter-control"
            />
          </div>
          <div className="vm-filter-field">
            <label className="vm-filter-label">创建时间</label>
            <DateRangeFilterField value={filterDateRange} onChange={setFilterDateRange} />
          </div>
          <div className="vm-filter-field">
            <label className="vm-filter-label">关键词</label>
            <Input
              allowClear
              placeholder="工单号 / 任务名 / 合同号"
              value={filterKeyword}
              onChange={(e) => setFilterKeyword(e.target.value)}
              className="vm-filter-control"
            />
          </div>
        </div>
        </div>
        <div className="vm-filter-actions ldb-filter-actions">
          <button type="button" className="vm-btn vm-btn-ghost ldb-toolbar-btn" onClick={resetFilters} data-vm-icon="rotate-ccw">
            重置
          </button>
          <button type="button" className="vm-btn vm-btn-primary ldb-toolbar-btn" onClick={() => setPage(1)} data-vm-icon="search">
            查询
          </button>
        </div>
      </section>

      <div
        className="vm-kpi-row vm-kpi-row--with-view"
        role="group"
        aria-label="任务统计"
        data-annotation-id="two-kpi"
      >
        {VIEW_KPI_CARDS.map((card) => (
          <KpiCardButton
            key={card.key}
            className="two-kpi-view-card"
            active={viewTab === card.key}
            icon={VIEW_KPI_ICONS[card.key]}
            title={card.title}
            count={viewKpiCounts[card.key] ?? 0}
            desc={card.desc}
            onClick={() => {
              setViewTab(card.key);
              setPage(1);
            }}
          />
        ))}
        {STATUS_KPI_CARDS.map((card) => (
          <KpiCardButton
            key={card.key}
            active={statusKpi === card.key}
            icon={STATUS_KPI_ICONS[card.key]}
            title={card.title}
            count={statusKpiCounts[card.key] ?? 0}
            desc={card.desc}
            onClick={() => handleStatusKpiClick(card.key)}
          />
        ))}
      </div>

      <section className="vm-table-section" data-annotation-id="two-table">
        <div className="vm-table-toolbar">
          <div className="vm-table-actions">
            <button
              type="button"
              className="vm-btn vm-btn-ghost ldb-toolbar-btn"
              onClick={() => message.info('根据筛选条件，导出相应记录（原型）')}
              data-vm-icon="download"
            >
              导出
            </button>
            <button type="button" className="vm-btn vm-btn-ghost ldb-toolbar-btn" onClick={openStandalone} data-vm-icon="plus">
              独立新增
            </button>
            <button type="button" className="vm-btn vm-btn-primary ldb-toolbar-btn" onClick={openContractWizard} data-vm-icon="plus">
              从采购合同发起
            </button>
          </div>
        </div>
        <div className="vm-table-card">
          <div className="vm-table-wrap">
            <Table
              rowKey="id"
              className="vm-list-table two-list-table lc-list-table--nested"
              columns={columns}
              dataSource={pagedTasks}
              pagination={false}
              tableLayout="fixed"
              scroll={{
                x: 1400,
                y: 'max(calc(100vh - var(--lc-list-chrome-offset, 434px)), 240px)',
              }}
              size="small"
            />
          </div>
          <div className="vm-table-footer">
            <TablePagination
              total={filteredTasks.length}
              page={page}
              pageSize={pageSize}
              onPageChange={setPage}
              onPageSizeChange={(ps) => {
                setPageSize(ps);
                setPage(1);
              }}
            />
          </div>
        </div>
      </section>

      <Drawer
        title="任务督办详情"
        width={560}
        open={!!detailTask}
        onClose={() => setDetailTask(null)}
        destroyOnClose
        extra={
          detailTask && detailTask.status !== 'completed' && detailTask.status !== 'closed' ? (
            <Button type="primary" onClick={() => handleUrge(detailTask)}>
              催办
            </Button>
          ) : null
        }
      >
        {detailTask && (
          <>
            <Alert
              type="info"
              showIcon
              message={`发起人：${ownerName(detailTask.initiatorId)} · 归口：${ownerName(detailTask.accountableOwnerId)} · 执行：${ownerName(detailTask.currentOwnerId)}`}
              style={{ marginBottom: 16 }}
            />
            <div className="two-permission-hint">
              执行人在 OneOS 任务执行页 / 小羚羚小程序 / 工作台待办中处理本任务，<strong>不可查看合同原文与金额</strong>。
            </div>

            <div className="two-drawer-section">
              <div className="two-drawer-section__title">
                {TASK_TYPE_META[detailTask.taskType]?.label} ·{' '}
                <Tag color={TASK_STATUS_META[detailTask.status]?.color}>
                  {TASK_STATUS_META[detailTask.status]?.label}
                </Tag>
              </div>
              <div style={{ fontWeight: 600, fontSize: 16, marginBottom: 8 }}>{detailTask.title}</div>
              <div className="two-clause-box">{detailTask.requirement}</div>
            </div>

            {detailTask.contractCode && (
              <div className="two-drawer-section">
                <div className="two-drawer-section__title">来源合同（仅业管可见）</div>
                <Tag color="blue">{detailTask.contractCode}</Tag>
                <span style={{ marginLeft: 8, fontSize: 12, color: '#64748b' }}>
                  {detailTask.source === 'standalone' ? '独立任务反向关联' : '合同发起'}
                </span>
              </div>
            )}

            <div className="two-drawer-section">
              <div className="two-drawer-section__title">执行周期</div>
              <span style={{ fontVariantNumeric: 'tabular-nums' }}>
                {detailTask.periodStart || '—'} 至 {detailTask.periodEnd || '—'}
              </span>
            </div>

            {(detailTask.vehicleIds || []).length > 0 && (
              <div className="two-drawer-section">
                <div className="two-drawer-section__title">绑定车辆</div>
                {MOCK_VEHICLES.filter((v) => detailTask.vehicleIds.includes(v.id)).map((v) => (
                  <span key={v.id} className="two-vehicle-chip">
                    {v.plateNo} · {v.model} · {v.mileage.toLocaleString()} km（{v.mileageSource}）
                  </span>
                ))}
              </div>
            )}

            {detailTask.taskType === 'mileage' && detailTask.progressInfo && (
              <div className="two-drawer-section">
                <div className="two-drawer-section__title">里程进度（自动）</div>
                <Progress percent={detailTask.progressInfo.percent} />
                <div className="two-progress-meta">{detailTask.progressInfo.label}</div>
              </div>
            )}

            <div className="two-drawer-section">
              <div className="two-drawer-section__title">执行反馈</div>
              {(detailTask.feedbacks || []).length === 0 ? (
                <span style={{ color: '#94a3b8' }}>暂无反馈</span>
              ) : (
                (detailTask.feedbacks || []).map((f, i) => (
                  <div key={i} className="two-clause-box" style={{ marginBottom: 8 }}>
                    <div style={{ fontSize: 12, color: '#64748b', marginBottom: 4 }}>
                      {f.at} · {f.by}
                    </div>
                    {f.note}
                    {f.attachments?.length ? (
                      <div style={{ marginTop: 6, fontSize: 12 }}>附件：{f.attachments.join('、')}</div>
                    ) : null}
                  </div>
                ))
              )}
            </div>

            <div className="two-drawer-section">
              <div className="two-drawer-section__title">操作时间线</div>
              <Timeline
                items={(detailTask.timeline || []).map((ev) => ({
                  children: (
                    <div className="two-timeline-item">
                      <div style={{ fontWeight: 500 }}>
                        {ev.action} · {ev.operator}
                      </div>
                      <div style={{ fontSize: 12, color: '#64748b' }}>{ev.at}</div>
                      {ev.remark ? <div style={{ marginTop: 4 }}>{ev.remark}</div> : null}
                    </div>
                  ),
                }))}
              />
            </div>

            {detailTask.syncWorkbench && (
              <Alert type="success" showIcon message="已同步至执行人工作台待办；小羚羚小程序待办（后续联调）" />
            )}
          </>
        )}
      </Drawer>

      <Modal
        title="从采购合同发起任务"
        open={contractModalOpen}
        onCancel={() => setContractModalOpen(false)}
        width={640}
        footer={
          <Space>
            <Button onClick={() => setContractModalOpen(false)}>取消</Button>
            {contractStep > 0 && (
              <Button onClick={() => setContractStep((s) => s - 1)}>上一步</Button>
            )}
            {contractStep < 2 ? (
              <Button type="primary" onClick={() => setContractStep((s) => s + 1)}>
                下一步
              </Button>
            ) : (
              <Button type="primary" onClick={submitContractTask}>
                发布任务
              </Button>
            )}
          </Space>
        }
        destroyOnClose
      >
        <Steps
          current={contractStep}
          size="small"
          style={{ marginBottom: 20 }}
          items={[{ title: '选合同与条款' }, { title: '周期与车辆' }, { title: '指派负责人' }]}
        />
        <Form form={contractForm} layout="vertical">
          {contractStep === 0 && (
            <>
              <div className="two-wizard-step-hint">选择采购合同与要发布的条款类型；条款正文将转为执行摘要，执行人不可见合同原文。</div>
              <Form.Item name="contractId" label="采购合同" rules={[{ required: true }]}>
                <Select
                  placeholder="选择合同"
                  options={MOCK_PURCHASE_CONTRACTS.map((c) => ({
                    value: c.id,
                    label: `${c.code} · ${c.vehicleModel} × ${c.quantity}`,
                  }))}
                />
              </Form.Item>
              <Form.Item name="clauseType" label="条款类型" rules={[{ required: true }]}>
                <Select options={CLAUSE_TYPE_OPTIONS} placeholder="选择类型" />
              </Form.Item>
              {selectedContract && contractWatchType && contractWatchType !== 'general' && (
                <Form.Item label="条款摘要（来自合同，可微调）" name="requirement" initialValue={selectedContract.clauses[contractWatchType]}>
                  <TextArea rows={4} />
                </Form.Item>
              )}
              <Form.Item name="title" label="任务名称">
                <Input placeholder="留空则自动生成" />
              </Form.Item>
            </>
          )}
          {contractStep === 1 && (
            <>
              <div className="two-wizard-step-hint">执行周期由业管自定义，可跨月、跨年，系统不做限制。</div>
              <Form.Item name="period" label="执行周期" rules={[{ required: true, message: '请选择起止日期' }]}>
                <RangePicker style={{ width: '100%' }} />
              </Form.Item>
              <Form.Item name="vehicleIds" label="绑定车辆">
                <Select
                  mode="multiple"
                  placeholder="选择采购车辆"
                  options={contractVehicles.map((v) => ({
                    value: v.id,
                    label: `${v.plateNo} · ${v.model}`,
                  }))}
                />
              </Form.Item>
              {(contractWatchType === 'mileage' || contractWatchType === 'policy') && (
                <>
                  <Form.Item name="mileageTarget" label="里程目标（km）" rules={[{ required: true }]}>
                    <Input type="number" placeholder="如 6000 或 150000" />
                  </Form.Item>
                  <Form.Item name="mileageMode" label="统计方式">
                    <Select
                      options={[
                        { value: 'period_avg', label: '周期内单车均值（适合月度/季度）' },
                        { value: 'cumulative', label: '累计里程（适合跨年长期跟踪）' },
                      ]}
                    />
                  </Form.Item>
                </>
              )}
            </>
          )}
          {contractStep === 2 && (
            <>
              <Form.Item name="currentOwnerId" label="当前执行人" rules={[{ required: true }]}>
                <Select options={MOCK_OWNERS.map((o) => ({ value: o.id, label: `${o.name}（${o.dept}）` }))} />
              </Form.Item>
              <Form.Item name="accountableOwnerId" label="归口责任人（固定，不因转交变更）" rules={[{ required: true }]}>
                <Select options={MOCK_OWNERS.map((o) => ({ value: o.id, label: `${o.name}（${o.dept}）` }))} />
              </Form.Item>
              <Alert type="info" showIcon message="发布后任务将同步至执行人工作台待办；执行页与小羚羚小程序为后续迭代。" />
            </>
          )}
        </Form>
      </Modal>

      <Modal
        title="独立新增任务"
        open={standaloneModalOpen}
        onCancel={() => setStandaloneModalOpen(false)}
        onOk={submitStandaloneTask}
        okText="发布"
        width={600}
        destroyOnClose
      >
        <Form form={standaloneForm} layout="vertical">
          <Form.Item name="title" label="任务名称" rules={[{ required: true }]}>
            <Input placeholder="简述要办理的事宜" />
          </Form.Item>
          <Form.Item name="requirement" label="执行要求" rules={[{ required: true }]}>
            <TextArea rows={3} placeholder="执行人可见的说明（不含合同金额）" />
          </Form.Item>
          <Form.Item name="taskType" label="任务类型" rules={[{ required: true }]}>
            <Select options={Object.entries(TASK_TYPE_META).map(([value, m]) => ({ value, label: m.label }))} />
          </Form.Item>
          <Form.Item name="contractId" label="反向关联采购合同（可选）">
            <Select
              allowClear
              placeholder="可不关联"
              options={MOCK_PURCHASE_CONTRACTS.map((c) => ({ value: c.id, label: c.code }))}
            />
          </Form.Item>
          <Form.Item name="period" label="计划周期">
            <RangePicker style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item name="vehicleIds" label="绑定车辆（可选）">
            <Select
              mode="multiple"
              options={MOCK_VEHICLES.map((v) => ({ value: v.id, label: `${v.plateNo} · ${v.model}` }))}
            />
          </Form.Item>
          {standaloneWatchType === 'mileage' && (
            <>
              <Form.Item name="mileageTarget" label="里程目标（km）">
                <Input type="number" />
              </Form.Item>
              <Form.Item name="mileageMode" label="统计方式">
                <Select
                  options={[
                    { value: 'period_avg', label: '周期内单车均值' },
                    { value: 'cumulative', label: '累计里程' },
                  ]}
                />
              </Form.Item>
            </>
          )}
          <Form.Item name="currentOwnerId" label="当前执行人" rules={[{ required: true }]}>
            <Select options={MOCK_OWNERS.map((o) => ({ value: o.id, label: `${o.name}（${o.dept}）` }))} />
          </Form.Item>
          <Form.Item name="accountableOwnerId" label="归口责任人" rules={[{ required: true }]}>
            <Select options={MOCK_OWNERS.map((o) => ({ value: o.id, label: `${o.name}（${o.dept}）` }))} />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
}
