import React, { useCallback, useEffect, useState } from 'react';
import dayjs from 'dayjs';
import { Button, Table, Modal, Input, Transfer, Spin } from 'antd';

import type { TransferProps } from 'antd/es/transfer';

import type { ColumnsType } from 'antd/es/table';

import { Plus, Trash2 } from 'lucide-react';

import { toast } from 'sonner';

import { useTranslation } from 'react-i18next';

import { materialBlacklistApi } from '../../../api/material/blacklist';

import { pickRecords, pickTotal, buildPageParams } from '../materialListUtils';

import {
  MaterialPageRoot,
  MaterialToolbarCard,
  MaterialTableCard,
  MaterialPaginationBar,
  MaterialDeleteButton,
  materialConfirmDelete,
  getMaterialFormModalProps,
} from '../MaterialPageLayout';

type TransferRecord = NonNullable<TransferProps['dataSource']>[number];

function firstDefinedRow(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 formatDateTimeCell(v: unknown): string {
  if (v === undefined || v === null || v === '') return '—';
  const n = typeof v === 'number' ? v : /^\d+$/.test(String(v).trim()) ? Number(String(v).trim()) : NaN;
  const d = Number.isFinite(n) && n > 1e12 ? dayjs(n) : dayjs(v as string | number | Date);
  return d.isValid() ? d.format('YYYY-MM-DD HH:mm:ss') : '—';
}

/** 与旧版 BlacklistForm.vue 一致：module 固定为物资柜等业务维度 */
const BLACKLIST_MODULE = '2';

export default function MaterialBlacklistPage() {
  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] = useState(10);
  const [draftUserName, setDraftUserName] = useState('');
  const [draftNickName, setDraftNickName] = useState('');
  const [appliedUserName, setAppliedUserName] = useState('');
  const [appliedNickName, setAppliedNickName] = useState('');
  const [modalOpen, setModalOpen] = useState(false);
  const [submitLoading, setSubmitLoading] = useState(false);
  const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);

  const [transferLoading, setTransferLoading] = useState(false);
  const [transferDataSource, setTransferDataSource] = useState<TransferRecord[]>([]);
  const [targetKeys, setTargetKeys] = useState<string[]>([]);
  /** key 为穿梭框 key（与旧版一致为 userId 字符串），值为提交用 userId */
  const [userIdByKey, setUserIdByKey] = useState<Map<string, string | number>>(new Map());

  const fetchList = useCallback(async () => {
    setLoading(true);
    try {
      const res = await materialBlacklistApi.listBlacklist({
        ...buildPageParams(pageNo, pageSize),
        userName: appliedUserName || undefined,
        nickName: appliedNickName || undefined,
      });
      setList(pickRecords(res));
      setTotal(pickTotal(res));
    } catch (e: any) {
      toast.error(e?.message || t('common.operationFailed'));
    } finally {
      setLoading(false);
    }
  }, [pageNo, pageSize, appliedUserName, appliedNickName, t]);

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

  /**
   * 与旧版 BlacklistForm getLeftList 一致：白名单分页接口拉可选用户，
   * 不再用「全量用户 − 黑名单」自行过滤，避免 userId 形态与后端不一致。
   */
  const loadTransferUsers = useCallback(async () => {
    setTransferLoading(true);
    try {
      const res = await materialBlacklistApi.listWhitelist({
        ...buildPageParams(1, -1),
        nickName: undefined,
      });
      const rows = pickRecords(res);
      const map = new Map<string, string | number>();
      const items: TransferRecord[] = [];
      for (const item of rows as any[]) {
        const userId = firstDefinedRow(item, ['userId', 'user_id', 'id']);
        if (userId === undefined || userId === null || userId === '') continue;
        const sid = String(userId);
        map.set(sid, userId as string | number);
        items.push({
          key: sid,
          title: `${item.nickName ?? item.nickname ?? '—'} (${item.userName ?? item.username ?? sid})`,
        });
      }
      setUserIdByKey(map);
      setTransferDataSource(items);
    } catch (e: any) {
      toast.error(e?.message || '加载用户列表失败');
      setTransferDataSource([]);
      setUserIdByKey(new Map());
    } finally {
      setTransferLoading(false);
    }
  }, []);

  useEffect(() => {
    if (!modalOpen) return;
    setTargetKeys([]);
    void loadTransferUsers();
  }, [modalOpen, loadTransferUsers]);

  const handleQuery = () => {
    setAppliedUserName(draftUserName);
    setAppliedNickName(draftNickName);
    setPageNo(1);
    setSelectedRowKeys([]);
  };

  const resetQuery = () => {
    setDraftUserName('');
    setDraftNickName('');
    setAppliedUserName('');
    setAppliedNickName('');
    setPageNo(1);
    setSelectedRowKeys([]);
  };

  /** 与旧版 submitForm 一致：一次 POST 数组 [{ userId, module: '2' }, ...] */
  const submitAdd = async () => {
    if (targetKeys.length === 0) {
      toast.error('请至少选择一名用户加入黑名单');
      return;
    }
    setSubmitLoading(true);
    try {
      const payload = targetKeys.map((key) => ({
        userId: userIdByKey.get(key) ?? key,
        module: BLACKLIST_MODULE,
      }));
      await materialBlacklistApi.addBlacklist(payload);
      toast.success(t('common.addSuccess'));
      setModalOpen(false);
      setTargetKeys([]);
      fetchList();
    } catch (e: any) {
      toast.error(e?.message || t('common.operationFailed'));
    } finally {
      setSubmitLoading(false);
    }
  };

  const onDelete = (row: any) => {
    const id = row.recordId ?? row.id;
    materialConfirmDelete(t, {
      count: 1,
      onOk: async () => {
        await materialBlacklistApi.delBlacklist(id);
        toast.success(t('common.deleteSuccess'));
        setSelectedRowKeys((prev) => prev.filter((k) => String(k) !== String(id)));
        fetchList();
      },
    });
  };

  const batchDelete = () => {
    if (selectedRowKeys.length === 0) {
      toast.error(t('common.pleaseSelectDataToDelete'));
      return;
    }
    const ids = selectedRowKeys
      .map((k) => Number(k))
      .filter((n) => Number.isFinite(n) && !Number.isNaN(n));
    if (ids.length === 0) {
      toast.error(t('common.pleaseSelectDataToDelete'));
      return;
    }
    materialConfirmDelete(t, {
      count: ids.length,
      onOk: async () => {
        await materialBlacklistApi.delBlacklist(ids.join(','));
        toast.success(t('common.deleteSuccess'));
        setSelectedRowKeys([]);
        fetchList();
      },
    });
  };

  /** Ant Design Transfer：operations[0]=左→右（添加），operations[1]=右→左（移除） */
  const transferFilter: TransferProps['filterOption'] = (inputValue, item) => {
    const title = (item.title ?? '').toLowerCase();
    const q = inputValue.trim().toLowerCase();
    return !q || title.includes(q);
  };

  const columns: ColumnsType<any> = [
    { title: '用户编号', dataIndex: 'userId', align: 'center' },
    { title: '工号', dataIndex: 'userName', align: 'center' },
    { title: '姓名', dataIndex: 'nickName', align: 'center' },
    {
      title: '创建时间',
      key: 'createTime',
      width: 170,
      align: 'center',
      render: (_, row) =>
        formatDateTimeCell(
          firstDefinedRow(row, ['createTime', 'create_time', 'gmtCreate', 'gmt_create', 'createDate']),
        ),
    },
    {
      title: t('table.operation'),
      width: 120,
      align: 'center',
      fixed: 'right',
      render: (_, row) => (
        <div className="flex justify-center">
          <MaterialDeleteButton label={t('common.delete')} onClick={() => onDelete(row)} />
        </div>
      ),
    },
  ];

  return (
    <MaterialPageRoot>
      <MaterialToolbarCard
        filterRow={
          <>
            <div className="flex items-center gap-2">
              <label className="text-sm font-medium text-gray-700 whitespace-nowrap">工号：</label>
              <Input
                allowClear
                placeholder="请输入"
                className="w-[140px]"
                value={draftUserName}
                onChange={(e) => setDraftUserName(e.target.value)}
              />
            </div>
            <div className="flex items-center gap-2">
              <label className="text-sm font-medium text-gray-700 whitespace-nowrap">姓名：</label>
              <Input
                allowClear
                placeholder="请输入"
                className="w-[140px]"
                value={draftNickName}
                onChange={(e) => setDraftNickName(e.target.value)}
              />
            </div>
          </>
        }
        onSearch={handleQuery}
        onReset={resetQuery}
        toolbarRight={
          <>
            <Button
              type="primary"
              icon={<Plus />}
              onClick={() => {
                setTargetKeys([]);
                setModalOpen(true);
              }}
            >
              {t('common.addNew')}
            </Button>
            <Button
              danger
              icon={<Trash2 className="h-4 w-4" />}
              disabled={selectedRowKeys.length === 0}
              onClick={batchDelete}
            >
              {t('common.batchDelete')}
            </Button>
          </>
        }
      />
      <MaterialTableCard>
        <Table
          rowKey={(r) => r.recordId ?? r.id}
          loading={loading}
          columns={columns}
          dataSource={list}
          pagination={false}
          scroll={{ x: 'max-content' }}
          rowSelection={{
            selectedRowKeys,
            onChange: setSelectedRowKeys,
            preserveSelectedRowKeys: true,
            getCheckboxProps: (record) => ({ name: record.userName }),
          }}
          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}
      />

      <Modal
        title="新增"
        open={modalOpen}
        onOk={submitAdd}
        onCancel={() => {
          setModalOpen(false);
          setTargetKeys([]);
        }}
        confirmLoading={submitLoading}
        {...getMaterialFormModalProps(t, 880)}
      >
        {transferLoading ? (
          <div className="flex justify-center py-16">
            <Spin />
          </div>
        ) : (
          <Transfer
            dataSource={transferDataSource}
            titles={['可选用户', '已选用户']}
            targetKeys={targetKeys}
            onChange={(next) => setTargetKeys(next as string[])}
            render={(item) => item.title ?? item.key}
            showSearch
            filterOption={transferFilter}
            listStyle={{ width: 360, height: 400 }}
            operations={['添加', '移除']}
            locale={{
              itemUnit: '项',
              itemsUnit: '项',
              searchPlaceholder: '请输入姓名或登录名',
            }}
          />
        )}
      </Modal>
    </MaterialPageRoot>
  );
}
