/*
 * @Author: code4eat awesomedema@gmail.com
 * @Date: 2023-03-03 11:30:33
 * @LastEditors: code4eat awesomedema@gmail.com
 * @LastEditTime: 2025-05-12 14:59:43
 * @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 KCIMPagecontainer from '@/components/KCIMPageContainer';
import { KCIMTable } from '@/components/KCIMTable';

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

import {
  ActionType,
  ProFormDependency,
  ProFormInstance,
  ProFormText,
  ProFormSelect,
  ProFormDigit,
  ProFormRadio,
} from '@ant-design/pro-components';
import { ModalForm, ProFormTextArea } from '@ant-design/pro-form';
import { ProColumns } from '@ant-design/pro-table';
import { Modal, message, Popconfirm, Form, Tabs, Switch, Row, Col } from 'antd';
import { Key, useEffect, useRef, useState } from 'react';

import 'moment/locale/zh-cn';
import locale from 'antd/es/date-picker/locale/zh_CN';

import {
  addData,
  copyDataToSelectedType,
  delData,
  editData,
  getReportProjectSettingList,
  saveReportRelation,
} from './service';

import './style.less';
import TableTransfer from './transform';
import React from 'react';
import { cleanTree } from '@/utils/tooljs';
import { getDicDataBySysId } from '@/services/getDic';

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

const DEFAULT_FONT_COLOR = 'rgba(0, 0, 0, 0.85)';
const DEFAULT_PICKER_COLOR = '#000000';

const normalizeColorToHex = (rawColor?: string) => {
  if (typeof rawColor !== 'string') return DEFAULT_PICKER_COLOR;
  const color = rawColor.trim();
  if (!color) return DEFAULT_PICKER_COLOR;

  const hexMatch = color.match(/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/);
  if (hexMatch) {
    const hex = hexMatch[1];
    const normalizedHex =
      hex.length === 3
        ? hex
            .split('')
            .map((item) => `${item}${item}`)
            .join('')
        : hex;
    return `#${normalizedHex.toLowerCase()}`;
  }

  const rgbMatch = color.match(
    /^rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})(?:\s*,\s*(0|1|0?\.\d+))?\s*\)$/i,
  );
  if (rgbMatch) {
    const toHex = (value: string) => {
      const channel = Math.max(0, Math.min(255, Number(value)));
      return channel.toString(16).padStart(2, '0');
    };
    return `#${toHex(rgbMatch[1])}${toHex(rgbMatch[2])}${toHex(rgbMatch[3])}`;
  }

  return DEFAULT_PICKER_COLOR;
};

const normalizeFontColor = (rawColor?: string) => {
  if (typeof rawColor !== 'string') return DEFAULT_FONT_COLOR;
  const color = rawColor.trim();
  return color || DEFAULT_FONT_COLOR;
};

let currentRow: any = undefined;

const accountingSubjectColumn = [
  {
    title: '会计科目编码',
    dataIndex: 'accountingCode',
    ellipsis: true,
  },
  {
    title: '会计科目名',
    dataIndex: 'accountingName',
    ellipsis: true,
  },
];

const shareParamsColumn = [
  {
    title: '分摊层级Id',
    dataIndex: 'id',
    ellipsis: true,
  },
  {
    title: '分摊层级名',
    dataIndex: 'shareName',
    ellipsis: true,
  },
];

const responsibilityColumn = [
  {
    title: '责任中心编码',
    dataIndex: 'responsibilityCode',
    ellipsis: true,
  },
  {
    title: '责任中心名',
    dataIndex: 'responsibilityName',
    ellipsis: true,
  },
];

const openRule = () => {
  Modal.info({
    title: '报表项目填写注意事项！',
    width: 800,
    content: (
      <div>
        <h4>计算类型说明 </h4>
        <span>不设置：</span>
        一般用于第一层。 对应成本科目：对应的是成本科目，如工资，收入类等
        <div></div>
        <span>对应责任中心：</span>
        对应的是分摊的责任中心，放射科，功能科等
        <div></div>
        <span>对应分摊层级：</span>
        对应的是分摊的层级，如"护理"分摊层级，"医技"分摊层级。
        <div></div>
        <span>小计：</span>
        是对第一层下的所有项目的合计计算。
        <div></div>
        <span>计算公式：</span>
        是按编号对报表项目的项目进行计算结果，支持加/减法。
        <div style={{ marginBottom: 20 }}></div>
        <h4>报表项目顺序注意事项</h4>
        计算类型是小计报表项目需要维护在对应层级的其他项目之后
        <div></div>
        计算类型是计算公式的报表项目需要维护在公式里包含的其他项目之后
      </div>
    ),
  });
};

export default function ReportItemSet() {
  const [tableDataFilterParams, set_tableDataFilterParams] = useState<
    any | undefined
  >({ reportType: 0 });
  const tableRef = useRef<ActionType>();
  const formRef = useRef<ProFormInstance>();
  const [tabs, set_tabs] = useState<any[]>([]);
  const [reportType, set_reportType] = useState<Key | undefined>(undefined);
  const [calcTypes, setCalcTypes] = useState<any[]>([]);
  const columns: ProColumns[] = [
    {
      title: '报表项目名',
      dataIndex: 'reportName',
      width: 200,
    },
    {
      title: 'Id',
      dataIndex: 'id',
      width: 80,
    },
    {
      title: '编号',
      dataIndex: 'num',
      width: 80,
    },
    {
      title: '字体颜色',
      dataIndex: 'fontColor',
      width: 200,
      render: (_: any, record: any) => {
        const color = normalizeFontColor(record?.fontColor);
        return (
          <span style={{ display: 'inline-flex', alignItems: 'center' }}>
            <span
              style={{
                width: 14,
                height: 14,
                borderRadius: 2,
                background: color,
                border: '1px solid #DAE2F2',
                marginRight: 8,
              }}
            />
            <span>{color}</span>
          </span>
        );
      },
    },
    {
      title: '计算方式',
      dataIndex: 'calcType',
      renderText: (num, record) => {
        const temp = calcTypes.filter((a) => a.code == num);
        return temp.length > 0 ? temp[0].name : '';
      },
    },
    // {
    //     title: '报表类型',
    //     dataIndex: 'reportType',
    //     renderText(num) {
    //         switch (num) {
    //             case 0:
    //                 return <>损益表</>;
    //             case 1:
    //                 return <>完全成本法表</>;
    //             case 2:
    //                 return <>变动成本表</>;
    //             case 3:
    //                 return <>全院损益表</>;
    //             case 4:
    //                 return <>全成本报表</>;
    //         }
    //     },
    // },
    {
      title: '计算公式',
      width: 300,
      dataIndex: 'calcFormula',
    },
    {
      title: '项目类型',
      dataIndex: 'costType',
      renderText(num) {
        switch (num) {
          case 1:
            return <>收入</>;
          case 2:
            return <>成本</>;
        }
      },
    },
    {
      title: '占比计算类型',
      dataIndex: 'fraction',
      renderText(num) {
        switch (num) {
          case 1:
            return <>分子</>;
          case 2:
            return <>分母</>;
          case 3:
            return <>不计算</>;
        }
      },
    },
    {
      title: '排序',
      dataIndex: 'sort',
      width: 80,
    },
    {
      title: '说明',
      dataIndex: 'description',
      ellipsis: true,
    },
    {
      title: '显示',
      fixed: 'right',
      width: 60,
      dataIndex: 'hide',
      renderText: (_: any, record: any) => {
        return (
          <Switch
            size="small"
            checked={_ == 1}
            onChange={(bool) =>
              updateTable({ ...record, hide: bool ? 1 : 0 }, 'EDIT')
            }
          />
        );
      },
    },
    {
      title: '操作',
      key: 'option',
      width: 200,
      fixed: 'right',
      valueType: 'option',
      render: (_: any, record: any) => {
        const { showAddRelation, parentId, calcType } = record;

        const btnGroup = true
          ? [
              <UpDataActBtn key={'addChild'} record={record} type="ADDCHILD" />,
              <UpDataActBtn key={'act'} record={record} type="EDIT" />,
              <Popconfirm
                title="是否确认删除？"
                key="del"
                onConfirm={() => delTableData(record)}
              >
                <a>删除</a>
              </Popconfirm>,
            ]
          : [
              <UpDataActBtn key={'act'} record={record} type="EDIT" />,
              <Popconfirm
                title="是否确认删除？"
                key="del"
                onConfirm={() => delTableData(record)}
              >
                <a>删除</a>
              </Popconfirm>,
            ];

        return showAddRelation
          ? [
              ...btnGroup,
              <a
                key="config3"
                onClick={() => {
                  currentRow = record;
                  if (showAddRelation == 1)
                    oprnTableTransform(record, accountingSubjectColumn, 1);
                  if (showAddRelation == 2)
                    oprnTableTransform(record, shareParamsColumn, 2);
                  if (showAddRelation == 3)
                    oprnTableTransform(record, responsibilityColumn, 3);
                }}
              >
                {showAddRelation == 1
                  ? '会计科目'
                  : showAddRelation == 2
                  ? '分摊层级'
                  : showAddRelation == 3 && '责任中心'}
              </a>,
            ]
          : btnGroup;
      },
    },
  ];

  const getTableData = async (params: any) => {
    const { reportType } = params;
    if (reportType == undefined) return [];
    const resp = await getReportProjectSettingList({ ...params });
    if (resp) {
      return {
        data: cleanTree(resp.list),
        success: true,
        total: resp.totalCount,
        pageSize: resp.pageSize,
        totalPage: resp.totalPage,
      };
    }
    return [];
  };

  const delTableData = async (record: any) => {
    const resp = await delData([record.id]);
    if (resp) {
      message.success('操作成功！');
      tableRef.current?.reload();
      // message.success('操作成功!');
    }
  };

  const onSaveHandle = async (
    keys: Key[],
    rows: any[],
    record: any,
    settingType: number,
  ) => {
    let selectedRowKeysToStr: string[] = [];
    if (settingType == 2) {
      keys ? keys.map((item: any) => selectedRowKeysToStr.push(`${item}`)) : [];
    }

    let selectedRowKeys: Key[] = [];
    if (settingType == 1) {
      selectedRowKeys = rows.map((a: any) => a.accountingCode);
    }
    if (settingType == 2) {
      selectedRowKeys = keys.map((a: any) => `${a}`);
    }
    if (settingType == 3) {
      selectedRowKeys = rows.map((a: any) => a.responsibilityCode);
    }
    const { id: reportId } = record;
    const resp = await saveReportRelation({
      reportId,
      reportType,
      relation: settingType,
      relationCodes: selectedRowKeys,
    });
    if (resp) {
      message.success('对照成功！');
      tableRef.current?.reload();
    }
  };

  const oprnTableTransform = (
    record: any,
    transferTableColumn: ProColumns[],
    settingType: number,
  ) => {
    const ref = React.createRef<{ save: any }>();

    Modal.confirm({
      title:
        settingType == 1
          ? `选择会计科目`
          : settingType == 2
          ? '选择分摊层级'
          : '选择责任中心',
      icon: <></>,
      width: 1000,
      centered: true,
      okText: '确定',
      cancelText: '取消',
      content: (
        <TableTransfer
          ref={ref}
          keyName={
            settingType == 1
              ? `accountingCode`
              : settingType == 2
              ? 'id'
              : 'responsibilityCode'
          }
          record={record}
          settingType={settingType}
          onSave={(keys, rows, settingType) =>
            onSaveHandle(keys, rows, record, settingType)
          }
          leftColumns={transferTableColumn}
          rightColumns={transferTableColumn}
        ></TableTransfer>
      ),
      onOk: () => {
        return ref.current && ref.current.save();
      },
    });
  };

  const updateTable = async (
    formVal: any,
    type: 'EDIT' | 'ADD' | 'ADDCHILD' | 'COPY',
  ) => {
    if (type == 'ADD' || type == 'ADDCHILD') {
      let parentId = 0;
      const {
        calcType = 0,
        calcFormula = '',
        fontColor = DEFAULT_PICKER_COLOR,
      } = formVal;

      type == 'ADDCHILD' && (parentId = formVal.id);

      const result = {
        ...formVal,
        calcType,
        calcFormula,
        fontColor: normalizeColorToHex(fontColor),
        isLoss: formVal.isLoss ? 1 : 0,
        reportType: Number(reportType),
        parentId,
        decimalPlace: formVal.decimalPlace,
        permil: formVal.dataType === 1 ? (formVal.permil ? 1 : 0) : 0,
      };

      const resp = await addData(result);
      if (resp) {
        currentRow = undefined;
        tableRef.current?.reload();
        message.success('操作成功！');
      }
    }
    if (type == 'EDIT') {
      try {
        const {
          reportName,
          sort,
          calcType = 0,
          calcFormula = '',
          isLoss,
          parentId,
          id,
          fraction,
          costType,
          description,
          hide,
          dataType,
          decimalPlace,
          permil,
          fontColor = DEFAULT_PICKER_COLOR,
        } = formVal;
        const result = {
          id,
          parentId,
          reportName,
          sort,
          reportType,
          calcType,
          calcFormula,
          fraction,
          costType,
          isLoss: isLoss ? 1 : 0,
          description,
          hide,
          dataType,
          fontColor: normalizeColorToHex(fontColor),
          decimalPlace: decimalPlace,
          permil: dataType === 1 ? (permil ? 1 : 0) : 0,
        };
        const resp = await editData(result);
        if (resp) {
          tableRef.current?.reload();
          message.success('操作成功！');
        }
      } catch (error) {
        console.log({ error });
      }
    }
    if (type == 'COPY') {
      //复制数据
      const { toReportType } = formVal;
      const resp = await copyDataToSelectedType({
        fromReportType: Number(reportType),
        toReportType,
      });
      if (resp) {
        message.success('复制成功！');
        tableRef.current?.reload();
      }
    }
    return true;
  };

  const UpDataActBtn = ({
    record,
    type,
  }: {
    record: any;
    type: 'EDIT' | 'ADD' | 'ADDCHILD' | 'COPY';
  }) => {
    const reportType =
      type == 'EDIT' || type == 'ADDCHILD' ? record.reportType : undefined;
    return (
      <ModalForm
        title={
          type == 'COPY' ? '复制' : `${type == 'EDIT' ? '编辑' : '新增'}报表`
        }
        width={380}
        formRef={formRef}
        initialValues={
          type == 'EDIT'
            ? {
                ...record,
                permil: record.dataType === 1 ? !!record.permil : false,
                fontColor: normalizeColorToHex(
                  record?.fontColor || DEFAULT_FONT_COLOR,
                ),
              }
            : {
                dataType: 1,
                decimalPlaces: 2,
                permil: false,
                fontColor: DEFAULT_PICKER_COLOR,
              }
        }
        trigger={
          type == 'EDIT' ? (
            <a key="edit">编辑</a>
          ) : type == 'ADDCHILD' ? (
            <a className="add">添加</a>
          ) : type == 'COPY' ? (
            <span className="copy" style={{ marginRight: 8 }}>
              复制
            </span>
          ) : (
            <span className="add">新增</span>
          )
        }
        onFinish={(val) => {
          return updateTable(
            type == 'EDIT'
              ? { ...record, ...val }
              : type == 'ADDCHILD'
              ? { ...val, id: record.id }
              : { ...val },
            type,
          );
        }}
        modalProps={{ destroyOnClose: true }}
        colProps={{ span: 24 }}
        grid
      >
        {type != 'COPY' && (
          <>
            <ProFormText
              label="报表名"
              rules={[
                {
                  required: true,
                  message: '报表名是必填项！',
                },
              ]}
              name="reportName"
            />
            <ProFormDigit
              label="排序"
              rules={[
                {
                  required: true,
                  message: '排序必填项！',
                },
              ]}
              name="sort"
            />
            {
              //新增顶级不展示
              <>
                <ProFormSelect
                  name="calcType"
                  label="计算类型"
                  options={[
                    ...calcTypes.map((a) => ({
                      label: a.name,
                      value: Number(a.code),
                    })),
                  ]}
                  placeholder="请选择状态"
                  rules={[{ required: true, message: '请选择计算类型!' }]}
                />

                <ProFormDependency name={['calcType']}>
                  {({ calcType }) => {
                    // const resp = await getResponsibilityCenterList({pageSize:100,current:1});
                    return calcType == 4 ? (
                      <ProFormText
                        label="计算公式"
                        rules={[
                          {
                            required: true,
                            message: '计算公式是必填项！',
                          },
                        ]}
                        placeholder="例如：[1] + [2]"
                        name="calcFormula"
                      />
                    ) : (
                      <></>
                    );
                  }}
                </ProFormDependency>
                <ProFormDependency name={['calcType']}>
                  {({ calcType }) => {
                    // const resp = await getResponsibilityCenterList({pageSize:100,current:1});
                    return calcType == 4 && reportType == 3 ? (
                      <Form.Item
                        name="isLoss"
                        label="损益标志"
                        valuePropName="checked"
                      >
                        <Switch size="small" />
                      </Form.Item>
                    ) : (
                      <></>
                    );
                  }}
                </ProFormDependency>
              </>
            }
            <ProFormSelect
              name="costType"
              label="报表项目类型"
              options={[
                { label: '收入', value: 1 },
                { label: '成本', value: 2 },
              ]}
              placeholder="请选择"
              rules={[{ required: true, message: '请选择报表项目类型!' }]}
            />
            <ProFormSelect
              name="fraction"
              label="占比计算类型"
              options={[
                { label: '分子', value: 1 },
                { label: '分母', value: 2 },
                { label: '不计算', value: 3 },
              ]}
              placeholder="请选择"
              rules={[{ required: true, message: '请选择占比计算类型!' }]}
            />
            <ProFormText
              name="fontColor"
              label="字体颜色"
              fieldProps={{
                type: 'color',
                allowClear: false,
                style: {
                  width: 72,
                  height: 24,
                  padding: 0,
                  border: 0,
                  background: 'transparent',
                },
              }}
              rules={[{ required: true, message: '请选择字体颜色!' }]}
            />
            <ProFormRadio.Group
              name="dataType"
              label="数据格式"
              options={[
                { label: '数值', value: 1 },
                { label: '百分比', value: 2 },
              ]}
              rules={[{ required: true }]}
            />
            <ProFormDependency name={['dataType']}>
              {({ dataType }) => {
                return dataType === 1 ? (
                  <>
                    <Row gutter={16}>
                      <Col span={12}>
                        <ProFormDigit
                          label="小数位数"
                          name="decimalPlace"
                          min={0}
                          max={10}
                          fieldProps={{ precision: 0 }}
                          rules={[
                            { required: true, message: '请输入小数位数!' },
                          ]}
                        />
                      </Col>
                      <Col span={12}>
                        <Form.Item
                          label="是否需要千分号"
                          name="permil"
                          valuePropName="checked"
                          style={{ marginBottom: '24px' }}
                        >
                          <Switch size="small" />
                        </Form.Item>
                      </Col>
                    </Row>
                  </>
                ) : (
                  <ProFormDigit
                    label="小数位数"
                    name="decimalPlace"
                    min={0}
                    max={10}
                    fieldProps={{ precision: 0 }}
                    rules={[{ required: true, message: '请输入小数位数!' }]}
                  />
                );
              }}
            </ProFormDependency>
            <ProFormTextArea
              label="说明"
              placeholder="请输入"
              name="description"
            />
          </>
        )}
        {type == 'COPY' && (
          <ProFormSelect
            name="toReportType"
            label="复制到"
            width="sm"
            options={tabs.map((a) => ({ label: a.label, value: a.key }))}
            placeholder="请选择"
            rules={[{ required: true, message: '请选择复制到目标!' }]}
          />
        )}
      </ModalForm>
    );
  };

  const onTabChanged = (key: Key) => {
    set_reportType(key);
    set_tableDataFilterParams({ ...tableDataFilterParams, reportType: key });
  };

  const getTabs = async () => {
    const { systemId } = JSON.parse(
      localStorage.getItem('currentSelectedTab') as string,
    );
    const resp = await getDicDataBySysId(systemId, 'PROFIT_REPORT_TYPE');
    if (resp) {
      const { dataVoList } = resp;
      set_tabs(
        dataVoList.map((a: any) => ({ label: a.name, key: Number(a.code) })),
      );
      set_tableDataFilterParams({
        ...tableDataFilterParams,
        reportType: dataVoList.length > 0 ? dataVoList[0].code : undefined,
      });
      set_reportType(dataVoList.length > 0 ? dataVoList[0].code : undefined);
    }
  };

  useEffect(() => {
    const fetchData = async () => {
      const { systemId } = JSON.parse(
        localStorage.getItem('currentSelectedTab') as string,
      );
      const resp = await getDicDataBySysId(systemId, 'REPORT_ITEM_CALC_TYPE');
      setCalcTypes(resp?.dataVoList ?? []);
    };
    fetchData();
    getTabs();
  }, []);

  return (
    <KCIMPagecontainer className="ReportItemSet" title={false}>
      <div className="header">
        <div className="pageTitle">报表项目设置</div>
        <div className="btnGroup">
          <span
            style={{ marginRight: 8, cursor: 'pointer' }}
            onClick={() => openRule()}
          >
            <img
              style={{ width: 16, marginRight: 4, marginTop: -1 }}
              src={require('../../../../../static/tip.png')}
            />
            说明
          </span>
          <UpDataActBtn record={undefined} type="COPY" />
          <UpDataActBtn record={undefined} type="ADD" />
        </div>
      </div>

      <div
        className="toolBar"
        style={{
          display: 'flex',
          flexDirection: 'row',
          justifyContent: 'space-between',
          alignItems: 'center',
        }}
      >
        <Tabs
          defaultActiveKey={tabs.length > 0 ? tabs[0].key : undefined}
          items={tabs}
          key={'key'}
          onChange={(key) => onTabChanged(key)}
        />
      </div>

      <div>
        <KCIMTable
          pagination={false}
          scroll={{ x: 1700, y: `calc(100vh - 191px)` }}
          columns={columns as ProColumns[]}
          actionRef={tableRef}
          rowKey="id"
          params={tableDataFilterParams}
          request={(params) => getTableData(params)}
        />
      </div>
    </KCIMPagecontainer>
  );
}
