import { condition, setAdvancedConfigToProps } from '../../util/util';
import {
  CnDatePickerPro,
  CnWeekPicker2,
  CnMonthPicker2,
  CnYearPicker2,
} from '@cainiaofe/cn-ui';
import { DisplayPosition } from '../position/display-position';
import React, { useEffect, useState } from 'react';
import { componentMap as formComponentMap } from '@cainiaofe/cn-ui';
import dayjs from 'dayjs';
import isPlainObject from 'lodash/isPlainObject';
import isArray from 'lodash/isArray';
import isFunction from 'lodash/isFunction';
import { makeRequest } from '@/common/util/request';
import { getJSExpressionPrototype } from '@/common/manager/common-style';
import { getDateTypeSetterSnippet } from '@/common/manager/setter-snippet';
import {
  getBizExtendPrototype,
  handleBizExtendComponentProps,
} from '@/common/manager/plugin';

export function requestDate(dateRequest, getRequestParams) {
  const _params = getRequestParams?.();
  if (isPlainObject(dateRequest)) {
    return makeRequest({
      buttonConfig: {
        options: {
          requestConfig: dateRequest,
        },
      },
      ..._params,
      needSuccessToast: false,
    }).then((res) => {
      const { success, data } = res || {};
      if (success && isPlainObject(data)) {
        const { disabledDate, enabledDate } = data;
        if (Array.isArray(enabledDate)) {
          const list = [];
          enabledDate.forEach((item) => {
            const day = dayjs(item);
            if (day) {
              list.push(day.startOf('d').valueOf());
            }
          });
          return {
            key: 'enabledDate',
            list,
          };
        } else if (Array.isArray(disabledDate) && disabledDate.length > 0) {
          const list = [];
          disabledDate.forEach((item) => {
            const day = dayjs(item);
            if (day) {
              list.push(day.startOf('d').valueOf());
            }
          });
          return {
            key: 'disabledDate',
            list,
          };
        }
      }
    });
  }
}

const presetMap = {
  nowTime: {
    key: '此刻',
    value: () => dayjs(),
  },
  nowTimeRanger: {
    key: '此刻',
    value: [dayjs(), dayjs()],
  },
  nowMonthRanger: {
    key: '本月',
    value: [dayjs().startOf('month'), dayjs().endOf('month')],
  },
};
export function handlePreset(presetConfig, getRequestParams) {
  if (isArray(presetConfig)) {
    return presetConfig.reduce((ret, nextPresetConfig: string) => {
      const matchPreset = presetMap[nextPresetConfig];
      if (matchPreset) {
        return {
          ...ret,
          [matchPreset?.key]: matchPreset?.value,
        };
      }
      return ret;
    }, {});
  } else if (isFunction(presetConfig)) {
    const _params = getRequestParams?.();
    let formValues = {};
    let _state = {};
    if (_params) {
      const { recordDataSource, state } = _params;
      if (isPlainObject(recordDataSource)) {
        formValues = recordDataSource;
      }
      if (isPlainObject(state)) {
        _state = state;
      }
    }
    return presetConfig(dayjs, formValues, _state);
  }
}

export function handleDisabledDate(
  disabled,
  disabledDateList,
  enabledDateList,
  getRequestParams,
  disabledType,
) {
  if (disabled) {
    if (typeof disabled === 'string') {
      switch (disabled) {
        case 'beforeToday':
          return (date, mode) => {
            const currentDate = dayjs();
            switch (mode) {
              case 'date':
                return date.valueOf() < currentDate.startOf('d').valueOf();
              case 'year':
                return date.year() < currentDate.year();
              case 'month':
                return (
                  date.year() * 100 + date.month() <
                  currentDate.year() * 100 + currentDate.month()
                );
            }
          };
        case 'afterToday':
          return (date, mode) => {
            const currentDate = dayjs();
            switch (mode) {
              case 'date':
                return date.valueOf() > currentDate.valueOf();
              case 'year':
                return date.year() > currentDate.year();
              case 'month':
                return (
                  date.year() * 100 + date.month() >
                  currentDate.year() * 100 + currentDate.month()
                );
            }
          };
      }
    } else if (isPlainObject(disabled)) {
      if (disabledType === 'enabledDate' && Array.isArray(enabledDateList)) {
        return (date, mode) => {
          switch (mode) {
            case 'date':
              return !enabledDateList.includes(date.startOf('d').valueOf());
          }
        };
      } else if (
        disabledType === 'disabledDate' &&
        disabledDateList?.length > 0
      ) {
        return (date, mode) => {
          switch (mode) {
            case 'date':
              return disabledDateList.includes(date.startOf('d').valueOf());
          }
        };
      }
    } else if (typeof disabled === 'function') {
      const _params = getRequestParams?.();
      let formValues = {};
      let _state = {};
      if (_params) {
        const { recordDataSource, state } = _params;
        if (isPlainObject(recordDataSource)) {
          formValues = recordDataSource;
        }
        if (isPlainObject(state)) {
          _state = state;
        }
      }
      return (date, mode) => {
        try {
          return disabled.call(this, date, mode, formValues, _state);
        } catch (e) {
          console.log(e, '执行disableDate失败');
        }
      };
    }
  }
}
function handleDisabledTime(disabled) {
  const currentDate = dayjs();
  const currentHour = currentDate.hour();
  if (typeof disabled === 'string' && disabled) {
    switch (disabled) {
      case 'beforeToday':
        return {
          disabledHours: (index) => {
            return index < currentHour;
          },
        };
      case 'afterToday':
        return {
          disabledHours: (index) => {
            return index > currentHour;
          },
        };
    }
  }
}

export function createDisabledDateSetter() {
  return {
    componentName: 'MixedSetter',
    props: {
      setters: [
        {
          title: '选择禁用日期',
          componentName: 'SelectSetter',
          props: {
            options: [
              {
                label: '禁用今天以前',
                value: 'beforeToday',
              },
              {
                label: '禁用今天以后',
                value: 'afterToday',
              },
            ],
          },
        },
        {
          title: '配置请求获取禁用日期',
          componentName: 'ServiceChoiceSetter',
          props: {
            buttonText: '选择请求API',
            params: {
              env: 'pre',
              pageSize: 999,
              // serviceType: 'HSF',
            },
            paramSetter: {
              componentName: 'MixedSetter',
              props: {
                setters: [
                  {
                    componentName: 'ParamSelectSetter',
                    props: {
                      dataKey: 'config',
                      labelKey: 'label',
                      valueKey: 'name',
                      groupName: '当前表单',
                    },
                    title: '选择参数',
                  },
                  {
                    componentName: 'StringSetter',
                    title: '字符串',
                  },
                  getJSExpressionPrototype({ type: 'formRequest' }),
                ],
              },
            },
          },
        },
        getJSExpressionPrototype({ type: 'datepicker' }),
      ],
    },
  };
}

export function DatePickerComposite(props: any): JSX.Element {
  const { type, disabledDate, getRequestParams, ...rest } = props;
  const extraProps = {};
  const [disabledType, setDisabledType] = useState();
  const [disabledDateList, setDisabledDateList] = useState();
  const [enabledDateList, setEnabledDateList] = useState();
  useEffect(() => {
    requestDate(disabledDate, getRequestParams)?.then((res) => {
      if (res) {
        const { key, list } = res;
        if (key) {
          setDisabledType(key);
        }
        if (key === 'disabledDate') {
          setDisabledDateList(list);
        } else if (key === 'enabledDate') {
          setEnabledDateList(list);
        }
      }
    });
  }, []);
  extraProps.disabledDate = handleDisabledDate(
    disabledDate,
    disabledDateList,
    enabledDateList,
    getRequestParams,
    disabledType,
  );
  switch (type) {
    case 'week':
      return <CnWeekPicker2 {...rest} {...extraProps} />;
    case 'month':
      return <CnMonthPicker2 {...rest} {...extraProps} />;
    case 'year':
      return <CnYearPicker2 {...rest} {...extraProps} />;
    default:
      return <CnDatePickerPro {...rest} {...extraProps} />;
  }
}

const DatePicker = {
  position: [
    DisplayPosition.form,
    DisplayPosition.filter,
    DisplayPosition.formDialog,
    DisplayPosition.cnArrayTable,
    DisplayPosition.cnArraySubAreaCard,
  ],
  thumbUrl:
    'https://img.alicdn.com/imgextra/i3/O1CN01wpVw5R1fGtCbNNF3X_!!6000000003980-2-tps-240-144.png',
  title: '日期选择器',
  componentName: 'DatePicker',
  component: DatePickerComposite,
  formItemBeforeHandler: (formItem, config) => {
    const { urlParams, formValue, state } = config || {};
    if (formItem) {
      const componentProps = formItem['x-component-props'];
      if (componentProps) {
        componentProps.getRequestParams = () => {
          return {
            urlParamsDataSource: urlParams,
            recordDataSource: formValue,
            state,
          };
        };
      }
      handleBizExtendComponentProps(componentProps, 'CnDatePickerPro');
      setAdvancedConfigToProps(componentProps);
    }
  },
  filterItemBeforeHandler: (filterItemProps, config) => {
    const { componentProps, urlParamsDataSource, recordDataSource, state } =
      config || {};
    if (componentProps) {
      componentProps.getRequestParams = () => {
        return {
          urlParamsDataSource,
          recordDataSource,
          state,
        };
      };
    }
  },
  formComponent: (props) => {
    const { type, disabledDate, presetConfig, getRequestParams, ...rest } =
      props;
    const { showTime } = rest || {};
    const extraProps = {};
    let Com;
    if (showTime) {
      // if(disabledDate) {
      //   extraProps.timePanelProps = {
      //     disabledDate:handleDisabledDate(disabledDate),
      //     ...handleDisabledTime(disabledDate),
      //   }
      // }
      // if(format?.includes(' HH')){
      //   extraProps.timePanelProps = {
      //     format: format.slice(format.indexOf(' HH') + 1)
      //   }
      // }
    }

    const [disabledDateList, setDisabledDateList] = useState([]);
    const [enabledDateList, setEnabledDateList] = useState([]);
    const [disabledType, setDisabledType] = useState();
    useEffect(() => {
      requestDate(disabledDate, getRequestParams)?.then((res) => {
        if (res) {
          const { key, list } = res;
          if (key) {
            setDisabledType(key);
          }
          if (key === 'disabledDate') {
            setDisabledDateList(list);
          } else if (key === 'enabledDate') {
            setEnabledDateList(list);
          }
        }
      });
    }, []);
    extraProps.disabledDate = handleDisabledDate(
      disabledDate,
      disabledDateList,
      enabledDateList,
      getRequestParams,
      disabledType,
    );
    if (presetConfig?.length > 0 || isFunction(presetConfig)) {
      extraProps.preset = handlePreset(presetConfig, getRequestParams);
    }
    switch (type) {
      case 'week':
        Com = formComponentMap.CnWeekPicker2;
        break;
      case 'month':
        Com = formComponentMap.CnMonthPicker2;
        break;
      case 'year':
        Com = formComponentMap.CnYearPicker2;
        break;
      default:
        Com = formComponentMap.CnDatePicker2;
    }
    return <Com {...rest} {...extraProps} />;
  },
  getDefaultProps: () => {
    return {
      type: 'date',
      outputFormat: '',
    };
  },
  getPrototypeList: () => {
    return [
      getDateTypeSetterSnippet(),
      {
        name: 'showTime',
        title: '显示时间',
        display: 'inline',
        setter: 'BoolSetter',
        condition(prop) {
          return (
            condition(prop, 'DatePicker', 'componentName') &&
            prop?.parent?.getPropValue?.('type') === 'date'
          );
        },
      },
      {
        name: 'outputFormat',
        title: '输出格式',
        display: 'inline',
        condition(prop) {
          return condition(prop, 'DatePicker', 'componentName');
        },
        setter: {
          componentName: 'SelectSetter',
          props: {
            options: [
              {
                label: '时间戳',
                value: '',
              },
              {
                label: 'YYYY',
                value: 'YYYY',
              },
              {
                label: 'YYYY-MM',
                value: 'YYYY-MM',
              },
              {
                label: 'YYYY-MM-DD',
                value: 'YYYY-MM-DD',
              },
              {
                label: 'YYYY-MM-DD HH',
                value: 'YYYY-MM-DD HH',
              },
              {
                label: 'YYYY-MM-DD HH:mm',
                value: 'YYYY-MM-DD HH:mm',
              },
              {
                label: 'YYYY-MM-DD HH:mm:ss',
                value: 'YYYY-MM-DD HH:mm:ss',
              },
            ],
          },
        },
      },
      {
        name: 'format',
        title: '前端显示格式',
        display: 'inline',
        condition(prop) {
          return condition(prop, 'DatePicker', 'componentName');
        },
        setter: {
          componentName: 'SelectSetter',
          props: {
            options: [
              {
                label: 'YYYY',
                value: 'YYYY',
              },
              {
                label: 'YYYY-MM',
                value: 'YYYY-MM',
              },
              {
                label: 'YYYY-MM-DD',
                value: 'YYYY-MM-DD',
              },
              {
                label: 'YYYY-MM-DD HH',
                value: 'YYYY-MM-DD HH',
              },
              {
                label: 'YYYY-MM-DD HH:mm',
                value: 'YYYY-MM-DD HH:mm',
              },
              {
                label: 'YYYY-MM-DD HH:mm:ss',
                value: 'YYYY-MM-DD HH:mm:ss',
              },
            ],
          },
        },
      },
      {
        name: 'disabledDate',
        title: '禁用日期',
        display: 'inline',
        condition(prop) {
          return condition(prop, 'DatePicker', 'componentName');
        },
        setter: createDisabledDateSetter(),
      },
      {
        name: 'presetConfig',
        title: '快捷操作',
        display: 'inline',
        setter: {
          componentName: 'MixedSetter',
          props: {
            setters: [
              {
                title: '选择快捷',
                componentName: 'CnSelectSetter',
                props: {
                  mode: 'muiltiple',
                  options: [
                    {
                      label: '此刻',
                      value: 'nowTime',
                    },
                  ],
                },
              },
              getJSExpressionPrototype({ type: 'datepickerPreset' }),
            ],
          },
        },
      },
      ...getBizExtendPrototype({
        componentName: 'CnDatePickerPro',
      }),
    ];
  },
};
export default DatePicker;
