import React from 'react'
import MultiPicker from '@gdjiami/rmc-picker/es/MultiPicker'
import Picker from '@gdjiami/rmc-picker/es/Picker'
import Modal from 'antd-mobile/es/modal'
import { Today } from '../calendar'

export interface YearPickerProps {
  value?: Date
  title?: string
  onChange?: (value: Date) => void
  disabledBefore?: Date
  disabledAfter?: Date
  children: (value: Date, onClick: () => void) => React.ReactNode
}

type YearList = number[]

interface State {
  yearList: YearList
  visible: boolean
  lastValue?: Date
}

const defaultDisabledBefore = new Date(0)
const defaultDisabledAfter = new Date(2100, 1, 1)

export default class YearPicker extends React.Component<YearPickerProps> {
  public static defaultProps = {
    title: '选择年份',
  }

  public state: State = {
    yearList: genList(
      this.props.value || Today,
      this.props.disabledBefore,
      this.props.disabledAfter,
    ),
    visible: false,
  }

  public componentDidUpdate(prevProps: YearPickerProps, prevState: State) {
    if (
      this.props.value &&
      (this.props.disabledBefore !== prevProps.disabledBefore ||
        this.props.disabledAfter !== prevProps.disabledAfter)
    ) {
      this.setState({
        yearList: genList(
          this.props.value,
          this.props.disabledBefore,
          this.props.disabledAfter,
        ),
      })
    }
  }

  public render() {
    const { children, value = Today, title } = this.props
    const { yearList, visible } = this.state
    return (
      <>
        {children(value, this.handleShow)}
        <Modal
          transparent
          maskClosable={false}
          visible={!!visible}
          wrapClassName="jm-date-picker__wrapper"
          className="jm-date-picker"
        >
          <div className="jm-date-picker__header-bar">
            <div className="jm-date-picker__action" onClick={this.handleCancel}>
              取消
            </div>
            <div className="jm-date-picker__title">{title}</div>
            <div className="jm-date-picker__action" onClick={this.handleOk}>
              确定
            </div>
          </div>
          <MultiPicker
            className="jm-date-picker__body"
            selectedValue={[value.getFullYear()]}
            onValueChange={this.handleSelectChange}
          >
            <Picker className="jm-date-picker__date">
              {yearList.map(i => (
                <Picker.Item value={i} key={i}>
                  {i}年
                </Picker.Item>
              ))}
            </Picker>
          </MultiPicker>
        </Modal>
      </>
    )
  }

  private handleSelectChange = ([year]: [number]) => {
    const value = new Date(this.props.value || 0)
    value.setFullYear(year)

    if (this.props.onChange) {
      this.props.onChange(value)
    }
  }

  private handleCancel = () => {
    this.setState({ visible: false })
    if (this.props.onChange) {
      this.props.onChange(this.state.lastValue!)
    }
  }

  private handleOk = () => {
    this.setState({ visible: false })
  }

  private handleShow = () => {
    this.setState({ visible: true, lastValue: this.props.value })
  }
}

function genList(
  date: Date,
  disabledBefore: Date = defaultDisabledBefore,
  disabledAfter: Date = defaultDisabledAfter,
) {
  const list: YearList = [date.getFullYear()]
  let prev = new Date(date)
  let next = new Date(date)
  let prevFinished: boolean = false
  let nextFinished: boolean = false

  for (let i = 1; i <= 100; i++) {
    if (!prevFinished) {
      prev = new Date(prev)
      prev.setFullYear(prev.getFullYear() - 1)
      if (disabledBefore.getFullYear() > prev.getFullYear()) {
        prevFinished = true
      } else {
        list.unshift(prev.getFullYear())
      }
    }

    if (!nextFinished) {
      next = new Date(next)
      next.setFullYear(next.getFullYear() + 1)
      if (next.getFullYear() > disabledAfter.getFullYear()) {
        nextFinished = true
      } else {
        list.push(next.getFullYear())
      }
    }
  }

  return list
}
