import { useEffect, useRef, useState } from 'react';
import {
  Button, Checkbox, Form, Input, Modal, Popconfirm, Radio, Select, Switch, Tabs, Tag, Upload, message,
} from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import type { UploadFile } from 'antd';
import { ProTable, type ActionType, type ProColumns } from '@ant-design/pro-components';
import dayjs from 'dayjs';
import {
  listLampTests,
  createLampTest,
  updateLampTest,
  deleteLampTest,
  listLampSteps,
  updateLampStep,
  uploadLampResultImage,
  judgeQPCR,
  uploadLampSpectrum,
  listSpectrumEntries,
  createSpectrumEntry,
  uploadSpectrumEntryFile,
  deleteSpectrumEntry,
  type LampTest,
  type LampTestStep,
  type SpectrumEntry,
} from '../dal/lamp';
import { listDiseases } from '../dal/knowledge';
import { listHouses, type SilkwormHouse } from '../dal/silkworm';
import { listBatches, type Batch } from '../dal/trayBatch';
import { authService } from '../services/auth';

const STATUS_LABELS: Record<string, string> = {
  pending: '待检测',
  testing: '检测中',
  resulted: '已出结果',
};

const RESULT_LABELS: Record<string, string> = {
  positive: '阳性',
  negative: '阴性',
  invalid: '无效',
};

const METHOD_LABELS: Record<string, string> = {
  lamp: 'LAMP',
  qpcr: 'qPCR',
  sers: 'SERS',
  hyperspectral: '高光谱',
};

const canWrite = () => authService.hasPermission('lamp:write');

function LampTab() {
  const [rooms, setRooms] = useState<SilkwormHouse[]>([]);
  const [batches, setBatches] = useState<Batch[]>([]);
  const [diseaseOptions, setDiseaseOptions] = useState<{ value: string; label: string }[]>([]);
  const actionRef = useRef<ActionType>();
  const [createOpen, setCreateOpen] = useState(false);
  const [createForm] = Form.useForm<Partial<LampTest>>();
  const [resultOpen, setResultOpen] = useState(false);
  const [resultForm] = Form.useForm<Partial<LampTest>>();
  const [resultTarget, setResultTarget] = useState<LampTest | null>(null);
  const [imageList, setImageList] = useState<UploadFile[]>([]);
  const [stepsOpen, setStepsOpen] = useState(false);
  const [stepsTarget, setStepsTarget] = useState<LampTest | null>(null);
  const [steps, setSteps] = useState<LampTestStep[]>([]);
  const [ctValues, setCtValues] = useState('');
  const [threshold, setThreshold] = useState<number>(35);

  useEffect(() => {
    Promise.all([
      listHouses().catch(() => ({ items: [] as SilkwormHouse[] })),
      listBatches().catch(() => [] as Batch[]),
      listDiseases().catch(() => [] as any[]),
    ]).then(([houseRes, batchRes, diseaseRes]) => {
      setRooms(houseRes.items);
      setBatches(batchRes);
      setDiseaseOptions(diseaseRes.map((d: any) => ({ value: d.name, label: d.name })));
    });
  }, []);

  const roomName = (id?: string) => rooms.find((r) => r.id === id)?.name || id || '-';
  const roomEnum = Object.fromEntries(rooms.map((r) => [r.id, { text: r.name }]));

  const openSteps = async (t: LampTest) => {
    setStepsTarget(t);
    setSteps(await listLampSteps(t.id).catch(() => [] as LampTestStep[]));
    setStepsOpen(true);
  };

  const openResult = (t: LampTest) => {
    setResultTarget(t);
    resultForm.setFieldsValue({ result: t.result });
    setImageList(
      t.resultImageUrl ? [{ uid: '-1', name: '结果照片', status: 'done', url: t.resultImageUrl }] : [],
    );
    setResultOpen(true);
  };

  const columns: ProColumns<LampTest>[] = [
    { title: '序号', valueType: 'indexBorder', search: false, width: 60 },
    { title: '方式', dataIndex: 'method', search: false, width: 90, render: (_, r) => <Tag>{METHOD_LABELS[r.method || 'lamp']}</Tag> },
    { title: '蚕房', dataIndex: 'roomId', valueType: 'select', valueEnum: roomEnum, render: (_, r) => roomName(r.roomId) },
    { title: '检测病种', dataIndex: 'diseases', search: false, render: (_, r) => (r.diseases || []).join('、') || '-' },
    { title: '采样信息', dataIndex: 'sampleInfo', search: false, render: (_, r) => r.sampleInfo || '-' },
    {
      title: '状态',
      dataIndex: 'status',
      valueType: 'select',
      valueEnum: Object.fromEntries(Object.entries(STATUS_LABELS).map(([k, v]) => [k, { text: v }])),
      render: (_, r) => <Tag color={r.status === 'resulted' ? 'green' : 'default'}>{STATUS_LABELS[r.status] || r.status}</Tag>,
    },
    { title: '结果', dataIndex: 'result', search: false, render: (_, r) => (r.result ? RESULT_LABELS[r.result] || r.result : '-') },
    {
      title: '交叉验证',
      dataIndex: 'crossStatus',
      search: false,
      render: (_, r) =>
        r.crossStatus === 'consistent' ? (
          <Tag color="green">一致</Tag>
        ) : r.crossStatus === 'inconsistent' ? (
          <Tag color="red">不一致</Tag>
        ) : (
          '-'
        ),
    },
    { title: '创建时间', dataIndex: 'createdAt', search: false, render: (_, r) => (r.createdAt ? dayjs(r.createdAt).format('YYYY-MM-DD HH:mm') : '-') },
    {
      title: '操作',
      valueType: 'option',
      render: (_, r) => [
        <a key="steps" onClick={() => openSteps(r)}>
          步骤
        </a>,
        <a key="result" onClick={() => openResult(r)}>
          结果
        </a>,
        ...(canWrite()
          ? [
              <Popconfirm
                key="del"
                title="确认删除该任务单？"
                onConfirm={async () => {
                  await deleteLampTest(r.id);
                  message.success('已删除');
                  actionRef.current?.reload();
                }}
              >
                <a style={{ color: '#ff4d4f' }}>删除</a>
              </Popconfirm>,
            ]
          : []),
      ],
    },
  ];

  return (
    <>
      <ProTable<LampTest>
        actionRef={actionRef}
        rowKey="id"
        columns={columns}
        search={{ labelWidth: 'auto' }}
        request={async (params) => {
          const res = await listLampTests({ roomId: params.roomId, status: params.status });
          return { data: res, total: res.length, success: true };
        }}
        toolBarRender={() =>
          canWrite()
            ? [
                <Button
                  key="new"
                  type="primary"
                  icon={<PlusOutlined />}
                  onClick={() => {
                    createForm.resetFields();
                    setCreateOpen(true);
                  }}
                >
                  新建任务单
                </Button>,
              ]
            : []
        }
      />

      <Modal
        title="新建 LAMP 检测任务单"
        open={createOpen}
        onCancel={() => setCreateOpen(false)}
        onOk={async () => {
          const v = await createForm.validateFields();
          await createLampTest(v);
          message.success('已创建（自动生成 5 步流程）');
          setCreateOpen(false);
          actionRef.current?.reload();
        }}
      >
        <Form form={createForm} layout="vertical">
          <Form.Item label="蚕房" name="roomId">
            <Select allowClear options={rooms.map((r) => ({ value: r.id, label: r.name }))} />
          </Form.Item>
          <Form.Item label="检测方式" name="method" initialValue="lamp">
            <Select options={Object.entries(METHOD_LABELS).map(([value, label]) => ({ value, label }))} />
          </Form.Item>
          <Form.Item label="蚕种批次" name="batchId">
            <Select
              allowClear
              options={batches.map((b) => ({ value: b.id, label: b.name }))}
            />
          </Form.Item>
          <Form.Item label="检测病种" name="diseases" rules={[{ required: true, message: '请选择检测病种' }]}>
            <Checkbox.Group options={diseaseOptions} />
          </Form.Item>
          <Form.Item label="采样信息" name="sampleInfo">
            <Input placeholder="如：5龄第3天，1号匾" />
          </Form.Item>
          <Form.Item label="备注" name="note">
            <Input.TextArea rows={2} />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title={`结果录入 - ${resultTarget ? roomName(resultTarget.roomId) : ''}`}
        open={resultOpen}
        onCancel={() => setResultOpen(false)}
        onOk={async () => {
          if (!resultTarget) return;
          const v = await resultForm.validateFields();
          await updateLampTest(resultTarget.id, { result: v.result });
          message.success('结果已保存');
          setResultOpen(false);
          actionRef.current?.reload();
        }}
      >
        <Form form={resultForm} layout="vertical">
          <Form.Item label="检测结果" name="result" rules={[{ required: true, message: '请选择结果' }]}>
            {resultTarget?.method === 'qpcr' ? (
              <div style={{ display: 'flex', gap: 8 }}>
                <Input
                  placeholder="Ct 值，逗号分隔，如 32,35"
                  value={ctValues}
                  onChange={(e) => setCtValues(e.target.value)}
                  style={{ flex: 1 }}
                />
                <Input
                  type="number"
                  placeholder="阈值"
                  value={threshold}
                  onChange={(e) => setThreshold(Number(e.target.value))}
                  style={{ width: 90 }}
                />
                <Button
                  onClick={async () => {
                    if (!resultTarget) return;
                    const cts = ctValues
                      .split(/[,，\s]+/)
                      .filter(Boolean)
                      .map(Number);
                    const updated = await judgeQPCR(resultTarget.id, cts, threshold);
                    message.success(`自动判读：${RESULT_LABELS[updated.result || ''] || updated.result}`);
                    resultForm.setFieldsValue({ result: updated.result });
                    setResultTarget({ ...resultTarget, ...updated });
                  }}
                >
                  自动判读
                </Button>
              </div>
            ) : (
              <Radio.Group
                options={[
                  { value: 'positive', label: '阳性' },
                  { value: 'negative', label: '阴性' },
                  { value: 'invalid', label: '无效' },
                ]}
              />
            )}
          </Form.Item>
          {resultTarget?.method === 'sers' ? (
            <Form.Item label="光谱数据文件">
              <Upload
                maxCount={1}
                accept=".csv,.txt,.json"
                customRequest={async ({ file, onSuccess, onError }) => {
                  if (!resultTarget) return;
                  try {
                    const res = await uploadLampSpectrum(resultTarget.id, file as File);
                    message.success('光谱已上传');
                    onSuccess?.(res);
                  } catch (e) {
                    onError?.(e as Error);
                  }
                }}
              >
                <Button icon={<PlusOutlined />}>上传光谱（csv/txt/json）</Button>
              </Upload>
            </Form.Item>
          ) : null}
          {resultTarget?.crossStatus && resultTarget.crossStatus !== 'pending' ? (
            <div style={{ marginBottom: 12 }}>
              <Tag color={resultTarget.crossStatus === 'consistent' ? 'green' : 'red'}>
                {resultTarget.crossStatus === 'consistent' ? '交叉验证：一致' : '交叉验证：不一致'}
              </Tag>
              {resultTarget.crossReason ? (
                <span style={{ marginLeft: 8, color: '#666' }}>{resultTarget.crossReason}</span>
              ) : null}
            </div>
          ) : null}
          <Form.Item label="结果照片">
            <Upload
              listType="picture-card"
              maxCount={1}
              accept=".jpg,.jpeg,.png,.webp"
              fileList={imageList}
              customRequest={async ({ file, onSuccess, onError }) => {
                if (!resultTarget) return;
                try {
                  const res = await uploadLampResultImage(resultTarget.id, file as File);
                  setImageList([{ uid: '-1', name: '结果照片', status: 'done', url: res.url }]);
                  onSuccess?.(res);
                } catch (e) {
                  onError?.(e as Error);
                }
              }}
              onRemove={() => setImageList([])}
            >
              {imageList.length >= 1 ? null : (
                <div>
                  <PlusOutlined />
                  <div style={{ marginTop: 8 }}>上传</div>
                </div>
              )}
            </Upload>
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title={`操作步骤 - ${stepsTarget ? roomName(stepsTarget.roomId) : ''}`}
        open={stepsOpen}
        onCancel={() => setStepsOpen(false)}
        footer={null}
      >
        {steps.map((s) => (
          <div
            key={s.id}
            style={{
              display: 'flex',
              alignItems: 'center',
              gap: 12,
              padding: '8px 0',
              borderBottom: '1px solid #f0f0f0',
            }}
          >
            <Tag>{`${s.stepNo}. ${s.name}`}</Tag>
            <Switch
              checked={s.done}
              onChange={async (done) => {
                await updateLampStep(s.lampTestId, s.stepNo, { done });
                setSteps(await listLampSteps(s.lampTestId));
                message.success('已更新');
              }}
            />
          </div>
        ))}
      </Modal>
    </>
  );
}

function SpectrumTab() {
  const actionRef = useRef<ActionType>();
  const [modalOpen, setModalOpen] = useState(false);
  const [form] = Form.useForm<Partial<SpectrumEntry>>();
  const [uploadedUrl, setUploadedUrl] = useState('');

  const columns: ProColumns<SpectrumEntry>[] = [
    { title: '序号', valueType: 'indexBorder', search: false, width: 60 },
    { title: '病种', dataIndex: 'disease' },
    { title: '来源', dataIndex: 'source', search: false, render: (_, r) => r.source || '-' },
    { title: '数据文件', dataIndex: 'dataUrl', search: false, render: (_, r) => (r.dataUrl ? <a href={r.dataUrl} target="_blank" rel="noreferrer">查看</a> : '-') },
    { title: '备注', dataIndex: 'note', search: false, render: (_, r) => r.note || '-' },
    {
      title: '操作',
      valueType: 'option',
      render: (_, r) => [
        <Popconfirm
          key="del"
          title="确认删除该光谱条目？"
          onConfirm={async () => {
            await deleteSpectrumEntry(r.id);
            message.success('已删除');
            actionRef.current?.reload();
          }}
        >
          <a style={{ color: '#ff4d4f' }}>删除</a>
        </Popconfirm>,
      ],
    },
  ];

  return (
    <>
      <ProTable<SpectrumEntry>
        actionRef={actionRef}
        rowKey="id"
        columns={columns}
        search={false}
        request={async () => {
          const res = await listSpectrumEntries();
          return { data: res, total: res.length, success: true };
        }}
        toolBarRender={() => [
          <Button
            key="new"
            type="primary"
            icon={<PlusOutlined />}
            onClick={() => {
              form.resetFields();
              setUploadedUrl('');
              setModalOpen(true);
            }}
          >
            新增光谱
          </Button>,
        ]}
      />
      <Modal
        title="新增光谱库条目"
        open={modalOpen}
        onCancel={() => setModalOpen(false)}
        onOk={async () => {
          const v = await form.validateFields();
          await createSpectrumEntry({ ...v, dataUrl: uploadedUrl || v.dataUrl });
          message.success('已保存');
          setModalOpen(false);
          actionRef.current?.reload();
        }}
      >
        <Form form={form} layout="vertical">
          <Form.Item label="病种" name="disease" rules={[{ required: true, message: '请输入病种' }]}>
            <Input />
          </Form.Item>
          <Form.Item label="来源" name="source">
            <Input placeholder="如：西南大学 / 本地采样" />
          </Form.Item>
          <Form.Item label="数据文件">
            <Upload
              maxCount={1}
              accept=".csv,.txt,.json"
              customRequest={async ({ file, onSuccess, onError }) => {
                try {
                  const res = await uploadSpectrumEntryFile(file as File);
                  setUploadedUrl(res.url);
                  message.success('文件已上传');
                  onSuccess?.(res);
                } catch (e) {
                  onError?.(e as Error);
                }
              }}
            >
              <Button icon={<PlusOutlined />}>上传光谱文件</Button>
            </Upload>
          </Form.Item>
          <Form.Item label="数据 URL" name="dataUrl">
            <Input placeholder="上传文件后自动填充，或手动填写" />
          </Form.Item>
          <Form.Item label="备注" name="note">
            <Input.TextArea rows={2} />
          </Form.Item>
        </Form>
      </Modal>
    </>
  );
}

export default function LampTestsPage() {
  return (
    <Tabs
      defaultActiveKey="lamp"
      items={[
        { key: 'lamp', label: '分子检测', children: <LampTab /> },
        { key: 'spectrum', label: '光谱库', children: <SpectrumTab /> },
      ]}
    />
  );
}
