import * as React from "react";
import {StyleProp, TextStyle, View} from "react-native";
import {reduxTools, utils} from '@yoronsoft/js-utils';
import {configEmitterParams, configInitValue, popupDirection, popupNames} from "./config";
import {IPopup, PopupEmitterParams, PopupInitParams, PopupNamesData, PopupSelectParams, PopupTipsParams} from "./popup";
import app, {ThemeCss} from "../app";
import Basic from '../basicPage';

const popup: IPopup = {
    names: {
        view: "view",
        select: "select",
        tip: "tip",
        err: "err"
    },
    direction: {
        left: "left",
        right: "right",
        top: "top",
        bottom: "bottom"
    },
    widthScale: {
        30: 0.3,
        40: 0.4,
        50: 0.5,
        60: 0.6,
        70: 0.7,
        80: 0.8,
        90: 0.9,
        100: 1
    },
    heightScale: {
        30: 0.3,
        40: 0.4,
        50: 0.5,
        60: 0.6,
        70: 0.7,
        80: 0.8,
        90: 0.9,
        100: 1
    },
    init: function (params?: PopupInitParams[]): void {
        params = params || [];
        const viewData = params.find(m => m.name === popupNames.view);
        const selectData = params.find(m => m.name === popupNames.select);
        const tipData = params.find(m => m.name === popupNames.tip);
        const errData = params.find(m => m.name === popupNames.err);
        const viewDefault: PopupInitParams = {name: popupNames.view, direction: popupDirection.bottom}
        const selectDefault: PopupInitParams = {name: popupNames.select, direction: popupDirection.bottom, space: 15}
        const tipDefault: PopupInitParams = {name: popupNames.tip, direction: popupDirection.top, space: 15}
        const errDefault: PopupInitParams = {name: popupNames.err, direction: popupDirection.top, space: 15};
        if (!viewData) params.push(viewDefault);
        if (!selectData) params.push(selectDefault);
        if (!tipData) params.push(tipDefault)
        else {
            if (typeof tipData.space !== "number") tipData.space = tipDefault.space;
        }
        if (!errData) params.push(errDefault)
        else {
            if (typeof errData.space !== "number") errData.space = errDefault.space;
        }
        reduxTools.create(configInitValue, params);
        reduxTools.create(configEmitterParams, {display: false});
    },
    has: function (): boolean {
        return reduxTools.get<{ display: boolean }>(configEmitterParams).display
    },
    show: function (name: PopupNamesData, value?: any): void {
        name = name || popupNames.view;
        const data = _getInitParamsByName(name);
        const emitterData: PopupEmitterParams = {
            display: true, direction: data.direction,
            value, space: data.space,
        }
        app.emitter.set(configEmitterParams, emitterData);
    },
    hide: function (): void {
        const data: PopupEmitterParams = reduxTools.get(configEmitterParams);
        data.display = false;
        app.emitter.set(configEmitterParams, data);
    },
    view: function (value: React.ReactNode): void {
        this.show(popupNames.view, value ?? <View/>);
    },
    select: function (list: any[], params?: PopupSelectParams): void {
        list = list || [];
        params = params || {};
        if (typeof params.hasCancel !== "boolean") params.hasCancel = true;
        if (!utils.isInteger(params.maxSize) || params.maxSize < 1) params.maxSize = 6;
        const css = app.theme.get<ThemeCss>();
        const btnCancel = app.language.getPopup('btn_cancel') ?? '取消';
        const name = popupNames.select;
        const data = _getInitParamsByName(name);
        const width = css.width - ((data.space ?? 0) * 2);
        const innerStyle: StyleProp<TextStyle> = {
            borderWidth: 0.5, borderRadius: 15,
            borderColor: css.app.line, overflow: 'hidden',
            backgroundColor: '#fff',
        };
        // const listBorder = {borderTopWidth: 0.5, borderTopColor: css.app.line};
        //  标题
        const titleView = params.title ?
            <Basic.Text text={params.title} size={params.titleSize ?? 15} lineHeight={50}
                        color={params.titleColor ?? '#666'} weight={'bold'} textAlign={'center'}
                        style={{borderBottomWidth: 0.5, borderBottomColor: css.app.line}}/> : <Basic.View height={10}/>;

        //  描述
        const descView = params.desc ?
            <View style={{padding: 15}}>
                <Basic.Text text={params.desc} size={params.titleSize ?? 12} lineHeight={22} p={10}
                            color={params.descColor ?? '#808080'} textAlign={'left'}
                            style={{
                                backgroundColor: '#f5f5f6',
                                borderWidth: 0.5,
                                borderRadius: 15,
                                borderColor: '#f5f5f6'
                            }}/>
            </View>
            : undefined;
        //  取消按钮
        const cancelView = params.hasCancel ?
            <Basic.View mt={15} mb={20}>
                <Basic.Text text={btnCancel} width={width} height={50} lineHeight={50} textAlign={'center'}
                            weight={'bold'} color={css.popup.cancelColor ?? css.font.white}
                            style={[innerStyle, {backgroundColor: css.app.main, borderColor: css.app.main}]}
                            onPress={() => this.hide()}/>
            </Basic.View> : <Basic.View height={20}/>;
        //  最大高度
        const height = list.length > params.maxSize ? 300 : list.length * 50;
        const valueView = <View>
            <View style={[innerStyle, {width: width}]}>
                {titleView}
                {descView}
                <Basic.View height={height}>
                    <Basic.Slide hasBarVertical={false} ph={15}>
                        {list.map((item, key) => {
                            const hasSelect = key === params.selectKey;
                            const selectStyle = hasSelect ? [innerStyle, {
                                backgroundColor: '#f5f5f6',
                                borderColor: css.app.main
                            }] : undefined;
                            return <Basic.Text key={key} text={item[params.textName] ?? item.text} lineHeight={46}
                                               style={selectStyle} textAlign={'center'}
                                               color={hasSelect ? css.app.main : '#666'}
                                               weight={hasSelect ? 'bold' : undefined}
                                               size={hasSelect ? undefined : 13}
                                               onPress={() => {
                                                   this.hide();
                                                   if (typeof params.callback === "function") params.callback(key);
                                               }}
                            />
                        })}
                    </Basic.Slide>
                </Basic.View>
            </View>
            {cancelView}
        </View>
        this.show(name, valueView);
    },
    tip: function (value: React.ReactNode, params?: PopupTipsParams): void {
        params = params || {};
        const css = app.theme.get<ThemeCss>();
        const name = popupNames.tip;
        const data = _getInitParamsByName(name);
        const valueView = typeof value === "string" ?
            <Basic.View height={css.header.height} ph={10} style={[css.rowAroundCenter, {flex: 1, overflow: 'hidden'}]}>
                <Basic.Text text={value.toString()} lineHeight={24} size={13} textAlign={'center'}
                            color={params.color ?? '#666'}/>
            </Basic.View> : value;
        const style: StyleProp<TextStyle> = {
            minWidth: css.width / 2,
            maxWidth: css.width * 0.7,
            flex: 1, borderWidth: 0.5, borderRadius: 15,
            borderColor: params.lineColor ?? params.bg ?? css.app.line,
            backgroundColor: params.bg ?? css.popup.bg ?? '#fff',
            marginTop: (css.app.barHeight + css.header.height), overflow: 'hidden'
        }
        if (typeof data.space !== "number" || data.space === 0) {
            style.borderRadius = 0;
            style.borderBottomStartRadius = style.borderBottomEndRadius = style.borderBottomRightRadius = style.borderBottomLeftRadius = 15;
        }
        const timer = setTimeout(() => {
            clearTimeout(timer);
            this.hide();
        }, params.timer ?? 1500)
        const view = <View style={css.colAroundCenter}>
            <View style={style}>{valueView}</View>
        </View>
        this.show(name, view);
    },
    err: function (value: React.ReactNode): void {
        this.tip(value, {color: '#c22a1f'});
    }
}
/**
 * 获取初始化配置参数
 * @param name
 */
const _getInitParamsByName = (name: PopupNamesData) => {
    const data: PopupInitParams[] = reduxTools.get(configInitValue);
    return data.find(m => m.name === name);
}

export default popup
export type {
    PopupEmitterParams, PopupInitParams, PopupNamesData, PopupSelectParams, PopupTipsParams
}
