import React, { useCallback, useEffect, useMemo, useState } from 'react';
import dayjs, { type Dayjs } from 'dayjs';
import {
  Table,
  Button,
  Row,
  Col,
  Select,
  Input,
  TreeSelect,
  DatePicker,
  Space,
  Image,
  Tag,
  Modal,
} from 'antd';
import type { ColumnsType } from 'antd/es/table';
import { Search, RefreshCw, Download } from 'lucide-react';
import { toast } from 'sonner';
import { useTranslation } from 'react-i18next';
import { materialCheckRecordApi } from '../../../api/material/checkRecord';
import { materialLockerApi } from '../../../api/material/lockers';
import { materialTypeApi } from '../../../api/material/type';
import {
  pickRecords,
  pickTotal,
  buildPageParams,
  fetchAllMaterialTypes,
  buildMaterialTypeTreeData,
  downloadBlob,
} from '../materialListUtils';
import {
  MaterialPageRoot,
  MaterialTableCard,
  MaterialPaginationBar,
  MaterialViewButton,
} from '../MaterialPageLayout';
import { switchMaterialSubMenu, MATERIAL_REPLACEMENT_RECORD_PRESET_KEY } from '../materialPvNav';

const MATERIALS_CABINET_LIST_PARAMS = buildPageParams(1, -1);

function firstDefined(row: Record<string, any>, keys: string[]) {
  for (const k of keys) {
    const v = row[k];
    if (v !== undefined && v !== null && v !== '') return v;
  }
  return undefined;
}

function mapCabinetListToFilterOptions(rows: any[]): { value: number; label: string }[] {
  const mapped = rows
    .map((c: any) => {
      const rawId = c.id ?? c.cabinetId;
      const value = Number(rawId);
      const label = String(c.cabinetName ?? c.name ?? '').trim();
      return { value, label: label || (Number.isFinite(value) ? `#${value}` : '') };
    })
    .filter((o) => Number.isFinite(o.value) && o.label);
  const hasZero = mapped.some((o) => o.value === 0);
  return hasZero ? mapped : [...mapped, { value: 0, label: '空' }];
}

/** 与旧版 CHECKS_STATUS 常见取值一致（无字典接口时兜底） */
const CHECK_RESULT_FILTER_OPTIONS = [
  { value: 0, label: '正常' },
  { value: 1, label: '异常' },
];

/** 与旧版 EXCEPTIONS_STATUS 常见取值一致 */
const ABNORMAL_REASON_FILTER_OPTIONS = [
  { value: 0, label: '无' },
  { value: 1, label: '损坏' },
  { value: 2, label: '丢失' },
  { value: 3, label: '过期' },
];

function renderCheckResultCell(_: unknown, row: any) {
  const name = firstDefined(row, ['statusName', 'status_name', 'checkStatusName', 'checkResultName']);
  if (name != null && String(name).trim() !== '') {
    const s = String(name).trim();
    const color = s.includes('异') ? 'error' : s.includes('正') ? 'success' : 'processing';
    return <Tag color={color}>{s}</Tag>;
  }
  const raw = firstDefined(row, ['status', 'checkStatus', 'check_status', 'checkResult']);
  if (raw === undefined || raw === null || raw === '') return <span className="text-gray-400">—</span>;
  const n = Number(raw);
  const map: Record<number, { label: string; color: string }> = {
    0: { label: '正常', color: 'success' },
    1: { label: '异常', color: 'error' },
  };
  if (Number.isFinite(n) && map[n]) {
    const x = map[n];
    return <Tag color={x.color}>{x.label}</Tag>;
  }
  return <Tag>{String(raw)}</Tag>;
}

function renderAbnormalReasonCell(_: unknown, row: any) {
  const raw = firstDefined(row, ['reason', 'exceptionReason', 'exception_reason', 'abnormalReason']);
  if (raw === undefined || raw === null || raw === '' || raw === 0 || raw === '0') {
    return <span className="text-gray-400">—</span>;
  }
  const name = firstDefined(row, ['reasonName', 'reason_name', 'exceptionName']);
  if (name != null && String(name).trim() !== '') {
    return <Tag color="magenta">{String(name).trim()}</Tag>;
  }
  const n = Number(raw);
  const map: Record<number, string> = {
    1: '损坏',
    2: '丢失',
    3: '过期',
  };
  if (Number.isFinite(n) && map[n]) return <Tag color="magenta">{map[n]}</Tag>;
  return <Tag color="magenta">{String(raw)}</Tag>;
}

type RecordDraft = {
  planName: string;
  cabinetId?: number;
  materialsName: string;
  materialsTypeId?: number;
  materialsRfid: string;
  checkTimeRange: [Dayjs, Dayjs] | null;
  checkStatus?: number;
  reason?: number;
  planId?: number;
};

function emptyDraft(fixedCabinetId?: number): RecordDraft {
  return {
    planName: '',
    materialsName: '',
    materialsRfid: '',
    checkTimeRange: null,
    checkStatus: undefined,
    reason: undefined,
    planId: undefined,
    ...(fixedCabinetId != null && Number.isFinite(Number(fixedCabinetId))
      ? { cabinetId: Number(fixedCabinetId) }
      : {}),
  };
}

export interface MaterialInspectionRecordPageProps {
  fixedCabinetId?: number;
  embedded?: boolean;
  embeddedTabBar?: React.ReactNode;
}

export default function MaterialInspectionRecordPage({
  fixedCabinetId,
  embedded,
  embeddedTabBar,
}: MaterialInspectionRecordPageProps = {}) {
  const { t } = useTranslation();
  const [loading, setLoading] = useState(false);
  const [exportLoading, setExportLoading] = useState(false);
  const [list, setList] = useState<any[]>([]);
  const [total, setTotal] = useState(0);
  const [pageNo, setPageNo] = useState(1);
  const [pageSize] = useState(10);
  const [draft, setDraft] = useState<RecordDraft>(() => emptyDraft(fixedCabinetId));
  const [applied, setApplied] = useState<RecordDraft>(() => emptyDraft(fixedCabinetId));
  const [cabinetOpts, setCabinetOpts] = useState<{ value: number; label: string }[]>([]);
  const [materialTypeRows, setMaterialTypeRows] = useState<any[]>([]);

  const typeTreeData = useMemo(() => buildMaterialTypeTreeData(materialTypeRows), [materialTypeRows]);

  const filterLabelCls =
    'shrink-0 text-right text-sm font-medium text-gray-600 whitespace-nowrap w-[100px] sm:w-[108px]';

  const cabinetLocked = fixedCabinetId != null && Number.isFinite(Number(fixedCabinetId));
  const showPlanFilters = !embedded;

  useEffect(() => {
    (async () => {
      try {
        const res = await materialLockerApi.listMaterialsCabinet(MATERIALS_CABINET_LIST_PARAMS);
        setCabinetOpts(mapCabinetListToFilterOptions(pickRecords(res)));
      } catch {
        try {
          const res2 = await materialLockerApi.listMaterialsCabinet(buildPageParams(1, 500));
          setCabinetOpts(mapCabinetListToFilterOptions(pickRecords(res2)));
        } catch {
          setCabinetOpts([]);
        }
      }
    })();
  }, []);

  useEffect(() => {
    (async () => {
      try {
        const typeRows = await fetchAllMaterialTypes(materialTypeApi.listType);
        const seen = new Set<number>();
        const unique: any[] = [];
        for (const x of typeRows) {
          const id = Number(x.id ?? x.materialsTypeId);
          if (!Number.isFinite(id) || id <= 0 || seen.has(id)) continue;
          seen.add(id);
          unique.push(x);
        }
        setMaterialTypeRows(unique);
      } catch {
        setMaterialTypeRows([]);
      }
    })();
  }, []);

  /** 从检查计划「查看」跳转：带入计划筛选（与旧版路由 query 一致） */
  useEffect(() => {
    if (embedded) return;
    try {
      const raw = sessionStorage.getItem('materialInspectionRecordPreset');
      if (!raw) return;
      const p = JSON.parse(raw);
      sessionStorage.removeItem('materialInspectionRecordPreset');
      const pid = p?.planId ?? p?.materialsCheckPlanId;
      const next = emptyDraft(fixedCabinetId);
      if (pid != null && Number.isFinite(Number(pid))) {
        next.planId = Number(pid);
      }
      const pn = p?.planName;
      if (typeof pn === 'string' && pn.trim()) next.planName = pn.trim();
      setDraft(next);
      setApplied(next);
      setPageNo(1);
    } catch {
      sessionStorage.removeItem('materialInspectionRecordPreset');
    }
  }, [embedded, fixedCabinetId]);

  useEffect(() => {
    if (cabinetLocked) {
      const id = Number(fixedCabinetId);
      setDraft((d) => ({ ...d, cabinetId: id }));
      setApplied((a) => ({ ...a, cabinetId: id }));
    }
  }, [fixedCabinetId, cabinetLocked]);

  const buildListParams = useCallback(() => {
    const q: Record<string, any> = {
      ...buildPageParams(pageNo, pageSize),
    };
    if (applied.planName?.trim()) q.planName = applied.planName.trim();
    if (applied.planId != null && Number.isFinite(applied.planId)) {
      q.planId = applied.planId;
      q.materialsCheckPlanId = applied.planId;
    }
    const cab =
      cabinetLocked && fixedCabinetId != null
        ? Number(fixedCabinetId)
        : applied.cabinetId != null && Number.isFinite(applied.cabinetId) && Number(applied.cabinetId) > 0
          ? Number(applied.cabinetId)
          : undefined;
    if (cab != null) q.cabinetId = cab;
    if (applied.materialsName?.trim()) q.materialsName = applied.materialsName.trim();
    if (applied.materialsTypeId != null) q.materialsTypeId = applied.materialsTypeId;
    if (applied.materialsRfid?.trim()) q.materialsRfid = applied.materialsRfid.trim();
    if (applied.checkStatus != null) q.status = applied.checkStatus;
    if (applied.reason != null) q.reason = applied.reason;
    if (applied.checkTimeRange?.[0] && applied.checkTimeRange[1]) {
      q.startTime = applied.checkTimeRange[0].format('YYYY-MM-DD HH:mm:ss');
      q.endTime = applied.checkTimeRange[1].format('YYYY-MM-DD HH:mm:ss');
    }
    return q;
  }, [pageNo, pageSize, applied, cabinetLocked, fixedCabinetId]);

  const fetchList = useCallback(async () => {
    setLoading(true);
    try {
      const res = await materialCheckRecordApi.listCheckRecord(buildListParams());
      setList(pickRecords(res));
      setTotal(pickTotal(res));
    } catch (e: any) {
      toast.error(e?.message || t('common.operationFailed'));
    } finally {
      setLoading(false);
    }
  }, [buildListParams, t]);

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

  const setDraftField = <K extends keyof RecordDraft>(key: K, value: RecordDraft[K]) => {
    setDraft((d) => ({ ...d, [key]: value }));
  };

  const handleQuery = () => {
    setApplied({ ...draft });
    setPageNo(1);
  };

  const resetQuery = () => {
    const e = emptyDraft(fixedCabinetId);
    setDraft(e);
    setApplied(e);
    setPageNo(1);
  };

  const handleExport = () => {
    Modal.confirm({
      title: '导出确认',
      content: '是否确认导出当前筛选条件下的物资检查记录？',
      okText: t('common.confirm'),
      cancelText: t('common.cancel'),
      onOk: async () => {
        setExportLoading(true);
        try {
          const exportParams = { ...buildListParams(), ...buildPageParams(1, 5000) };
          const blob = (await materialCheckRecordApi.exportCheckRecord(exportParams)) as unknown as Blob;
          if (blob instanceof Blob) {
            downloadBlob(blob, '物资检查记录.xls');
            toast.success('导出成功');
          }
        } catch (e: any) {
          toast.error(e?.message || t('common.operationFailed'));
        } finally {
          setExportLoading(false);
        }
      },
    });
  };

  const goReplacementRecord = (row: any) => {
    const recordId = firstDefined(row, ['recordId', 'id', 'materialsCheckRecordId']);
    try {
      const n = recordId != null && recordId !== '' ? Number(recordId) : NaN;
      sessionStorage.setItem(
        MATERIAL_REPLACEMENT_RECORD_PRESET_KEY,
        JSON.stringify({
          recordId: Number.isFinite(n) ? n : undefined,
          checkRecordId: Number.isFinite(n) ? n : undefined,
        }),
      );
    } catch {
      /* ignore */
    }
    switchMaterialSubMenu('materialManagement', 'materialReplacementRecord');
  };

  const columns: ColumnsType<any> = useMemo(
    () => [
      {
        title: '计划名称',
        width: 200,
        align: 'center',
        ellipsis: true,
        render: (_, row) =>
          String(firstDefined(row, ['planName', 'plan_name', 'materialsCheckPlanName']) ?? '—'),
      },
      {
        title: '物资柜',
        width: 120,
        align: 'center',
        render: (_, row) =>
          String(firstDefined(row, ['cabinetName', 'cabinet_name', 'materialsCabinetName']) ?? '—'),
      },
      {
        title: '物资编号',
        width: 96,
        align: 'center',
        render: (_, row) => String(firstDefined(row, ['materialsId', 'materials_id']) ?? '—'),
      },
      {
        title: '物资名称',
        width: 120,
        align: 'center',
        ellipsis: true,
        render: (_, row) => String(firstDefined(row, ['materialsName', 'materials_name']) ?? '—'),
      },
      {
        title: '物资类型',
        width: 120,
        align: 'center',
        ellipsis: true,
        render: (_, row) => String(firstDefined(row, ['materialsTypeName', 'typeName']) ?? '—'),
      },
      {
        title: '物资图片',
        width: 88,
        align: 'center',
        render: (_, row) => {
          const src = firstDefined(row, [
            'materialsTypePicture',
            'materialsPicture',
            'picture',
            'imageUrl',
          ]);
          if (!src) return <span className="text-gray-400">—</span>;
          return (
            <div className="inline-flex rounded-md border border-gray-200 bg-gray-50 p-0.5 shadow-sm">
              <Image
                src={String(src)}
                width={44}
                height={44}
                className="!rounded object-cover"
                preview={{ mask: '预览' }}
              />
            </div>
          );
        },
      },
      {
        title: 'RFID',
        width: 140,
        ellipsis: true,
        align: 'center',
        render: (_, row) => String(firstDefined(row, ['materialsRfid', 'rfid', 'rfidCode']) ?? '—'),
      },
      {
        title: '检查时间',
        width: 172,
        align: 'center',
        render: (_, row) =>
          String(firstDefined(row, ['checkDate', 'checkTime', 'check_time', 'createTime']) ?? '—'),
      },
      {
        title: '检查结果',
        width: 100,
        align: 'center',
        render: (_, row) => renderCheckResultCell(_, row),
      },
      {
        title: '异常原因',
        width: 100,
        align: 'center',
        render: (_, row) => renderAbnormalReasonCell(_, row),
      },
      {
        title: '措施',
        width: 120,
        ellipsis: true,
        align: 'center',
        render: (_, row) => String(firstDefined(row, ['measure', 'measures', 'handleMeasure']) ?? '—'),
      },
      {
        title: '更换记录',
        width: 100,
        align: 'center',
        render: (_, row) => <MaterialViewButton label="查看" onClick={() => goReplacementRecord(row)} />,
      },
    ],
    [t],
  );

  const filterCard = (
    <div className="overflow-hidden rounded-xl border border-gray-200/80 bg-white shadow-sm ring-1 ring-gray-100/80">
      {embeddedTabBar ? (
        <div className="border-b border-gray-100/80 px-2 pb-3 pt-4 sm:px-3 sm:pb-4 sm:pt-5">{embeddedTabBar}</div>
      ) : null}
      <div className="box-border w-full min-w-0 px-5" style={{ paddingTop: 28, paddingBottom: 20 }}>
        <div className="w-full min-w-0 space-y-4">
          <Row gutter={[16, 16]}>
            {showPlanFilters ? (
              <Col xs={24} sm={12} lg={6}>
                <div className="flex min-w-0 items-center gap-2.5">
                  <span className={filterLabelCls}>计划名称</span>
                  <Input
                    allowClear
                    placeholder="请输入计划名称"
                    className="min-w-0 flex-1"
                    value={draft.planName}
                    onChange={(e) => setDraftField('planName', e.target.value)}
                    onPressEnter={handleQuery}
                  />
                </div>
              </Col>
            ) : null}
            <Col xs={24} sm={12} lg={6}>
              <div className="flex min-w-0 items-center gap-2.5">
                <span className={filterLabelCls}>物资柜</span>
                <Select
                  allowClear={!cabinetLocked}
                  disabled={cabinetLocked}
                  placeholder="请选择物资柜"
                  className="min-w-0 flex-1"
                  options={cabinetOpts}
                  value={draft.cabinetId}
                  onChange={(v) => setDraftField('cabinetId', v ?? undefined)}
                />
              </div>
            </Col>
            <Col xs={24} sm={12} lg={6}>
              <div className="flex min-w-0 items-center gap-2.5">
                <span className={filterLabelCls}>物资名称</span>
                <Input
                  allowClear
                  placeholder="请输入物资名称"
                  className="min-w-0 flex-1"
                  value={draft.materialsName}
                  onChange={(e) => setDraftField('materialsName', e.target.value)}
                  onPressEnter={handleQuery}
                />
              </div>
            </Col>
            <Col xs={24} sm={12} lg={6}>
              <div className="flex min-w-0 items-center gap-2.5">
                <span className={filterLabelCls}>物资类型</span>
                <TreeSelect
                  allowClear
                  showSearch
                  treeDefaultExpandAll
                  treeLine={{ showLeafIcon: false }}
                  placeholder="请选择物资类型"
                  className="min-w-0 flex-1"
                  treeData={typeTreeData}
                  treeNodeFilterProp="title"
                  value={draft.materialsTypeId}
                  onChange={(v) =>
                    setDraftField('materialsTypeId', v != null && v !== '' ? Number(v) : undefined)
                  }
                />
              </div>
            </Col>
          </Row>
          <Row gutter={[16, 16]}>
            <Col xs={24} sm={12} lg={6}>
              <div className="flex min-w-0 items-center gap-2.5">
                <span className={filterLabelCls}>RFID</span>
                <Input
                  allowClear
                  placeholder="请输入RFID"
                  className="min-w-0 flex-1"
                  value={draft.materialsRfid}
                  onChange={(e) => setDraftField('materialsRfid', e.target.value)}
                  onPressEnter={handleQuery}
                />
              </div>
            </Col>
            <Col xs={24} sm={12} lg={9}>
              <div className="flex min-w-0 items-center gap-2.5">
                <span className={filterLabelCls}>检查时间</span>
                <DatePicker.RangePicker
                  showTime
                  className="min-w-0 flex-1 [&_.ant-picker-input]:min-w-0"
                  value={draft.checkTimeRange}
                  onChange={(vals) => {
                    const a = vals?.[0];
                    const b = vals?.[1];
                    setDraftField('checkTimeRange', a && b ? [a, b] : null);
                  }}
                  placeholder={['开始日期', '结束日期']}
                />
              </div>
            </Col>
            <Col xs={24} sm={12} lg={6}>
              <div className="flex min-w-0 items-center gap-2.5">
                <span className={filterLabelCls}>检查结果</span>
                <Select
                  allowClear
                  placeholder="请选择检查结果"
                  className="min-w-0 flex-1"
                  options={CHECK_RESULT_FILTER_OPTIONS}
                  value={draft.checkStatus}
                  onChange={(v) => setDraftField('checkStatus', v ?? undefined)}
                />
              </div>
            </Col>
            <Col xs={24} sm={12} lg={6}>
              <div className="flex min-w-0 items-center gap-2.5">
                <span className={filterLabelCls}>异常原因</span>
                <Select
                  allowClear
                  placeholder="请选择异常原因"
                  className="min-w-0 flex-1"
                  options={ABNORMAL_REASON_FILTER_OPTIONS}
                  value={draft.reason}
                  onChange={(v) => setDraftField('reason', v ?? undefined)}
                />
              </div>
            </Col>
            <Col flex="auto" className="min-w-0">
              <div className="ml-[20px] flex min-w-0 flex-wrap items-center">
                <Space size="small" wrap>
                  <Button type="primary" icon={<Search className="h-4 w-4" />} onClick={handleQuery}>
                    {t('common.search')}
                  </Button>
                  <Button icon={<RefreshCw className="h-4 w-4" />} onClick={resetQuery}>
                    {t('common.reset')}
                  </Button>
                  <Button
                    type="primary"
                    ghost
                    className="!border-green-600 !text-green-600 hover:!border-green-700 hover:!text-green-700"
                    icon={<Download className="h-4 w-4" />}
                    loading={exportLoading}
                    onClick={handleExport}
                  >
                    导出
                  </Button>
                </Space>
              </div>
            </Col>
          </Row>
        </div>
      </div>
    </div>
  );

  const tableInner = (
    <>
      <MaterialTableCard flush={Boolean(embedded)}>
        <Table
          rowKey={(r) => r.recordId ?? r.id}
          loading={loading}
          columns={columns}
          dataSource={list}
          pagination={false}
          scroll={{ x: 'max-content' }}
          rowClassName={(_, index) => (index !== undefined && index % 2 === 1 ? 'isolation-work-list-row-alt' : '')}
        />
      </MaterialTableCard>
      <MaterialPaginationBar
        flushTop={Boolean(embedded)}
        total={total}
        current={pageNo}
        pageSize={pageSize}
        onPageChange={setPageNo}
        loading={loading}
        listLength={list.length}
      />
    </>
  );

  const listSection = embedded ? (
    <div className="rounded-xl border border-gray-200/80 bg-white shadow-sm ring-1 ring-gray-100/80">{tableInner}</div>
  ) : (
    tableInner
  );

  const pageBody = (
    <>
      {filterCard}
      {listSection}
    </>
  );

  return embedded ? <div className="space-y-4">{pageBody}</div> : <MaterialPageRoot>{pageBody}</MaterialPageRoot>;
}
