import { createApp, h, render } from "vue";
import App from "./App.vue";
import { createRouter, createWebHashHistory } from "vue-router";
import { routes } from "./router";
import less from "less";
import "./styles/ch.less";

import {
    showToast,
    showLoadingToast,
    showSuccessToast,
    showFailToast,
    showNotify,
    showDialog,
    showConfirmDialog,
    showImagePreview,
    closeToast
} from "vant";
import "vant/es/notify/style";
import "vant/es/dialog/style";
import "vant/es/toast/style";
import "vant/es/image-preview/style";
import "vant/es/calendar/style";


const app = createApp(App);

import VueQr from "vue-qr";
app.component("VueQr", VueQr);

const router = createRouter({
    history: createWebHashHistory(),
    routes,
    scrollBehavior(to, from, savedPosition) {
        if (to.meta.cache && savedPosition)
            return new Promise((resolve, reject) => {
                resolve(savedPosition);
            });
        else
            return { top: 0 };
    }
});

app.use(router);

import pinia from './stores';
import { useDatadicStore, dictCache } from './stores/datadic';
import { useUserStore } from './stores/user';
app.use(pinia);

const datadicStore = useDatadicStore()
datadicStore.init()

const userStore = useUserStore()

// 全局前置守卫
router.beforeEach((to, from, next) => {
    if (to.meta.noLogin) {
        return next();
    }
    const isLogin = userStore.isLogin;
    if (!isLogin) {
        return next({ name: 'Login', query: { redirect: to.fullPath } });
    }
    next();
});

app.config.globalProperties.$datadic = {
    get: (code) => dictCache[code] || null,
    getContent: (code) => dictCache[code] ? dictCache[code].contents : '',
}

app.config.globalProperties.$userInfo = userStore.getUserInfo;

app.config.globalProperties.$showDialog = showDialog;
app.config.globalProperties.$showConfirmDialog = showConfirmDialog;
app.config.globalProperties.$showNotify = showNotify;
app.config.globalProperties.$showToast = showToast;
app.config.globalProperties.$showLoadingToast = showLoadingToast;
app.config.globalProperties.$showSuccessToast = showSuccessToast;
app.config.globalProperties.$showFailToast = showFailToast;
app.config.globalProperties.$closeToast = closeToast;
app.config.globalProperties.$showImagePreview = showImagePreview;

app.config.globalProperties.$toMoney = (e, label, length = 2) => {
    const num = parseFloat(e).toFixed(length);
    const [a, b] = num.split('.');
    return `${a}.<${label}>${b}</${label}>`;
};

app.config.globalProperties.$autoToast = (val, msg, type = 'Fail', isThrow = true) => {
    if (val) {
        app.config.globalProperties[`$show${type}Toast`](msg);
        if (isThrow)
            throw msg;
    }
};

let skeleton;
app.config.globalProperties.$showSkeleton = () => {
    if (!skeleton)
        skeleton = h(BaseSkeleton);
    render(skeleton, document.body);
    document.body.appendChild(skeleton.el);
};
app.config.globalProperties.$closeSkeleton = () => {
    if (skeleton && document.body.contains(skeleton.el))
        document.body.removeChild(skeleton.el);
};

app.config.globalProperties.$navigate = (e) => {
    if (window.__wxjs_environment === 'miniprogram') {
        const index = e.indexOf('?');
        let query = '';
        if (index > -1)
            query = e.slice(index);
        const data = router.resolve({ path: e });
        wx.miniProgram.navigateTo({
            url: `/pages/webview/webview?url=${encodeURIComponent(`${location.origin}/${data.href}${query}`)}`,
        });
    }
    else { router.push(e); }
};
app.config.globalProperties.$ls = {
    set: (e, obj) => {
        localStorage.setItem(e, obj);
    },
    get: (e) => {
        return localStorage.getItem(e);
    },
    remove: (e) => {
        localStorage.removeItem(e);
    }
};
app.config.globalProperties.$ss = {
    set: (e, obj) => {
        sessionStorage.setItem(e, obj);
    },
    get: (e) => {
        return sessionStorage.getItem(e);
    },
    remove: (e) => {
        sessionStorage.removeItem(e);
    }
};

import ObjectHelper from './utils/ObjectHelper';
import date from './utils/date';
app.config.globalProperties.$conf = {
    apiUrl: import.meta.env.VITE_API_URL,
    ossUrl: import.meta.env.VITE_OSS_URL,
};
app.config.globalProperties.$date = date;
app.config.globalProperties.$copyText = (e) => { return ObjectHelper.Copy(e) };
app.config.globalProperties.$getRule = (e) => { return ObjectHelper.getRule(e) };
app.config.globalProperties.$groupBy = (e, key) => { return ObjectHelper.groupBy(e, key) };
app.config.globalProperties.$unsigned = (e) => { return e > 0 ? e : 0 };
app.config.globalProperties.$truncate = (e, p, a) => {
    return `${e.substring(0, p)}...${e.substring(e.length - a)}`;
};
app.config.globalProperties.$trunc = (e, p) => {
    const tp = Math.pow(10, p);
    return Math.trunc(e * tp) / tp;
};
app.config.globalProperties.$valid = (field, msg) => {
    if (!field) {
        app.config.globalProperties.$showFailToast(msg);
        return false;
    }
    return true;
};
app.config.globalProperties.$token = (e) => {
    const token = localStorage.getItem(e === 'token' ? 'member_token' : e).split('.');
    return {
        header: JSON.parse(atob(token[0])),
        payload: JSON.parse(atob(token[1])),
    }
};
app.config.globalProperties.$file = (e) => {
    if (!e) return '/img/avatar.png';
    if (typeof e !== 'string') return '/img/avatar.png';
    if (e.startsWith('http://') || e.startsWith('https://'))
        return e;
    else
        return import.meta.env.VITE_OSS_URL + e;
};
app.config.globalProperties.$openUrl = (e) => {
    window.open(e);
};
app.config.globalProperties.$refresh = () => { window.location.replace('#/refresh?key=' + app.config.globalProperties.$route.name) };
app.config.globalProperties.$verify = (permissions, module, type) => {
    return permissions.indexOf(`${module}:${type}`) > -1;
};
app.config.globalProperties.$substring = (e, begin, end) => {
    if (typeof e !== 'string') {
        return '';
    }
    return e.length > end ? e.substring(begin, end) + "..." : e;
}
app.config.globalProperties.$fileSize = (e) => {
    let level = 0;
    while (e >= 1024 && level < 4) {
        e /= 1024;
        level++;
    }
    return `${e.toFixed(2)}${['B', 'KB', 'MB', 'GB'][level]}`;
};
app.config.globalProperties.$compressFiles = (files) => {
    const fileArray = Array.isArray(files) ? files : [files];

    const promises = fileArray.map(file => {
        return new Promise((resolve, reject) => {
            if (!(file instanceof File)) {
                return reject(new Error('Invalid file type'));
            }
            imageConversion.compressAccurately(file, 400)
                .then(res => {
                    res = new File([res], file.name, { type: res.type, lastModified: Date.now() });
                    resolve(res);
                })
                .catch(err => {
                    console.error('压缩失败', err);
                    reject(err);
                });
        });
    });

    return Promise.all(promises);
};

app.config.globalProperties.$uploadFiles = (files, uploadUrl) => {
    let fd = new FormData();
    files.forEach(x => {
        fd.append('file', x.file, x.file.name);
    });
    return new Promise((resolve, reject) => {
        fetch(`${import.meta.env.VITE_API_URL}${uploadUrl}`, {
            method: 'POST',
            headers: {
                'Authorization': `Bearer ${localStorage.getItem('member_token')}`,
            },
            body: fd,
        }).then(rep => {
            rep.json().then(data => {
                if (data.errcode) {
                    reject(data);
                }
                else {
                    //上传成功
                    resolve(data);
                }
            }).catch(err => {
                reject({ message: '上传失败' });
            });
        }).catch(err => {
            reject(err);
        });
    });
}

// enum

import enums from './utils/enums';
Object.getOwnPropertyNames(enums).forEach(x => {
    app.config.globalProperties[`${x}`] = enums[x];
});

import geo from './utils/geo';
app.config.globalProperties.$geo = geo;

app.config.globalProperties.$distance = (e) => {
    if (e < 1)
        return `${e * 1000}m`;
    return `${e}km`;
};
app.config.globalProperties.$goIndex = () => {
    if (window.__wxjs_environment == 'miniprogram') {
        wx.miniProgram.reLaunch({
            url: `/pages/index/index`,
        });
    }
    else {
        location.replace('#/');
        setTimeout(() => {
            location.reload();
        }, 100);
    }
}

app.config.globalProperties.$CheckStates = [{ label: '待审核', color: 'primary' }, { label: '已通过', color: 'success' }, { label: '已拒绝', color: 'danger' }];
app.config.globalProperties.$goService = () => {
    if (app.config.globalProperties.$isWechatMini()) {
        wx.miniProgram.navigateTo({
            url: `/pages/service/service`,
        });
    } else {
        app.config.globalProperties.$navigate('/Service');
    }
};


app.config.globalProperties.$isWechat = () => { return navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger' };
app.config.globalProperties.$isWechatMini = () => { return window.__wxjs_environment == 'miniprogram' };
app.config.globalProperties.$openLocation = (lon, lat, name = '', address = '') => {
    if (wx && app.config.globalProperties.$isWechat())
        wx.openLocation({
            longitude: lon,
            latitude: lat,
            name: name,
            address: address,
            scale: 18,
        });
    else
        window.open(`http://api.map.baidu.com/marker?location=${lat},${lon}&coord_type=gcj02&title=${name}&content=${address}&output=html`);
};

// app.config.globalProperties.$isLogin = () => {
//     if (!localStorage.getItem('token'))
//         return false;
//     const token = app.config.globalProperties.$token('token');
//     return token.header.exp > Date.now() && (window.__wxjs_environment != 'miniprogram' || localStorage.getItem('miniopenid'));
// }

app.config.globalProperties.$validPhone = (e) => {
    return /^1(3|4|5|6|7|8|9)\d{9}$/.test(e);
}

app.config.globalProperties.$validIdCard = (idCard) => {
    const reg18 = /^[1-9]\d{5}(19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;

    return reg18.test(idCard);
}

app.config.globalProperties.$getShareLink = () => {
    const query = app.config.globalProperties.$route.query;
    const recommend = localStorage.getItem('cellphone');
    let link = Object.keys(query).filter(x => x != 'RecommendCode').map(x => {
        return `${x}=${query[x]}`;
    }).join('&');
    link += `&RecommendCode=${recommend}`;
    return `${location.href.split('?')[0]}?${link}`;
}

// CH
import { post, get, put, del, request, postForm } from './api/http';
import { isLogin, formatGMT } from './api/user';

app.config.globalProperties.$post = post;
app.config.globalProperties.$get = get;
app.config.globalProperties.$put = put;
app.config.globalProperties.$del = del;
app.config.globalProperties.$request = request;
app.config.globalProperties.$postForm = postForm;
app.config.globalProperties.$isLogin = isLogin;
app.config.globalProperties.$formatGMT = formatGMT;
app.config.globalProperties.$formatCellphone = (e) => {
    if (!e || e.length !== 11) return e;
    return e.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
};

// ManagerPopup 通过 window 事件触发
app.config.globalProperties.$showManagerPopup = () => { window.dispatchEvent(new Event('showManagerPopup')) }
app.config.globalProperties.$closeManagerPopup = () => { window.dispatchEvent(new Event('closeManagerPopup')) }

app.mount("#app");
