import React from 'react'
import PYAlert from '../../Common/alert/PYAlert'
import {Image, StyleSheet, Text, TouchableOpacity, View} from 'react-native'
import {Picker} from '@react-native-picker/picker'
import LunarSolarTransform from '../../Common/Solar&Lunar/LunarSolarTransform'
import {leap_month_for_year} from '../../Common/Solar&Lunar/Define'
import {isFunction, isNumber} from '../../Common/tool/TypeTool'
import LunarSolarHelper from '../../Common/Solar&Lunar/LunarSolarHelper'
import Lunar from '../../Common/Solar&Lunar/Lunar'
import Solar from '../../Common/Solar&Lunar/Solar'

type PropsType = {
    onSelect: (year: number, month: number, day: number, isLunar: boolean, isSecondLeapMonth: boolean) => void
}

type StateType = {
    // 年份下标
    yearIdx: number
    // 月份下标
    monthIdx: number
    // 日期下标
    dayIdx: number
    // 是否为农历
    isLunar: boolean
}

export default class BirthdaySelectDateAlert extends React.Component<PropsType, StateType> {
    state: StateType
    alertRef: PYAlert | null = null

    constructor(props: PropsType) {
        super(props)
        this.state = {
            yearIdx: 1970,
            monthIdx: 0,
            dayIdx: 0,
            isLunar: false,
        }
    }

    render() {
        return (
            <PYAlert
                ref={e => (this.alertRef = e)}
                closeOnHardwareBackPress={false}
                closeOnTouchOutside={false}
                customView={this._renderCustomView()}
            />
        )
    }

    _renderCustomView = () => {
        return (
            <View style={styles.container}>
                {this._renderTitle()}
                {this._renderSwitchBtn()}
                {this._renderPickerView()}
                {this._renderCancelBtn()}
                {this._renderSureBtn()}
            </View>
        )
    }

    _renderTitle = () => {
        const title = this.state.isLunar ? '农历' : '公历'
        return <Text style={styles.title}>{title}</Text>
    }

    _renderSwitchBtn = () => {
        return (
            <TouchableOpacity style={styles.switchBtn} onPress={this._onPressSwitchBtn.bind(this)}>
                <Text style={styles.switchBtnTitle}>{'切换'}</Text>
                <Image style={styles.switchBtnImg} source={require('../../Common/img/switch.png')} />
            </TouchableOpacity>
        )
    }

    _onPressSwitchBtn = () => {
        const isLunar = this.state.isLunar
        const dict = this._getDict(isLunar)
        const year = dict.year
        const month = dict.month
        const day = dict.day
        const isSecondLeapMonth = dict.isSecondLeapMonth
        if (isLunar) {
            const lunar = new Lunar(year, month, day, isSecondLeapMonth)
            const solar = LunarSolarTransform.lunarToSolar(lunar)
            const idxDict = this._getIdxDict(solar.year, solar.month, solar.day, false, false)
            this.setState({
                yearIdx: idxDict.yearIdx,
                monthIdx: idxDict.monthIdx,
                dayIdx: idxDict.dayIdx,
                isLunar: false,
            })
        } else {
            const solar = new Solar(year, month, day)
            const lunar = LunarSolarTransform.solarToLunar(solar)
            const idxDict = this._getIdxDict(lunar.year, lunar.month, lunar.day, true, lunar.isSecondLeapMonth)
            this.setState({
                yearIdx: idxDict.yearIdx,
                monthIdx: idxDict.monthIdx,
                dayIdx: idxDict.dayIdx,
                isLunar: true,
            })
        }
    }

    _renderPickerView = () => {
        const isLunar = this.state.isLunar
        const dict = this._getDict(isLunar)
        const years = this._getYearNames()
        const yearViews = []
        for (let i = 0; i < years.length; i++) {
            const year = years[i]
            const view = this._renderItem(year, i)
            yearViews.push(view)
        }
        const months = this._getMonthNames(dict.year)
        const monthViews = []
        for (let i = 0; i < months.length; i++) {
            const month = months[i]
            const view = this._renderItem(month, i)
            monthViews.push(view)
        }
        const days = this._getDayNames(dict.year, dict.month)
        const dayViews = []
        for (let i = 0; i < days.length; i++) {
            const day = days[i]
            const view = this._renderItem(day, i)
            dayViews.push(view)
        }
        const numberOfLines = this.state.isLunar ? 2 : 1
        const idxDict = this._getIdxDict(dict.year, dict.month, dict.day, isLunar, dict.isSecondLeapMonth)
        return (
            <View style={styles.pickerBg}>
                <Picker<number>
                    style={styles.pickerYear}
                    mode={'dialog'}
                    selectedValue={idxDict.yearIdx}
                    onValueChange={this._onYearChanged.bind(this)}
                    itemStyle={styles.item}
                    numberOfLines={numberOfLines}>
                    {yearViews}
                </Picker>
                <Picker<number>
                    style={styles.pickerMonth}
                    mode={'dialog'}
                    selectedValue={idxDict.monthIdx}
                    onValueChange={this._onMonthChanged.bind(this)}
                    itemStyle={styles.item}
                    numberOfLines={numberOfLines}>
                    {monthViews}
                </Picker>
                <Picker<number>
                    style={styles.pickerDay}
                    mode={'dialog'}
                    selectedValue={idxDict.dayIdx}
                    onValueChange={this._onDayChanged.bind(this)}
                    itemStyle={styles.item}
                    numberOfLines={numberOfLines}>
                    {dayViews}
                </Picker>
            </View>
        )
    }

    _onYearChanged = (itemValue: number, itemIndex: number) => {
        this.setState({
            yearIdx: itemIndex,
        })
    }

    _onMonthChanged = (itemValue: number, itemIndex: number) => {
        this.setState({
            monthIdx: itemIndex,
        })
    }

    _onDayChanged = (itemValue: number, itemIndex: number) => {
        this.setState({
            dayIdx: itemIndex,
        })
    }

    _renderItem = (item: string, i: number) => {
        return <Picker.Item style={styles.item} key={i} label={item} value={i} />
    }

    _renderCancelBtn = () => {
        return (
            <TouchableOpacity style={styles.cancelBtn} onPress={this._onPressCancelBtn.bind(this)}>
                <Text style={styles.cancelBtnTitle}>{'取消'}</Text>
            </TouchableOpacity>
        )
    }

    _onPressCancelBtn = () => {
        this.alertRef?.hide()
    }

    _renderSureBtn = () => {
        return (
            <TouchableOpacity style={styles.sureBtn} onPress={this._onPressSureBtn.bind(this)}>
                <Text style={styles.sureBtnTitle}>{'确定'}</Text>
            </TouchableOpacity>
        )
    }

    _onPressSureBtn = () => {
        this.alertRef?.hide()
        const isLunar = this.state.isLunar
        const dict = this._getDict(isLunar)
        const year = dict.year
        const month = dict.month
        const day = dict.day
        const isSecondLeapMonth = dict.isSecondLeapMonth
        isFunction(this.props.onSelect) && this.props.onSelect(year, month, day, isLunar, isSecondLeapMonth)
    }

    _getDict = (isLunar: boolean) => {
        const year = this.state.yearIdx + 1900
        let month = this.state.monthIdx + 1
        let isSecondLeapMonth = false
        const leapMonth = leap_month_for_year[year]
        if (isLunar && isNumber(leapMonth)) {
            if (this.state.monthIdx < leapMonth) {
                month = this.state.monthIdx + 1
            } else if (this.state.monthIdx === leapMonth) {
                month = this.state.monthIdx
                isSecondLeapMonth = true
            } else {
                month = this.state.monthIdx
            }
        }
        const day = this.state.dayIdx + 1
        return {year, month, day, isSecondLeapMonth}
    }

    _getIdxDict = (year: number, month: number, day: number, isLunar: boolean, isSecondLeapMonth: boolean) => {
        const yearIdx = year - 1900
        let monthIdx = month - 1
        const leapMonth = leap_month_for_year[year]
        if (isLunar && isNumber(leapMonth)) {
            if (month < leapMonth) {
                monthIdx = month - 1
            } else if (month === leapMonth) {
                monthIdx = isSecondLeapMonth ? month : month - 1
            } else {
                monthIdx = month
            }
        }
        const dayIdx = day - 1
        return {yearIdx, monthIdx, dayIdx}
    }

    _getYearNames = (): Array<string> => {
        const yearNames: Array<string> = []
        for (let i = 1900; i < 2100; i++) {
            if (this.state.isLunar) {
                const name = LunarSolarHelper.getChineseYearName(i) + '\n' + '(' + i + ')'
                yearNames.push(name)
            } else {
                const name = i + '年'
                yearNames.push(name)
            }
        }
        return yearNames
    }

    _getMonthNames = (year: number): Array<string> => {
        const leapMonth = leap_month_for_year[year]
        const monthNames: Array<string> = []
        for (let i = 1; i <= 12; i++) {
            if (this.state.isLunar) {
                const name = LunarSolarHelper.getChineseMonthName(i, false)
                monthNames.push(name)
                if (i === leapMonth) {
                    const leapName = LunarSolarHelper.getChineseMonthName(i, true)
                    monthNames.push(leapName)
                }
            } else {
                const name = i + '月'
                monthNames.push(name)
            }
        }
        return monthNames
    }

    _getDayNames = (year: number, month: number): Array<string> => {
        const dayNames: Array<string> = []
        const days = LunarSolarTransform.getDaysCountForLunarYear(year, month)
        for (let i = 1; i <= days; i++) {
            if (this.state.isLunar) {
                const name = LunarSolarHelper.getChineseDayName(i)
                dayNames.push(name)
            } else {
                const name = i + '日'
                dayNames.push(name)
            }
        }
        return dayNames
    }

    show = (year: number, month: number, day: number, isLunar: boolean, isSecondLeapMonth: boolean) => {
        const idxDict = this._getIdxDict(year, month, day, isLunar, isSecondLeapMonth)
        this.setState({
            yearIdx: idxDict.yearIdx,
            monthIdx: idxDict.monthIdx,
            dayIdx: idxDict.dayIdx,
            isLunar: isLunar,
        })
        this.alertRef?.show()
    }
}

const styles = StyleSheet.create({
    container: {
        width: 320,
        height: 320,
        borderRadius: 15,
        backgroundColor: 'white',
        alignItems: 'center',
    },
    title: {
        fontSize: 20,
        color: '#191919',
        marginTop: 16,
    },
    switchBtn: {
        position: 'absolute',
        width: 80,
        height: 60,
        right: 0,
        flexDirection: 'row',
        justifyContent: 'center',
        alignItems: 'center',
    },
    switchBtnTitle: {
        fontSize: 15,
        color: 'rgb(0,115,249)',
    },
    switchBtnImg: {
        width: 17,
        height: 17,
        resizeMode: 'contain',
        tintColor: 'rgb(0,115,249)',
    },
    cancelBtn: {
        position: 'absolute',
        width: 90,
        height: 40,
        left: 25,
        bottom: 15,
        justifyContent: 'center',
        alignItems: 'center',
        borderColor: '#eeeeee',
        backgroundColor: 'white',
        borderWidth: 1,
        borderRadius: 5,
    },
    cancelBtnTitle: {
        fontSize: 17,
        color: '#191919',
    },
    sureBtn: {
        position: 'absolute',
        width: 90,
        height: 40,
        right: 25,
        bottom: 15,
        justifyContent: 'center',
        alignItems: 'center',
        borderRadius: 5,
        backgroundColor: '#FFB3DB',
    },
    sureBtnTitle: {
        fontSize: 17,
        color: 'white',
    },
    pickerBg: {
        width: 320,
        marginTop: 10,
        flexDirection: 'row',
        justifyContent: 'center',
    },
    pickerYear: {
        width: 120,
    },
    pickerMonth: {
        width: 90,
    },
    pickerDay: {
        width: 100,
    },
    item: {
        fontSize: 15,
        paddingHorizontal: 1,
    },
})
