/**
 * 全局model
 */
import { routerRedux } from 'dva/router'
import { message } from 'antd'
import * as service from '../services/index'
import URLS from '../constants/url'
import moment from 'moment'

const code = window.sessionStorage.getItem('usercode');
const account = window.localStorage.getItem('account');
const password = window.localStorage.getItem('password');
const name = window.sessionStorage.getItem('username');
const role = window.sessionStorage.getItem('userrole');
const department = window.sessionStorage.getItem('department');
const job = window.sessionStorage.getItem('job');
const expireTime = window.sessionStorage.getItem('expireTime');
const autoLogin = window.localStorage.getItem('autoLogin') ? window.localStorage.getItem('autoLogin') === 'true' : true;

const t = moment(+expireTime);
const isLogin = expireTime && t.isValid();
const authenticated = t.isValid() && t.diff(moment()) > 0;

export default {
    namespace: 'main',
    state: {
        authenticated: authenticated,
        autoLogin: autoLogin,
        isLogin: isLogin,
        expireTime,
        currentUser: {
            code,
            account,
            password,
            name,
            role,
            department,
            job,
        },
        currentPage: '', // 当前页面路由
        lastWorkshopPage: '/workshop/dataConnect', // 最后停留报表制作页面路由
        lastSettingPage: '/setting/admin', // 最后停留系统设置页面路由
    },
    reducers: {
        setCurrentPage(state, action) {
            return { ...state, currentPage: action.page === '/' ? '/home' : action.page };
        },
        setCurrentUser(state, action) {
            const { user } = action;
            return { ...state, currentUser: user };
        },
        setLastWorkshopPage(state, action) {
            return { ...state, lastWorkshopPage: action.page === '/workshop' ? '/workshop/dataConnect' : action.page };
        },
        setLastSettingPage(state, action) {
            return { ...state, lastSettingPage: action.page === '/setting' ? '/setting/admin' : action.page };
        },
        setFields(state, action) {
            const { fields } = action;
            let obj = {};
            fields.map(f => (obj[f.name] = f.value));
            let newState = Object.assign({}, state, obj);
            return Object.assign({}, newState );
        },
        reset(state, action) {
            return Object.assign({}, state, { currentPage: '', lastWorkshopPage: '/workshop/dataConnect', lastSettingPage: '/setting/admin' });
        }
    },
    effects: {
        *redirect (action, { put }) {
            const { path, reload } = action;
            yield put(routerRedux.push(path || '/'));
            if(reload) {
                window.location.reload();
            }
        },
        *goBack (action, { put }) {
            const { reload, path } = action;
            if(window.history.length === 1) {
                yield put(routerRedux.push(path || '/'));
            }else {
                yield put(routerRedux.goBack());
            }
            if(reload) {
                window.location.reload();
            }
        },
        *login(action, {put, call}) {
            const { username, password, autoLogin } = action;

            function authenticate(token, expireTime, user, autoLogin) {
                window.sessionStorage.setItem("loginTime", new Date().getTime());
                window.sessionStorage.setItem("token", token);
                window.sessionStorage.setItem("expireTime", expireTime);
            
                window.sessionStorage.setItem("usercode", user.code);
                window.localStorage.setItem("autoLogin", autoLogin ? 'true' : 'false');
                window.localStorage.setItem("account", user.account)
                window.sessionStorage.setItem("account", user.account);
                autoLogin ? window.localStorage.setItem("password", user.password) : window.localStorage.removeItem('password');
                window.sessionStorage.setItem("username", user.name);
                window.sessionStorage.setItem("phone", user.phone);
                window.sessionStorage.setItem("userrole", user.role);
                window.sessionStorage.setItem("department", user.department);
                window.sessionStorage.setItem("job", user.job);
            }

            const body = {
                userName: username,
                passWord: password
            };
            try {
                const res = yield call(service.fetch, {
                    url: URLS.LOGIN,
                    allow: true,
                    body
                });
                if(!res.err && res.data.code > 0) {
                    const resData = res.data.data;

                    const token = resData.token;
                    const expireTime = resData.times;
                    const user = resData.user;
                    const currentUser = {
                        code: user.id+'',
                        account: username,
                        phone: user.phone,
                        password: autoLogin ? password : '',
                        name: user.name,
                        role: user.role || 'normal',
                        department: user.department,
                        job: user.post,
                    };
                    yield put({ type: 'setFields', fields: [
                        { name: 'isLogin', value: true },
                        { name: 'autoLogin', value: autoLogin },
                        { name: 'authenticated', value: true },
                        { name: 'currentUser', value: currentUser }
                    ]});
                    authenticate(token, expireTime, currentUser, autoLogin);
                    return true;
                }else {
                    message.error('登录失败: ' + (res.err || res.data.msg));
                    return false;
                }
            }catch(e) {
                message.error('登录失败: ' + e.message);
                return false;
            }
        },
        *logout( action, { put, call, select }) {
            try {
                window.sessionStorage.removeItem("phone");
                window.sessionStorage.removeItem("username");
                window.sessionStorage.removeItem("userrole");
                window.sessionStorage.removeItem("usercode");
                window.sessionStorage.removeItem("department");
                window.sessionStorage.removeItem("job");
                window.sessionStorage.removeItem("loginTime");
                window.sessionStorage.removeItem("token");
                window.sessionStorage.removeItem("expireTime");

                yield put({ type: 'dataConnect/reset' });
                yield put({ type: 'dataSource/reset' });
                yield put({ type: 'chart/reset' });
                yield put({ type: 'dashboard/reset' });
                yield put({ type: 'user/reset' });
                yield put({ type: 'userGroup/reset', list: [] });
                yield put({ type: 'recent/reset' });
                yield put({ type: 'setFields', fields: [
                    { name: 'isLogin', value: false },
                    { name: 'authenticated', value: false },
                ]});
                // yield put({ type: 'recent/listRecentDashboard', recentDashboard: [] });
                yield put({ type: 'dataConnect/reset' });
                yield put({ type: 'dataSource/reset' });
                yield put({ type: 'dataSourceDetail/reset' });
                yield put({ type: 'chart/reset' });
                yield put({ type: 'chartDesigner/reset' });
                yield put({ type: 'authority/reset' });
                yield put({ type: 'dashboard/reset' });
                yield put({ type: 'dashboardDesigner/reset' });
                yield put({ type: 'home/reset' });
                yield put({ type: 'logs/reset' });
                yield put({ type: 'recent/reset' });
                yield put({ type: 'reset' });
            }catch(e) {
                message.error('注销失败: ' + e.message);
            }
        },
    },
    subscriptions: {
        setup({ dispatch, history }) {
            message.config({
                top: 60,
                duration: 2,
                maxCount: 3,
            });

            /************************ 登录超时弹出重新登录框 **************************/
            let checkExpireTime = () => {
                let expireTime = window.sessionStorage.getItem('expireTime');
                let t = moment(+expireTime).diff(moment())
                return t >= 0 ? t : 0;
            }
        
            let onExpired = () => {
                dispatch({ type: 'setFields', fields: [{ name: 'authenticated', value: false}] });
            }

            let hiddenProperty = 'hidden' in document ? 'hidden' :    
                'webkitHidden' in document ? 'webkitHidden' :    
                'mozHidden' in document ? 'mozHidden' :    
                null;
            let visibilityChangeEvent = hiddenProperty.replace(/hidden/i, 'visibilitychange');
            let timeoutKey = window.setTimeout(onExpired, checkExpireTime());
            let onVisibilityChange = () => {
                if (document[hiddenProperty]) {
                    window.clearTimeout(timeoutKey);
                }else{
                    timeoutKey = window.setTimeout(onExpired, checkExpireTime());
                }
            }
            document.addEventListener(visibilityChangeEvent, onVisibilityChange);
            
            /************************ 记录当前页面 **************************/
            return history.listen(({ pathname, query }) => {
                dispatch({ type: 'setCurrentPage', page: pathname });
                if(pathname.startsWith('/workshop')) {
                    dispatch({ type: 'setLastWorkshopPage', page: pathname });
                }else if(pathname.startsWith('/setting')) {
                    dispatch({ type: 'setLastSettingPage', page: pathname });
                }
            })
        }
    }
};