import React, { useContext, useState } from 'react';
import { Calendar as OldCalendar, CalendarProps, ConfigProvider } from 'antd';
import moment, { Moment } from 'moment';
import locale from 'antd/es/calendar/locale/zh_CN';
import './index.less';
import classNames from 'classnames';
import { Icon } from '../Icon';
import { Button } from '../Button';
import { Select } from '../Select';
import { translate } from '../utils/index';

type CalendarContent = {
  type: 'info' | 'warning' | 'error' | 'success';
  value: string;
};

type CalendarMessageItem = {
  cellType: 'date' | 'month' | 'both';
  contents: Array<CalendarContent>;
  time: string;
};

interface CalendarExtraProps {
  headerType?: 'default' | 'select';
  template?: 'message';
  list?: CalendarMessageItem[];
}

function Calendar({
  className,
  headerRender,
  headerType = 'default',
  fullscreen = true,
  template,
  dateCellRender,
  monthCellRender,
  list,
  ...props
}: CalendarProps<Moment> & CalendarExtraProps) {
  const { getPrefixCls } = useContext(ConfigProvider.ConfigContext);
  const prefixCls = getPrefixCls('btri-calendar');
  const [type, setType] = useState(props.mode || 'month');

  function getHeader(obj: {
    value: Moment;
    type: CalendarProps<Moment>['mode'];
    onChange: (date: Moment) => void;
    onTypeChange: (type: CalendarProps<Moment>['mode']) => void;
  }) {
    if (headerRender) return headerRender(obj);
    const iconStyle = {
      fontSize: fullscreen ? '20px' : '16px',
      color: 'var(--gray-7)',
      cursor: 'pointer',
    };
    const formatStr = 'YYYY [年] MM [月]';
    const formatStrByYear = 'YYYY [年]';
    const changeDateStr = (action: 'add' | 'subtract') => {
      const m = obj.value[action](1, type === 'month' ? 'M' : 'y');
      // TODO 修改类型
      obj.onChange(obj?.value?.clone()?.[type](m?.[type]()) as Moment);
    };
    const toCurrent = () => {
      const m1 = moment();
      obj.onChange(m1);
    };
    const selectType = (t: 'month' | 'year') => {
      setType(t);
      obj.onTypeChange(t);
    };
    const getDateStr = () => {
      return obj.value.format(type === 'month' ? formatStr : formatStrByYear);
    };

    // headerType === 'select' 的操作
    const { Option } = Select;
    const month = obj.value.month();
    const months = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
    const year = obj.value.year();
    const years: number[] = [];
    for (let i = year - 10; i < year + 10; i += 1) {
      years.push(i);
    }
    const selectValue = (t: 'month' | 'year', v: any) => {
      // TODO 修改类型
      obj.onChange(obj?.value?.clone()[t](v) as Moment);
    };
    const { locale } = useContext(ConfigProvider.ConfigContext);

    return (
      <section
        className={classNames(`${prefixCls}-header`, {
          [`${prefixCls}-header--small`]: !fullscreen,
        })}
      >
        <div className={`${prefixCls}-header-left`}>
          {headerType === 'default' ? (
            <>
              <Icon
                onClick={() => changeDateStr('subtract')}
                style={iconStyle}
                iconName="Left"
              />
              <p className={fullscreen ? `` : `${prefixCls}-header-dateStr`}>
                {getDateStr()}
              </p>
              <Icon
                onClick={() => changeDateStr('add')}
                style={iconStyle}
                iconName="Right"
              />
            </>
          ) : (
            <>
              <Select
                placeholder={translate(
                  'packages.base.src.Calendar.index.请选择年',
                  locale?.locale,
                )}
                style={{ width: fullscreen ? '120px' : '92px' }}
                onChange={(v) => selectValue('year', v)}
                allowClear={false}
                defaultValue={year}
                size={fullscreen ? 'middle' : 'small'}
              >
                {years.map((vo: number, i: number) => {
                  return (
                    <Option value={vo} key={vo + i}>
                      {vo} 年
                    </Option>
                  );
                })}
              </Select>
              {type === 'month' ? (
                <Select
                  placeholder={translate(
                    'packages.base.src.Calendar.index.请选择月份',
                    locale?.locale,
                  )}
                  size={fullscreen ? 'middle' : 'small'}
                  style={{
                    width: fullscreen ? '90px' : '68px',
                    marginLeft: '8px',
                  }}
                  onChange={(v) => selectValue('month', v)}
                  defaultValue={month}
                  allowClear={false}
                >
                  {months.map((vo: number, i: number) => {
                    return (
                      <Option value={i} key={vo + i}>
                        {vo} 月
                      </Option>
                    );
                  })}
                </Select>
              ) : null}
            </>
          )}
          {fullscreen ? (
            <Button
              onClick={toCurrent}
              className={`${prefixCls}-header-btn--${headerType}`}
              type="primary"
            >
              {type === 'month'
                ? translate(
                    'packages.base.src.DatePicker.index.今天',
                    locale?.locale,
                  )
                : translate(
                    'packages.base.src.Calendar.index.本月',
                    locale?.locale,
                  )}
            </Button>
          ) : null}
        </div>
        <div
          className={classNames(`${prefixCls}-header-right`, {
            [`${prefixCls}-header-right--small`]: !fullscreen,
          })}
        >
          <span onClick={() => selectType('month')}>月</span>
          <span onClick={() => selectType('year')}>年</span>
          <div
            className={`${prefixCls}-header-right-block`}
            style={{
              transform: `translateX(${
                type === 'year' ? (fullscreen ? '46px' : '28px') : '0'
              })`,
            }}
          >
            {type === 'month'
              ? translate('packages.base.src.Calendar.index.月', locale?.locale)
              : translate(
                  'packages.base.src.Calendar.index.年',
                  locale?.locale,
                )}
          </div>
        </div>
      </section>
    );
  }

  const getMessageTemplate = (vo: CalendarMessageItem, t: 'month' | 'date') => {
    return (date: Moment) => {
      const s = t === 'month' ? 'YYYYMM' : 'YYYYMMDD';
      let isSame = moment(vo.time).format(s) === date.format(s);

      return isSame
        ? vo.contents.map((item, index) => {
            return (
              <ul className={`${prefixCls}-template`}>
                <li
                  key={item.value + index}
                  className={classNames(
                    `${prefixCls}-template-item`,
                    `${prefixCls}-template-item--${item.type}`,
                  )}
                >
                  <div></div>
                  <p>{item.value}</p>
                </li>
              </ul>
            );
          })
        : null;
    };
  };

  const cellRender = (() => {
    if (template !== 'message') return { dateCellRender, monthCellRender };

    let dateRenders = [],
      monthRenders = [];

    for (let vo of list) {
      if (vo.cellType === 'date') {
        dateRenders.push(getMessageTemplate(vo, 'date'));
      } else if (vo.cellType === 'month') {
        monthRenders.push(getMessageTemplate(vo, 'month'));
      } else {
        dateRenders.push(getMessageTemplate(vo, 'date'));
        monthRenders.push(getMessageTemplate(vo, 'month'));
      }
    }

    const getEl = (t: 'month' | 'date') => (date: Moment) => {
      const arr = t === 'date' ? dateRenders : monthRenders;
      for (let item of arr) {
        let el = item(date);
        if (el) return el;
      }
    };

    return {
      dateCellRender: getEl('date'),
      monthCellRender: getEl('month'),
    };
  })();

  return (
    <OldCalendar
      {...props}
      headerRender={getHeader}
      locale={locale}
      fullscreen={fullscreen}
      monthCellRender={cellRender.monthCellRender}
      dateCellRender={cellRender.dateCellRender}
      className={classNames(
        `${prefixCls}-box`,
        { [`${prefixCls}-box--small`]: !fullscreen },
        className,
      )}
    ></OldCalendar>
  );
}

export { Calendar };
