<script lang="tsx">
    import type { PropType } from 'vue'
    import { Button, Result } from 'ant-design-vue'
    import { computed, defineComponent, ref, unref } from 'vue'
    import { ExceptionEnum } from '/@/enums/exceptionEnum'
    import notDataSvg from '/@/assets/svg/no-data.svg'
    import netWorkSvg from '/@/assets/svg/net-error.svg'
    import { useRoute } from 'vue-router'
    import { useDesign } from '/@/hooks/web/useDesign'
    import { useI18n } from '/@/hooks/web/useI18n'
    import { useGo, useRedo } from '/@/hooks/web/usePage'
    import { PageEnum } from '/@/enums/pageEnum'

    interface MapValue {
        title: string
        subTitle: string
        btnText?: string
        icon?: string
        handler?: Fn
        status?: string
    }

    export default defineComponent({
        name: 'ErrorPage',
        props: {
            // 状态码
            status: {
                type: Number as PropType<number>,
                default: ExceptionEnum.PAGE_NOT_FOUND,
            },

            title: {
                type: String as PropType<string>,
                default: '',
            },

            subTitle: {
                type: String as PropType<string>,
                default: '',
            },

            full: {
                type: Boolean as PropType<boolean>,
                default: false,
            },
        },
        setup(props) {
            const statusMapRef = ref(new Map<string | number, MapValue>())

            const { query } = useRoute()
            const go = useGo()
            const redo = useRedo()
            const { t } = useI18n()
            const { prefixCls } = useDesign('app-exception-page')

            const getStatus = computed(() => {
                const { status: routeStatus } = query
                const { status } = props
                return Number(routeStatus) || status
            })

            const getMapValue = computed((): MapValue => {
                return unref(statusMapRef).get(unref(getStatus)) as MapValue
            })

            const backLoginI18n = t('sys.exception.backLogin')
            const backHomeI18n = t('sys.exception.backHome')

            unref(statusMapRef).set(ExceptionEnum.PAGE_NOT_ACCESS, {
                title: '403',
                status: `${ExceptionEnum.PAGE_NOT_ACCESS}`,
                subTitle: t('sys.exception.subTitle403'),
                btnText: props.full ? backLoginI18n : backHomeI18n,
                handler: () => (props.full ? go(PageEnum.BASE_LOGIN) : go()),
            })

            unref(statusMapRef).set(ExceptionEnum.PAGE_NOT_FOUND, {
                title: '404',
                status: `${ExceptionEnum.PAGE_NOT_FOUND}`,
                subTitle: t('sys.exception.subTitle404'),
                btnText: props.full ? backLoginI18n : backHomeI18n,
                handler: () => (props.full ? go(PageEnum.BASE_LOGIN) : go()),
            })

            unref(statusMapRef).set(ExceptionEnum.ERROR, {
                title: '500',
                status: `${ExceptionEnum.ERROR}`,
                subTitle: t('sys.exception.subTitle500'),
                btnText: backHomeI18n,
                handler: () => go(),
            })

            unref(statusMapRef).set(ExceptionEnum.PAGE_NOT_DATA, {
                title: t('sys.exception.noDataTitle'),
                subTitle: '',
                btnText: t('common.redo'),
                handler: () => redo(),
                icon: notDataSvg,
            })

            unref(statusMapRef).set(ExceptionEnum.NET_WORK_ERROR, {
                title: t('sys.exception.networkErrorTitle'),
                subTitle: t('sys.exception.networkErrorSubTitle'),
                btnText: t('common.redo'),
                handler: () => redo(),
                icon: netWorkSvg,
            })

            return () => {
                const { title, subTitle, btnText, icon, handler, status } = unref(getMapValue) || {}
                return (
                    <Result
                        class={prefixCls}
                        status={status as any}
                        title={props.title || title}
                        sub-title={props.subTitle || subTitle}
                    >
                        {{
                            extra: () =>
                                btnText && (
                                    <Button type="primary" onClick={handler}>
                                        {() => btnText}
                                    </Button>
                                ),
                            icon: () => (icon ? <img src={icon} /> : null),
                        }}
                    </Result>
                )
            }
        },
    })
</script>

<style lang="less">
    @prefix-cls: ~'@{namespace}-app-exception-page';

    .@{prefix-cls} {
        display: flex;
        align-items: center;
        flex-direction: column;

        .ant-result-icon {
            img {
                max-width: 400px;
                max-height: 300px;
            }
        }
    }
</style>
