/*
 * @Author: code4eat awesomedema@gmail.com
 * @Date: 2023-03-03 11:30:33
 * @LastEditors: code4eat awesomedema@gmail.com
 * @LastEditTime: 2025-02-28 15:18:53
 * @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/pubDicTypeMana/index.tsx
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */

import { createFromIconfontCN } from '@ant-design/icons';

import { ModalForm, ProFormDependency, ProFormInstance, ProFormRadio, ProFormSelect, ProFormText, ProFormTextArea } from '@ant-design/pro-form';
import { ActionType, ProColumns } from '@ant-design/pro-table';
import { Input, message, Popconfirm, Switch, Tooltip } from 'antd';
import { useEffect, useRef, useState } from 'react';

import 'moment/locale/zh-cn';

import { addData, applyBatchItemValueReq, delData, editData, generateTableDataReq, getCurrentHospAlldeps, getTableList } from './service';

import './style.less';

import React from 'react';
import generateTableData from './generateTableData';
import { useModel } from 'umi';
import KCTable from '@/components/kcTable';

const IconFont = createFromIconfontCN({
  scriptUrl: '',
});

//填报周期
export const DATAFILL_PERIODTYPE = [
  { label: '月度', value: 1 },
  { label: '季度', value: 2 },
  { label: '年度', value: 3 },
  { label: '变动时', value: 4 },
];
//填报主体类型
export const DATAFILL_MAINTYPE = [
  { label: '职能部门', value: 1 },
  { label: '相关科室', value: 2 },
];

//填报维度
export const DATAFILL_DIMENSIONTYPE = [
  { label: '按全院  ', value: 1 },
  { label: '按科室', value: 2 },
];

type Data = {
  // 键为科室/部门编码，保持字符串类型
  [key: string]: string;
};

type LabelValue = {
  label: string;
  // value 需保持为字符串编码，避免多选时因 NaN 造成同值冲突
  value: string;
};

// 全局简单缓存，避免每次打开不同弹窗都重复请求
let cachedDeptOptions: LabelValue[] | null = null;

export function transformToLabelValue(data: Data): LabelValue[] {
  const result: LabelValue[] = [];
  for (const key in data) {
    if (data.hasOwnProperty(key)) {
      result.push({
        label: data[key],
        value: key,
      });
    }
  }
  return result;
}

export const searchTree = (tree: any[], searchTerm: string) => {
  const searchTermLower = searchTerm.toLowerCase();

  function searchNode(node: any) {
    const matchedChildren: any[] = [];

    if (node.children && node.children.length > 0) {
      node.children.forEach((child: any) => {
        const matchedChild = searchNode(child);
        if (matchedChild) {
          matchedChildren.push(matchedChild);
        }
      });
    }

    if (node.responsibilityName.toLowerCase().includes(searchTermLower) || (node.responsibilityCode && node.responsibilityCode.toLowerCase().includes(searchTermLower))) {
      return {
        ...node,
        children: matchedChildren.length > 0 ? matchedChildren : node.children,
      };
    } else if (matchedChildren.length > 0) {
      return {
        ...node,
        children: matchedChildren,
      };
    }

    return null;
  }

  return tree.map((rootNode) => searchNode(rootNode)).filter((node) => node !== null);
};

const defaultYear = new Date().getFullYear();
let table_columns: any[] = [];
let total_tableDataSource: any[] = [];

export default function FillingMana() {
  const { initialState, setInitialState } = useModel('@@initialState');
  const [tableDataFilterParams, set_tableDataFilterParams] = useState<{
    current: number;
    pageSize: number;
    name?: string;
  }>({
    current: 1,
    pageSize: 10
  });
  const [tableDataSearchKeywords, set_tableDataSearchKeywords] = useState<string>('');
  const tableRef = useRef<ActionType>();
  const detailTableRef = useRef<ActionType>();
  const formRef = useRef<ProFormInstance>();
  const [tableDataSource, set_tableDataSource] = useState<any[]>([]);
  const [tableColumns, set_tableColumns] = useState<ProColumns[]>([]);
  const [currentEditRow, set_currentEditRow] = useState<any>(undefined);
  const [actionType, set_actionType] = useState<'NORMAL' | 'DETAIL' | undefined>('NORMAL');
  const [currentEditTableRow, set_currentEditTableRow] = useState<any>(undefined);
  const [currentYear, set_currentYear] = useState(defaultYear);
  const [isFirstLoad, setIsFirstLoad] = useState(true);

  const tableColumns_default: ProColumns[] = [
    {
      title: '操作',
      key: 'option',
      fixed: 'right',
      width: 80,
      valueType: 'option',
      render: (_: any, record: any) => {
        return (
          <a
            key={'edit'}
            onClick={() => {
              set_currentEditTableRow(record);
            }}
          >
            编辑
          </a>
        );
      },
    },
  ];

  const columns: ProColumns[] = [
    {
      title: '填报项目',
      ellipsis: true,
      dataIndex: 'name',
    },
    {
      title: '填报周期',
      ellipsis: true,
      dataIndex: 'periodType',
      renderText(code, record, index, action) {
        const item = DATAFILL_PERIODTYPE.find((item) => item.value === code);
        return item ? item.label : '';
      },
    },
    {
      title: '填报维度',
      ellipsis: true,
      dataIndex: 'dimensionType',
      renderText(code, record, index, action) {
        const item = DATAFILL_DIMENSIONTYPE.find((item) => item.value === code);
        return item ? item.label : '';
      },
    },
    {
      title: '填报主体类型',
      ellipsis: true,
      dataIndex: 'type',
      renderText(code, record, index, action) {
        const item = DATAFILL_MAINTYPE.find((item) => item.value === code);
        return item ? item.label : '';
      },
    },
    {
      title: '填报主体',
      ellipsis: true,
      dataIndex: 'typeName',
      renderText(_, record) {
        // 根据维度类型从 fillDeptList 提取名称并用逗号拼接
        const list = Array.isArray(record?.fillDeptList) ? record.fillDeptList : [];
        const names = list
          .map((item: any) => {
            if (record?.dimensionType === 2) {
              return item?.dimensionTypeName ?? item?.departmentName ?? '';
            }
            // 默认按全院/维度类型为 1 时取 departmentName
            return item?.departmentName ?? item?.dimensionTypeName ?? '';
          })
          .filter((s: string) => s);
        return names.join(',');
      },
    },
    {
      title: '填报单位',
      ellipsis: true,
      dataIndex: 'unit',
    },
    {
      title: '填报说明',
      ellipsis: true,
      dataIndex: 'description',
    },
    {
      title: '启用',
      width: 60,
      ellipsis: true,
      dataIndex: 'status',
      renderText(num, record) {
        return (
          <Switch
            size="small"
            checked={num}
            onChange={(bool) =>
              updateTable(
                {
                  ...record,
                  status: bool ? 1 : 0,
                  fillDeptList: record?.fillDeptList.map((a: any) => ({ value: a.departmentCode, label: a.departmentName })),
                  relateDeptList: record?.relateDeptList.map((a: any) => ({ value: a.departmentCode, label: a.departmentName })),
                },
                'EDIT',
              )
            }
          />
        );
      },
    },
    {
      title: '操作',
      key: 'option',
      fixed: 'right',
      width: 120,
      valueType: 'option',
      render: (_: any, record: any) => {
        const { applyStatus } = record;

        return [
          <a
            key={'detail'}
            onClick={() => {
              set_currentEditRow(record);
            }}
          >
            详情
          </a>,
          <UpDataActBtn record={record} type={'EDIT'} />,
          <Popconfirm title="是否确认删除？" key="del" onConfirm={() => delTableData(record)}>
            <a>删除</a>
          </Popconfirm>,
        ];
      },
    },
  ];

  const getGenerateTableData = async () => {
    const resp = await generateTableDataReq({ fillItemCode: currentEditRow?.code, dataYear: currentYear });
    if (resp) {
      const { itemTitles, itemDatas } = resp;
      const { columns, dataSource } = generateTableData(itemTitles, itemDatas, [0]);
      table_columns = columns;
      total_tableDataSource = dataSource;
      set_tableColumns(columns);
      set_tableDataSource(dataSource);
    }
  };
  const getTableData = async (params: any) => {
    const { current = 1, pageSize = 10, name } = params;
    const resp = await getTableList({
      current,
      pageSize,
      name
    });
    if (resp) {
      return {
        data: resp.list,
        success: true,
        total: resp.totalCount
      };
    }
    return {
      data: [],
      success: false,
      total: 0
    };
  };

  const delTableData = async (record: any) => {
    const resp = await delData(record.code);
    if (resp) {
      tableRef.current?.reload();
    }
  };

  const updateTable = async (data: any, type: 'ADD' | 'EDIT') => {
    try {
      const result = {
        name: data.name,
        type: data.type,
        dimensionType: data.type == 2 ? 2 : data.dimensionType,
        periodType: data.periodType,
        unit: data.unit,
        status: type == 'ADD' ? null : data.status,
        description: data.description,
        fillDeptList:
          data.fillDeptList instanceof Array
            ? data.fillDeptList.map((a: any) => ({ departmentCode: a.value, departmentName: a.label }))
            : [{ departmentCode: data.fillDeptList.value, departmentName: data.fillDeptList.label }],
        relateDeptList: data.type != 2 && data.dimensionType != 1 && data.relateDeptList ? data.relateDeptList.map((a: any) => ({ departmentCode: a.value, departmentName: a.label })) : [],
      };

      if (type == 'ADD') {
        const resp = await addData(result);
        if (resp) {
          tableRef.current?.reload();
          return true;
        }
      }
      if (type == 'EDIT') {
        const resp = await editData({ code: data.code, ...result });
        if (resp) {
          tableRef.current?.reload();
        }
        return true;
      }
    } catch (error) {
      console.log({ 'updateTable error': error });
    }

    return false;
  };

  const handleTableChange = (pagination: any) => {
    set_tableDataFilterParams({
      ...tableDataFilterParams,
      current: pagination.current,
      pageSize: pagination.pageSize
    });
  }

  const tableDataSearchHandle = (paramName: string) => {
    set_tableDataFilterParams({
      ...tableDataFilterParams,
      current: 1,
      [`${paramName}`]: tableDataSearchKeywords
    });
  }

  const detailtableDataSearchHandle = (paramName: string) => {
    const result = total_tableDataSource.filter((a: any) => a[`${paramName}`].indexOf(tableDataSearchKeywords) != -1);
    set_tableDataSource(result);
  };

  const UpDataActBtn = ({ record, type, sideHandle }: { record: any; type: 'EDIT' | 'ADD'; sideHandle?: { [key: string]: any } }) => {
    const actType = type;
    const ref = React.createRef<{ save: any }>();
    const [maintype, set_maintype] = useState(undefined);
    const [dimensionType, set_dimensionType] = useState(undefined);
    // 本地选项缓存，避免每次搜索触发远程过滤
    const [deptOptions, set_deptOptions] = useState<LabelValue[]>([]);
    const { commitResult } = sideHandle ? sideHandle : {};

    useEffect(() => {
      if (type !== undefined) {
        formRef.current?.setFieldValue('fillDeptList', []); // 清空填报主体
      }
    }, [maintype]);

    useEffect(() => {
      if (dimensionType !== undefined) {
        formRef.current?.setFieldValue('relateDeptList', []); // 清空填相关科室
      }
    }, [dimensionType]);

    // 弹窗打开时才加载选项，并使用文件级缓存
    const ensureDeptOptions = async () => {
      if (deptOptions && deptOptions.length > 0) return;
      if (cachedDeptOptions && cachedDeptOptions.length > 0) {
        set_deptOptions(cachedDeptOptions);
        return;
      }
      const depLists = await getCurrentHospAlldeps();
      const opts = depLists ? transformToLabelValue(depLists) : [];
      cachedDeptOptions = opts;
      set_deptOptions(opts);
    };

    return (
      <ModalForm
        title={`${type == 'EDIT' ? '编辑' : '新增'}`}
        width={352}
        formRef={formRef}
        initialValues={
          type == 'EDIT'
            ? {
                ...record,
                // 使用字符串编码，避免多选时因 NaN 造成同值冲突
                fillDeptList: record?.fillDeptList?.map((a: any) => ({ label: a.departmentName, value: a.departmentCode })) || [],
                relateDeptList: record?.relateDeptList?.map((a: any) => ({ label: a.departmentName, value: a.departmentCode })) || [],
              }
            : { periodType: 1, type: 1, dimensionType: 1 }
        }
        trigger={
          type == 'EDIT' ? (
            <a key="edit" onClick={() => ensureDeptOptions()}>编辑</a>
          ) : (
            <a className="add" onClick={() => ensureDeptOptions()}>新增</a>
          )
        }
        onFinish={(val) => {
          commitResult && commitResult();
          return updateTable(type == 'EDIT' ? { ...val, status: record.status } : { ...val }, type);
        }}
        modalProps={{ destroyOnClose: true }}
        colProps={{ span: 24 }}
        grid
      >
        {
          <>
            <ProFormText
              name="name"
              label="填报项目："
              placeholder="请输入"
              // disabled={type == 'EDIT'}
              rules={[{ required: true, message: '填报项目不能为空!' }]}
            />
            <ProFormText name="code" label="填报编码：" hidden={type == 'ADD'} disabled={type == 'EDIT'} />
            <ProFormRadio.Group label="填报周期：" name="periodType" disabled={type == 'EDIT' && record.limitFlag} options={DATAFILL_PERIODTYPE} rules={[{ required: true }]} />
            <ProFormRadio.Group
              label="填报主体类型："
              name="type"
              disabled={type == 'EDIT' && record.limitFlag}
              options={DATAFILL_MAINTYPE}
              rules={[{ required: true }]}
              fieldProps={{
                onChange(e) {
                  set_maintype(e.target.value);
                },
              }}
            />
            <ProFormDependency name={['type']}>
              {({ type }) => {
                return (
                  <>
                    <ProFormSelect
                      label="填报主体："
                      name="fillDeptList"
                      disabled={actType == 'EDIT' && record.limitFlag}
                      options={deptOptions}
                      fieldProps={
                        type === 2
                          ? {
                              mode: 'multiple', // 禁止自由录入，避免检索词生成新项
                              maxTagCount: 'responsive',
                              labelInValue: true,
                              size: 'small',
                              // 开启检索（按名称与编码匹配）
                              showSearch: true,
                              optionFilterProp: 'label',
                              filterOption: (input: string, option: any) => {
                                const label: string = (option?.label ?? '').toString();
                                const value: string = (option?.value ?? '').toString();
                                const kw = input.toLowerCase();
                                return label.toLowerCase().includes(kw) || value.toLowerCase().includes(kw);
                              },
                            }
                          : {
                              labelInValue: true,
                              size: 'small',
                              // 开启检索（按名称与编码匹配）
                              showSearch: true,
                              optionFilterProp: 'label',
                              filterOption: (input: string, option: any) => {
                                const label: string = (option?.label ?? '').toString();
                                const value: string = (option?.value ?? '').toString();
                                const kw = input.toLowerCase();
                                return label.toLowerCase().includes(kw) || value.toLowerCase().includes(kw);
                              },
                            }
                      }
                      rules={[{ required: true, message: '填报主体不能为空!' }]}
                    />

                    {type != 2 && (
                      <>
                        <ProFormRadio.Group label="填报维度：" name="dimensionType" disabled={type == 'EDIT' && record.limitFlag} options={DATAFILL_DIMENSIONTYPE} rules={[{ required: true }]} />
                        <ProFormDependency name={['dimensionType']}>
                          {({ dimensionType }) => {
                            return (
                              dimensionType == 2 && (
                                <ProFormSelect
                                  label="相关科室："
                                  disabled={type == 'EDIT' && record.limitFlag}
                                  name={'relateDeptList'}
                                  options={deptOptions}
                                  fieldProps={{
                                    mode: 'multiple', // 禁止自由录入
                                    maxTagCount: 'responsive',
                                    labelInValue: true,
                                    size: 'small',
                                    // 开启检索（按名称与编码匹配）
                                    showSearch: true,
                                    optionFilterProp: 'label',
                                    filterOption: (input: string, option: any) => {
                                      const label: string = (option?.label ?? '').toString();
                                      const value: string = (option?.value ?? '').toString();
                                      const kw = input.toLowerCase();
                                      return label.toLowerCase().includes(kw) || value.toLowerCase().includes(kw);
                                    },
                                  }}
                                  rules={[{ required: true, message: '相关科室不能为空!' }]}
                                />
                              )
                            );
                          }}
                        </ProFormDependency>
                      </>
                    )}
                  </>
                );
              }}
            </ProFormDependency>

            <ProFormText name="unit" label="填报值单位：" placeholder="请输入" rules={[{ required: true, message: '填报值单位不能为空!' }]} />
            <ProFormTextArea
              name="description"
              label="填报说明："
              placeholder="请输入"
              fieldProps={{
                rows: 4,
              }}
              rules={[{ required: false }]}
            />
          </>
        }
      </ModalForm>
    );
  };

  useEffect(() => {
    if (!isFirstLoad) {
      getGenerateTableData();
    } else {
      setIsFirstLoad(false); // 标记首次加载已完成
    }
  }, [currentYear]);

  useEffect(() => {
    if (currentEditRow) {
      set_actionType('DETAIL');
      getGenerateTableData();
    } else {
      set_actionType('NORMAL');
    }
  }, [currentEditRow]);

  return (
    <div className="FillingMana">
      {actionType == 'DETAIL' && (
        <div className="FillingMana-detail">
          <div className="FillingMana-detail-header">
            <div className="FillingMana-detail-header-title">
              <div className="backBtn" onClick={() => set_currentEditRow(undefined)}>
                <IconFont style={{ fontSize: 15 }} type={'iconfanhui'} />
              </div>
              <span>{currentEditRow?.name}</span>
            </div>
            <div className="FillingMana-detail-header-title-sub">
              <span>
                填报周期：
                {currentEditRow &&
                  `${DATAFILL_PERIODTYPE.find((item) => item.value === currentEditRow.periodType) ? DATAFILL_PERIODTYPE.find((item) => item.value === currentEditRow.periodType)?.label : ''}`}
              </span>
              <span>
                填报维度：
                {currentEditRow &&
                  `${
                    DATAFILL_DIMENSIONTYPE.find((item) => item.value === currentEditRow.dimensionType) ? DATAFILL_DIMENSIONTYPE.find((item) => item.value === currentEditRow.dimensionType)?.label : ''
                  }`}
              </span>
              <span>填报单位：{currentEditRow?.unit}</span>
            </div>
          </div>
          <div className="FillingMana-detail-content">
            <div className="toolBar">
              <div className="filter">
                <div className="filterItem">
                  <span className="label" style={{ whiteSpace: 'nowrap' }}>
                    {' '}
                    检索：
                  </span>
                  <Input
                    placeholder={'填报科室'}
                    allowClear
                    autoComplete="off"
                    suffix={<IconFont type="iconsousuo" style={{ color: '#99A6BF' }} onClick={() => detailtableDataSearchHandle('dimensionName')} />}
                    onChange={(e) => {
                      set_tableDataSearchKeywords(e.target.value);
                      if (e.target.value.length == 0) {
                        set_tableDataSource(total_tableDataSource);
                      }
                    }}
                    onPressEnter={(e: any) => {
                      const result = total_tableDataSource.filter((a: any) => a.dimensionName.indexOf(e.target.value) != -1);
                      set_tableDataSource(result);
                    }}
                  />
                </div>
              </div>
              <div className="btnGroup">
                {(currentEditRow?.periodType == 1 || currentEditRow?.periodType == 2) && (
                  <div className="changeBtn">
                    <div className="actBtn" onClick={() => set_currentYear(currentYear - 1)}>
                      <IconFont type={'iconshuangzuo'} />
                    </div>
                    <span style={{ padding: '0 8px' }}>{currentYear}</span>
                    <div className="actBtn" onClick={() => set_currentYear(currentYear + 1)}>
                      <IconFont type={'iconshuangyou'} />
                    </div>
                  </div>
                )}
              </div>
            </div>
            <KCTable
              newVer
              actionRef={detailTableRef}
              columns={[...tableColumns, ...tableColumns_default]}
              scroll={{ y: 'calc(100vh - 298px)', x: `${tableColumns.length * 120}px` }}
              rowKey="id"
              dataSource={tableDataSource}
              pagination={false}
              editable={{
                editableKeys: currentEditTableRow ? [currentEditTableRow.id] : [],
                actionRender: (row, config, defaultDom) => [defaultDom.save, defaultDom.cancel],
                onSave: async (key, record, originRow, newLineConfig) => {
                  let unEditableColum: any = [];
                  const editableColumn = table_columns.filter((a: any) => {
                    !a.editable && unEditableColum.push(a);
                    return a.editable;
                  });

                  const result = editableColumn.map((a: any) => ({
                    fillItemCode: record[`${unEditableColum[0].dataIndex}_fillItemCode`],
                    dimensionCode: record[`${unEditableColum[0].dataIndex}_dimensionCode`],
                    periodCode: a.key,
                    value: record[`${a.key}`] ?? null,
                    dataYear: currentYear,
                  }));
                  const resp = await applyBatchItemValueReq(result);
                  if (resp) {
                    set_currentEditTableRow(undefined);
                    getGenerateTableData();
                  }
                  return Promise.resolve(true);
                },
                onCancel: (key, record, originRow, newLineConfig) => {
                  set_currentEditTableRow(undefined);
                  return Promise.resolve(true);
                },
              }}
            />
          </div>
        </div>
      )}
      {actionType != 'DETAIL' && (
        <div style={{ padding: 16, background: '#fff', borderRadius: 4 }}>
          <div className="toolBar">
            <div className="filter">
              <div className="filterItem">
                <span className="label" style={{ whiteSpace: 'nowrap' }}>
                  {' '}
                  检索：
                </span>
                <Input
                  placeholder={'填报项目'}
                  allowClear
                  autoComplete="off"
                  suffix={<IconFont type="iconsousuo" style={{ color: '#99A6BF' }} onClick={() => tableDataSearchHandle('name')} />}
                  onChange={(e) => {
                    set_tableDataSearchKeywords(e.target.value);
                    if (e.target.value.length == 0) {
                      set_tableDataFilterParams({
                        ...tableDataFilterParams,
                        current: 1,
                        name: '',
                      });
                    }
                  }}
                  onPressEnter={(e) => {
                    set_tableDataFilterParams({
                      ...tableDataFilterParams,
                      current: 1,
                      name: (e.target as HTMLInputElement).value,
                    });
                  }}
                />
              </div>
            </div>
            <div className="btnGroup">
              <UpDataActBtn record={undefined} type={'ADD'} />
            </div>
          </div>
          <KCTable
            columns={columns}
            scroll={{ y: `calc(100vh - 250px)` }}
            rowKey="id"
            newVer
            params={tableDataFilterParams}
            request={(params) => getTableData(params)}
            onChange={handleTableChange}
          />
        </div>
      )}
    </div>
  );
}
