import React, { useRef } from 'react';
import { useIntl } from 'umi';
import type { ProFormInstance } from '@ant-design/pro-form';
import { ModalForm, ProFormRadio } from '@ant-design/pro-form';
import * as XLSX from 'xlsx';

type Column = {
  code: string;
  name: string;
};

type ColumnInternal = {
  code: string[];
  name: string;
};

export type ExportFormProps = {
  dataGetter: (pageParams: { current: number; pageSize: number }) => Promise<any[]>;
  columnsGetter: () => Promise<Column[]>;
  fileNameProvider?: () => Promise<string>;
  param: Partial<{
    current: number;
    pageSize: number;
  }>;
  visible: boolean;
  onVisibleChange: (visible: boolean) => void;
  onSubmitting: () => Promise<any>;
  onSuccess: (params: any) => Promise<void>;
  onError: (params: any, error: unknown) => Promise<void>;
};

function getValueByCode(obj: any, code: string[]): any {
  return getValueByCodeAndIndex(obj, code, 0);
}

function getValueByCodeAndIndex(obj: any, code: string[], index: number): any {
  if (code.length > index) {
    return getValueByCodeAndIndex(obj[code[index]], code, index + 1);
  }
  return obj;
}

const ExportForm: React.FC<ExportFormProps> = (props) => {
  const intl = useIntl();
  const formRef = useRef<ProFormInstance>();

  return (
    <ModalForm
      formRef={formRef}
      title={intl.formatMessage({
        id: 'component.option.exprot.excel',
        defaultMessage: '导出到Excel',
      })}
      width="600px"
      visible={props.visible}
      onVisibleChange={(visible: boolean) => {
        if (visible) {
          formRef?.current?.setFieldsValue({
            type: 'all',
          });
        }
        props.onVisibleChange(visible);
      }}
      onFinish={async (value: { type: string }) => {
        const params = await props.onSubmitting();
        let pageParams: { current: number; pageSize: number };
        switch (value.type) {
          case 'current':
            pageParams = {
              current: props.param.current || 1,
              pageSize: props.param.pageSize || 20,
            };
            break;
          case 'all':
            pageParams = {
              current: 1,
              pageSize: 10000,
            };
            break;
          default:
            pageParams = {
              current: 1,
              pageSize: 0,
            };
            break;
        }
        try {
          const cols: ColumnInternal[] = (await props.columnsGetter()).map((i) => ({
            code: i.code.split('.'),
            name: i.name,
          }));
          if (cols.length == 0) {
            return;
          }
          const data = await props.dataGetter(pageParams);

          let fileName;
          if (props.fileNameProvider) {
            fileName = await props.fileNameProvider();
          } else {
            fileName = 'Data.xlsx';
          }

          const excelData = data.map((item) => {
            const obj = {};
            cols.forEach((col) => {
              obj[col.name] = getValueByCode(item, col.code);
            });
            return obj;
          });

          const workBook = XLSX.utils.book_new();
          const workSheet = XLSX.utils.json_to_sheet(excelData);
          XLSX.utils.book_append_sheet(workBook, workSheet);
          XLSX.writeFile(workBook, fileName, { bookType: 'xlsx' });
          await props.onSuccess(params);
        } catch (error) {
          await props.onError(params, error);
        }
      }}
    >
      <ProFormRadio.Group
        name="type"
        options={[
          {
            label: intl.formatMessage({
              id: 'component.option.exprot.type.current',
              defaultMessage: '当前页',
            }),
            value: 'current',
          },
          {
            label: intl.formatMessage({
              id: 'component.option.exprot.type.all',
              defaultMessage: '所有页',
            }),
            value: 'all',
          },
        ]}
      />
    </ModalForm>
  );
};

export default ExportForm;
