import * as React from "react";
import {StyleProp, TextInput, TextStyle, View} from "react-native";
import {reduxTools, utils} from '@yoronsoft/js-utils';
import {configEmitterParams, configInitValue, modalBtnDirection, modalBtnType, modalNames, modalType} from "./config";
import app from "../app";
import Basic from "../basicPage";

import {
    IModal, ModalBtnDirectionData,
    ModalBtnParams, ModalBtnResultParams, ModalEmitterParams,
    ModalInitParams,
    ModalNamesData,
    ModalParams,
    ModalPasswordParams
} from "./modal";
import {ThemeCss} from "../app";

const modal: IModal = {
    names: modalNames,
    type: modalType,
    btnDirection: modalBtnDirection,
    btnType: modalBtnType,
    init: function (params: ModalInitParams[]): void {
        params = params || [];
        const alertData = params.find(m => m.name === modalNames.alert);
        const confirmData = params.find(m => m.name === modalNames.confirm);
        const passwordData = params.find(m => m.name === modalNames.password);
        const otherData = params.find(m => m.name === modalNames.other);
        const alertDefault: ModalInitParams = {
            name: modalNames.alert,
            type: modalType.default,
            btnList: [{type: modalBtnType.sure}]
        };
        const confirmDefault: ModalInitParams = {
            name: modalNames.confirm,
            type: modalType.default,
            btnList: [{type: modalBtnType.cancel}, {type: modalBtnType.sure}]
        };
        const passwordDefault: ModalInitParams = {
            name: modalNames.password,
            type: modalType.default,
            btnList: [{type: modalBtnType.cancel}, {type: modalBtnType.sure}]
        };
        const otherDefault: ModalInitParams = {
            name: modalNames.other,
            type: modalType.default,
            btnList: [{type: modalBtnType.sure}]
        };
        if (!alertData) params.push(alertDefault);
        else {
            if (!alertData.type) alertData.type = alertDefault.type;
            if (!alertData.btnList) alertData.btnList = alertDefault.btnList;
        }
        if (!confirmData) params.push(confirmDefault);
        else {
            if (!confirmData.type) confirmData.type = confirmDefault.type;
            if (!confirmData.btnList) confirmData.btnList = confirmDefault.btnList;
        }
        if (!passwordData) params.push(passwordDefault);
        else {
            if (!passwordData.type) passwordData.type = passwordDefault.type;
            if (!passwordData.btnList) passwordData.btnList = passwordDefault.btnList;
        }
        if (!otherData) params.push(otherDefault);
        else {
            if (!otherData.type) otherData.type = otherDefault.type;
            if (!otherData.btnList) otherData.btnList = otherDefault.btnList;
        }
        reduxTools.create(configInitValue, params);
        reduxTools.create(configEmitterParams, {display: false});
    },
    has: function (): boolean {
        return reduxTools.get<{ display: boolean }>(configEmitterParams).display;
    },
    alert: function (content: React.ReactNode, params?: ModalParams): void {
        params = params || {};
        if (content) params.content = content;
        this.show(modalNames.alert, params);
    },
    confirm: function (content: React.ReactNode, params?: ModalParams): void {
        params = params || {};
        if (content) params.content = content;
        this.show(modalNames.confirm, params);
    },
    password: function (params?: ModalPasswordParams): void {
        const css = app.theme.get<ThemeCss>();
        const hasUsable = app.touchID.hasUsable();
        let passwordValue = '';
        params.content = <Basic.View>
            {
                params.hasTouchID && hasUsable ?
                    <Basic.View style={css.colAroundCenter} pv={20}>
                        <Basic.Icon name={app.iconfont.getTouchID()} size={30} color={'#808080'}/>
                    </Basic.View> :
                    <TextInput
                        style={{
                            height: 48,
                            paddingHorizontal: 15,
                            color: '#808080',
                            borderWidth: 0.5,
                            borderColor: '#e1e1e1',
                            borderRadius: 5, backgroundColor: '#fff'
                        }}
                        maxLength={20}
                        autoFocus={true}
                        allowFontScaling={false}
                        secureTextEntry={true}
                        passwordRules={'minlength:6;maxlength:20;'}
                        onChangeText={res => passwordValue = res}/>
            }
            {/*{*/}
            {/*    !params.hasTouchID && hasUsable && params.touchIDHref ?*/}
            {/*        <Basic.Text text={params.touchIDTips ?? '开启指纹'} size={12} mv={15}*/}
            {/*                    textAlign={'center'} color={'#808080'}*/}
            {/*                    onPress={() => {*/}
            {/*                        this.hide();*/}
            {/*                        nav.go(params.touchIDHref);*/}
            {/*                    }}/> : undefined*/}
            {/*}*/}
        </Basic.View>;
        const data = _getInitParamsByName(modalNames.password);
        if (!params.btn) params.btn = data.btnList;
        if (params.hasTouchID && hasUsable) {
            if (!params.title) params.title = app.language.getTouchID('title') ?? '指纹';
            params.btn = [{
                type: modalBtnType.cancel, callback: () => {
                    this.hide();
                }
            }];
            app.touchID.reacquire().then(res => {
                if (res) app.touchID.verify().then(hasSuccess => {
                    const result: ModalBtnResultParams = {
                        type: modalBtnType.sure,
                        name: modalNames.password,
                        hasCorrPassword: hasSuccess
                    };
                    this.hide();
                    if (typeof params.callback === "function") params.callback(result);
                })
            })
        } else {
            params.btn.map((item) => {
                item.callback = (res: ModalBtnResultParams) => {
                    if (item.type === modalBtnType.sure) res.hasCorrPassword = params.password === passwordValue;
                    params.callback(res);
                };
            });
        }

        this.show(modalNames.password, params);
    },
    show: function (name: ModalNamesData, params?: ModalParams): void {
        name = name ?? modalNames.other;
        params = params || {};
        //  脱钩
        const initParams = _getInitParamsByName(name);
        const data = utils.toCopyDeepJson(initParams);
        //  循环判断btn
        data.btnList.map((item, key) => {
            if (params.btn && params.btn.length > key) {
                if (params.btn[key].text) item.text = params.btn[key].text;
                if (params.btn[key].callback) item.callback = params.btn[key].callback;
            } else {
                if (typeof params.callback === "function")
                    item.callback = res => params.callback(res);
            }
        });
        if (typeof params.title === "undefined") {
            const lang = app.language.getModal(`title_${name}`);
            if (name === modalNames.alert) params.title = lang ?? '提示';
            if (name === modalNames.confirm) params.title = lang ?? '提示';
            if (name === modalNames.password) params.title = lang ?? '密码';
            if (name === modalNames.other) params.title = lang ?? '';
        }
        const emitterData: ModalEmitterParams = {
            display: true,
            type: data.type,
            space: data.space ?? 10,
            title: _getTitle(params.title),
            content: _getContent(params.content),
            btn: _getBtn(name, data.btnList, data.btnDirection),
        };
        app.emitter.set(configEmitterParams, emitterData);
    },
    hide: function (): void {
        const data: ModalEmitterParams = reduxTools.get(configEmitterParams);
        data.display = false;
        app.emitter.set(configEmitterParams, data);
    },
    isSure: function (params: ModalBtnParams): boolean {
        return params.type === modalBtnType.sure;
    },
    isCancel: function (params: ModalBtnParams): boolean {
        return params.type === modalBtnType.cancel;
    },
    isOther: function (params: ModalBtnParams): boolean {
        return params.type === modalBtnType.other;
    },

}

/**
 * 获取初始化配置参数
 * @param name
 */
const _getInitParamsByName = (name: ModalNamesData) => {
    const data: ModalInitParams[] = reduxTools.get(configInitValue);
    return data.find(m => m.name === name);
}
/**
 * 获取title
 * @param title
 */
const _getTitle = (title: string | React.ReactNode) => {
    if (typeof title === 'undefined') return <View style={{height: 15}}/>;
    if (typeof title === 'string') return <Basic.Text text={title} size={15} weight={'bold'} lineHeight={30} t={15}
                                                      color={'#666'} textAlign={'center'}/>
    return title
}
/**
 * 获取content
 * @param content
 */
const _getContent = (content: string | React.ReactNode) => {
    if (typeof content === 'undefined') return <View/>;
    if (typeof content === 'string') return <Basic.Text text={content} lineHeight={24} textAlign={'center'}
                                                        color={'#777777'}/>;
    return content
}
/**
 * 获取 btn
 * @param name          名称
 * @param list          数据列表
 * @param direction     方向
 */
const _getBtn = (name: ModalNamesData, list: ModalBtnParams[], direction: ModalBtnDirectionData) => {
    const css = app.theme.get<ThemeCss>();
    if (typeof list === 'undefined') return <View/>;
    const btnStyle: StyleProp<TextStyle> = {
        minHeight: 48,
        borderTopWidth: 0.5,
        borderColor: '#e1e1e1',
    }
    const dirStyle = direction === modalBtnDirection.col ? css.colStartCenter : css.rowAroundCenter;
    return <View style={[btnStyle, dirStyle]}>
        {
            list.map((item, key) => {
                let lang = app.language.getModal(`btn_${item.type}`) ?? '';
                if (item.text) lang = item.text;
                else if (!lang) {
                    if (item.type === modalBtnType.sure) lang = '确定';
                    else if (item.type === modalBtnType.cancel) lang = '取消';
                    else if (item.type === modalBtnType.other) lang = item.text;
                }
                return <Basic.Text key={key} text={lang} height={48} textAlign={'center'}
                                   color={'#666'} lineHeight={48} style={{flex: 1}}
                                   onPress={() => {
                                       modal.hide();
                                       const data: ModalBtnResultParams = {name, type: item.type};
                                       if (typeof item.callback === "function") item.callback(data);
                                   }}/>
            })
        }
    </View>
}

export default modal
export type {
    IModal, ModalBtnDirectionData,
    ModalBtnParams, ModalBtnResultParams, ModalEmitterParams,
    ModalInitParams,
    ModalNamesData,
    ModalParams,
    ModalPasswordParams
}
