import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { Table, Button, Form, Input, Modal, Image, Row, Col, Tree, Select, Tag } from 'antd';
import type { ColumnsType } from 'antd/es/table';
import type { DataNode } from 'antd/es/tree';
import { Plus } from 'lucide-react';
import { toast } from 'sonner';
import { useTranslation } from 'react-i18next';
import { materialLockerApi, CabinetVO } from '../../../api/material/lockers';
import { workstationApi } from '../../../api/workstation';
import { handleTree } from '../../../utils/tree';
import UploadImg from '../../lockCabinet/UploadImg';
import MaterialLockerDetailPage from './MaterialLockerDetailPage';
import { pickRecords, pickTotal, buildPageParams, fetchAllWorkstations } from '../materialListUtils';
import {
  MaterialPageRoot,
  MaterialToolbarCard,
  MaterialTableCard,
  MaterialPaginationBar,
  MaterialEditButton,
  MaterialDeleteButton,
  MaterialViewButton,
  materialConfirmDelete,
  getMaterialFormModalProps,
  materialFormLayout,
} from '../MaterialPageLayout';

/** 物资柜状态：0 正常 1 借出 2 异常 */
const CABINET_STATUS_OPTIONS = [
  { value: 0, label: '正常' },
  { value: 1, label: '借出' },
  { value: 2, label: '异常' },
];

const CABINET_STATUS_LABEL: Record<number, string> = {
  0: '正常',
  1: '借出',
  2: '异常',
};

/** 异常类型：0 正常 1 物资异常 2 物资柜异常 3 错还柜子 4 物资借出 5 超时未关门 */
const EXCEPTION_TYPE_LABEL: Record<number, string> = {
  0: '正常',
  1: '物资异常',
  2: '物资柜异常',
  3: '错还柜子',
  4: '物资借出',
  5: '超时未关门',
};

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

function toFiniteInt(v: unknown): number | undefined {
  if (v === undefined || v === null || v === '') return undefined;
  if (typeof v === 'string' && v.trim() === '') return undefined;
  const n = Number(v);
  return Number.isFinite(n) ? Math.trunc(n) : undefined;
}

function getCabinetStatusValue(row: Record<string, unknown>): number | undefined {
  const raw = firstDefined(row, ['status', 'cabinetStatus', 'runStatus', 'cabinetRunStatus']);
  if (raw === '正常') return 0;
  if (raw === '借出') return 1;
  if (raw === '异常') return 2;
  return toFiniteInt(raw);
}

function renderCabinetStatusTag(row: Record<string, unknown>) {
  const raw = firstDefined(row, ['status', 'cabinetStatus', 'runStatus', 'cabinetRunStatus']);
  const code = getCabinetStatusValue(row);
  if (code !== undefined && CABINET_STATUS_LABEL[code] !== undefined) {
    const color = code === 0 ? 'blue' : code === 1 ? 'processing' : 'error';
    return <Tag color={color}>{CABINET_STATUS_LABEL[code]}</Tag>;
  }
  if (typeof raw === 'string' && raw.trim() !== '') {
    return <Tag color="default">{raw}</Tag>;
  }
  return <Tag color="default">—</Tag>;
}

function getExceptionTypeCode(row: Record<string, unknown>): number | undefined {
  return toFiniteInt(
    firstDefined(row, [
      'exReason',
      'exceptionType',
      'abnormalType',
      'exceptionTypeCode',
      'abnormalTypeCode',
      'doorExceptionType',
      'exceptionKind',
    ]),
  );
}

function exceptionTypeTagColor(code: number): string {
  if (code === 0) return 'blue';
  if (code === 1 || code === 2) return 'error';
  if (code === 3 || code === 5) return 'warning';
  if (code === 4) return 'processing';
  return 'default';
}

function renderExceptionTypeTag(row: Record<string, unknown>) {
  const code = getExceptionTypeCode(row);
  if (code !== undefined && EXCEPTION_TYPE_LABEL[code] !== undefined) {
    return (
      <Tag color={exceptionTypeTagColor(code)}>{EXCEPTION_TYPE_LABEL[code]}</Tag>
    );
  }
  const ex = firstDefined(row, [
    'exceptionTypeName',
    'exceptionName',
    'exceptionDesc',
    'abnormalTypeName',
    'exceptionMsg',
    'errorMessage',
    'abnormalReason',
  ]);
  if (ex !== undefined && ex !== null && ex !== '') {
    return <Tag color="default">{String(ex)}</Tag>;
  }
  return <Tag color="default">—</Tag>;
}

function filterWorkstationTree(nodes: any[], kw: string): any[] {
  const q = kw.trim().toLowerCase();
  if (!q) return nodes;
  const match = (n: any) => {
    const code = String(n.workstationCode ?? '').toLowerCase();
    const name = String(n.workstationName ?? '').toLowerCase();
    return code.includes(q) || name.includes(q);
  };
  return nodes
    .map((n) => {
      const children = n.children?.length ? filterWorkstationTree(n.children, kw) : [];
      if (match(n) || children.length) return { ...n, children: children.length ? children : undefined };
      return null;
    })
    .filter(Boolean) as any[];
}

function toAntdTreeData(nodes: any[]): DataNode[] {
  return nodes.map((n) => ({
    key: String(n.id),
    title: (n.workstationCode || n.workstationName || String(n.id)) as React.ReactNode,
    children: n.children?.length ? toAntdTreeData(n.children) : undefined,
  }));
}

/** 区域树打平为下拉选项（value 为岗位/区域 id） */
function flattenWorkstationOptions(nodes: any[]): { label: string; value: number }[] {
  const out: { label: string; value: number }[] = [];
  const walk = (arr: any[]) => {
    for (const n of arr) {
      const id = Number(n.id ?? n.workstationId);
      if (Number.isFinite(id) && id > 0) {
        const code = n.workstationCode ? String(n.workstationCode) : '';
        const name = n.workstationName ? String(n.workstationName) : '';
        const label = [code, name].filter(Boolean).join(' / ') || String(id);
        out.push({ value: id, label });
      }
      if (n.children?.length) walk(n.children);
    }
  };
  walk(nodes);
  return out;
}

export default function MaterialLockersPage() {
  const { t } = useTranslation();
  const [loading, setLoading] = useState(false);
  const [list, setList] = useState<any[]>([]);
  const [total, setTotal] = useState(0);
  const [pageNo, setPageNo] = useState(1);
  /** 与点位管理列表一致：固定每页条数，分页条不提供「每页几条 / 前往页」 */
  const pageSize = 10;
  const [draftQuery, setDraftQuery] = useState({ cabinetName: '', status: undefined as number | undefined });
  const [appliedQuery, setAppliedQuery] = useState({ cabinetName: '', status: undefined as number | undefined });
  const [modalOpen, setModalOpen] = useState(false);
  const [editing, setEditing] = useState<CabinetVO | null>(null);
  const [form] = Form.useForm();

  const [areaSearch, setAreaSearch] = useState('');
  const [areaTreeRaw, setAreaTreeRaw] = useState<any[]>([]);
  const [selectedAreaKey, setSelectedAreaKey] = useState<string>('all');
  /** 非空时展示物资柜详情页（由列表「查看」进入） */
  const [lockerDetail, setLockerDetail] = useState<{ id: number; name: string } | null>(null);

  const workstationIdFilter = selectedAreaKey === 'all' ? undefined : Number(selectedAreaKey);

  const filteredAreaTree = useMemo(() => filterWorkstationTree(areaTreeRaw, areaSearch), [areaTreeRaw, areaSearch]);

  const areaTreeData: DataNode[] = useMemo(
    () => [{ key: 'all', title: '全部区域' }, ...toAntdTreeData(filteredAreaTree)],
    [filteredAreaTree],
  );

  const workstationOptions = useMemo(() => {
    const base = flattenWorkstationOptions(areaTreeRaw);
    if (!editing) return base;
    const wid = Number(editing.workstationId);
    if (Number.isFinite(wid) && wid > 0 && !base.some((o) => o.value === wid)) {
      const label =
        firstDefined(editing as unknown as Record<string, unknown>, ['workstationCode', 'workstationName']) ??
        `区域 #${wid}`;
      return [{ value: wid, label: String(label) }, ...base];
    }
    return base;
  }, [areaTreeRaw, editing]);

  const loadAreaTree = useCallback(async () => {
    try {
      const flat = await fetchAllWorkstations(workstationApi.listMarsDept);
      const normalized = flat.map((w: any) => {
        const id = Number(w.workstationId ?? w.id);
        return {
          ...w,
          id: Number.isFinite(id) ? id : 0,
          parentId: w.parentId != null && w.parentId !== '' ? Number(w.parentId) : 0,
        };
      });
      const tree = handleTree(normalized, 'id', 'parentId', 'children');
      setAreaTreeRaw(tree);
    } catch (e: any) {
      toast.error(e?.message || '加载区域失败');
      setAreaTreeRaw([]);
    }
  }, []);

  useEffect(() => {
    loadAreaTree();
  }, [loadAreaTree]);

  const fetchList = useCallback(async () => {
    setLoading(true);
    try {
      const res = await materialLockerApi.listMaterialsCabinet({
        ...buildPageParams(pageNo, pageSize),
        cabinetName: appliedQuery.cabinetName || undefined,
        status: appliedQuery.status,
        workstationId: workstationIdFilter,
      });
      setList(pickRecords(res));
      setTotal(pickTotal(res));
    } catch (e: any) {
      toast.error(e?.message || '加载物资柜失败');
      setList([]);
    } finally {
      setLoading(false);
    }
  }, [pageNo, appliedQuery.cabinetName, appliedQuery.status, workstationIdFilter]);

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

  const handleQuery = () => {
    setAppliedQuery({ ...draftQuery });
    setPageNo(1);
  };

  const resetQuery = () => {
    const empty = { cabinetName: '', status: undefined as number | undefined };
    setDraftQuery(empty);
    setAppliedQuery(empty);
    setPageNo(1);
  };

  const openCreate = () => {
    setEditing(null);
    form.resetFields();
    form.setFieldsValue({
      cabinetName: '',
      remark: '',
      cabinetPicture: '',
      workstationId:
        workstationIdFilter != null && Number.isFinite(workstationIdFilter) && workstationIdFilter > 0
          ? workstationIdFilter
          : undefined,
    });
    setModalOpen(true);
  };

  const openEdit = (row: any) => {
    setEditing(row);
    form.setFieldsValue({
      cabinetName: row.cabinetName,
      remark: row.remark ?? '',
      cabinetPicture: row.cabinetPicture ?? '',
      workstationId: row.workstationId != null && row.workstationId !== '' ? Number(row.workstationId) : undefined,
    });
    setModalOpen(true);
  };

  const openLockerDetail = (row: any) => {
    const id = row.cabinetId ?? row.id;
    if (id == null) return;
    setLockerDetail({
      id: Number(id),
      name: String(row.cabinetName ?? ''),
    });
  };

  const handleSubmit = async () => {
    try {
      const v = await form.validateFields();
      setLoading(true);
      const editId = editing ? (editing.cabinetId ?? editing.id) : undefined;
      if (editId != null && editing) {
        await materialLockerApi.updateMaterialsCabinet({
          ...editing,
          cabinetId: editId,
          cabinetName: v.cabinetName,
          cabinetCode: editing.cabinetCode || v.cabinetName,
          cabinetType: editing.cabinetType || 'default',
          remark: v.remark,
          cabinetPicture: v.cabinetPicture || '',
          workstationId: v.workstationId,
        } as CabinetVO);
        toast.success(t('common.updateSuccess'));
      } else {
        await materialLockerApi.addMaterialsCabinet({
          cabinetName: v.cabinetName,
          cabinetCode: v.cabinetName,
          cabinetType: 'default',
          status: 0,
          remark: v.remark,
          cabinetPicture: v.cabinetPicture || undefined,
          workstationId: v.workstationId,
        } as CabinetVO);
        toast.success(t('common.addSuccess'));
      }
      setModalOpen(false);
      fetchList();
    } catch (e: any) {
      if (e?.errorFields) return;
      toast.error(e?.message || t('common.operationFailed'));
    } finally {
      setLoading(false);
    }
  };

  const handleDelete = (row: any) => {
    const id = row.cabinetId ?? row.id;
    if (!id) return;
    materialConfirmDelete(t, {
      count: 1,
      onOk: async () => {
        await materialLockerApi.deleteMaterialsCabinet(id);
        toast.success(t('common.deleteSuccess'));
        fetchList();
      },
    });
  };

  const areaCol = (row: any) =>
    firstDefined(row, ['workstationCode', 'workstationName', 'areaCode', 'areaName']) ?? '—';

  const columns: ColumnsType<any> = [
    { title: '物资柜编号', dataIndex: 'cabinetId', width: 110, align: 'center', render: (v, row) => v ?? row.id ?? '—' },
    { title: '物资柜名称', dataIndex: 'cabinetName', ellipsis: true, align: 'center' },
    {
      title: '所属区域',
      key: 'area',
      ellipsis: true,
      align: 'center',
      render: (_, row) => areaCol(row),
    },
    {
      title: '物资柜图片',
      dataIndex: 'cabinetPicture',
      width: 100,
      align: 'center',
      render: (url: string) =>
        url ? <Image src={url} width={50} height={50} style={{ objectFit: 'cover' }} /> : '—',
    },
    {
      title: '物资柜状态',
      key: 'cabinetStatus',
      width: 100,
      align: 'center',
      render: (_, row) => renderCabinetStatusTag(row),
    },
    {
      title: '异常类型',
      key: 'exceptionType',
      width: 140,
      align: 'center',
      render: (_, row) => renderExceptionTypeTag(row),
    },
    {
      title: '查看',
      key: 'view',
      width: 100,
      align: 'center',
      fixed: 'right',
      render: (_, row) => <MaterialViewButton label="查看" onClick={() => openLockerDetail(row)} />,
    },
    {
      title: t('table.operation'),
      width: 160,
      align: 'center',
      fixed: 'right',
      render: (_, row) => (
        <div className="flex items-center gap-2 justify-center">
          <MaterialEditButton label={t('common.edit')} onClick={() => openEdit(row)} />
          <MaterialDeleteButton label={t('common.delete')} onClick={() => handleDelete(row)} />
        </div>
      ),
    },
  ];

  const listBody = (
    <div className="flex gap-4 items-start">
      <div className="w-[260px] shrink-0 bg-white rounded-xl border border-gray-200/50 shadow-sm p-4 flex flex-col gap-3 min-h-[420px]">
        <Input.Search allowClear placeholder="请输入区域名称" value={areaSearch} onChange={(e) => setAreaSearch(e.target.value)} />
        <div className="flex-1 overflow-auto border border-gray-100 rounded-lg p-2">
          <Tree
            blockNode
            showLine
            selectedKeys={[selectedAreaKey]}
            treeData={areaTreeData}
            onSelect={(keys) => {
              if (keys.length && typeof keys[0] === 'string') {
                setSelectedAreaKey(keys[0]);
                setPageNo(1);
              }
            }}
          />
        </div>
      </div>
      <div className="flex-1 min-w-0 space-y-4">
        <MaterialToolbarCard
          filterRow={
            <div className="flex items-center gap-3 flex-wrap">
              <div className="flex items-center gap-2">
                <span className="text-sm font-medium text-gray-700 whitespace-nowrap">物资柜名称：</span>
                <Input
                  allowClear
                  placeholder="请输入物资柜名称"
                  className="w-[180px]"
                  value={draftQuery.cabinetName}
                  onChange={(e) => setDraftQuery((q) => ({ ...q, cabinetName: e.target.value }))}
                  onPressEnter={handleQuery}
                />
              </div>
              <div className="flex items-center gap-2">
                <span className="text-sm font-medium text-gray-700 whitespace-nowrap">物资柜状态：</span>
                <Select
                  allowClear
                  placeholder="请选择物资柜状态"
                  className="w-[180px]"
                  options={CABINET_STATUS_OPTIONS}
                  value={draftQuery.status}
                  onChange={(v) => setDraftQuery((q) => ({ ...q, status: v ?? undefined }))}
                />
              </div>
            </div>
          }
          onSearch={handleQuery}
          onReset={resetQuery}
          toolbarRight={
            <Button type="primary" icon={<Plus />} onClick={openCreate}>
              {t('common.addNew')}
            </Button>
          }
        />
        <MaterialTableCard>
          <Table
            rowKey={(r) => r.cabinetId ?? 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
          total={total}
          current={pageNo}
          pageSize={pageSize}
          onPageChange={setPageNo}
          loading={loading}
          listLength={list.length}
        />
      </div>
    </div>
  );

  if (lockerDetail) {
    return (
      <MaterialPageRoot>
        <MaterialLockerDetailPage
          cabinetId={lockerDetail.id}
          cabinetName={lockerDetail.name}
          onBack={() => setLockerDetail(null)}
        />
      </MaterialPageRoot>
    );
  }

  return (
    <MaterialPageRoot>
      {listBody}

      <Modal
        title={editing ? '编辑物资柜信息' : '新增物资柜信息'}
        open={modalOpen}
        onOk={handleSubmit}
        onCancel={() => setModalOpen(false)}
        confirmLoading={loading}
        {...getMaterialFormModalProps(t, 560)}
      >
        <Form form={form} {...materialFormLayout}>
          <Row gutter={16}>
            <Col span={24}>
              <Form.Item
                name="cabinetName"
                label="物资柜名称"
                rules={[{ required: true, message: '请输入物资柜名称' }]}
              >
                <Input allowClear placeholder="请输入物资柜名称" />
              </Form.Item>
            </Col>
            <Col span={24}>
              <Form.Item
                name="workstationId"
                label="所属区域"
                rules={[{ required: true, message: '请选择所属区域' }]}
              >
                <Select
                  allowClear
                  showSearch
                  optionFilterProp="label"
                  placeholder="选择所属区域"
                  options={workstationOptions}
                />
              </Form.Item>
            </Col>
            <Col span={24}>
              <Form.Item name="cabinetPicture" label="物资柜图片">
                <UploadImg width="120px" height="120px" />
              </Form.Item>
            </Col>
            <Col span={24}>
              <Form.Item name="remark" label="备注">
                <Input.TextArea allowClear rows={4} placeholder="请输入内容" />
              </Form.Item>
            </Col>
          </Row>
        </Form>
      </Modal>
    </MaterialPageRoot>
  );
}
