import { message } from 'antd'
import * as service from '../services/index'
import URLS from '../constants/url'
import DEFAULT_COLUMN_TYPE from './defaultColumnType.json'

export default {
    namespace: 'dataSourceDetail',
    state: {
        originData: {
            dirty: false,
            code: null,
            name: '未命名',
            type: null,
            connectCode: null,
            connectName: null,
            dbType: null,
            dbName: null,
            address: null,
            port: null,
            target: null,
            targetDirty: false,
            fetched: false,
            creatorCode: null,
            creatorName: null,
            createTime: null,
            userName: null,
            password: null,
            description: '',
            group: '-1',
            notice: '',
            columns: [],
            demo: false
        },
    },
    reducers: {
        setField(state, action) {
            const { name, value } = action;
            let obj = {};
            obj[name] = value;
            let newState = Object.assign({}, state, obj);
            return Object.assign({}, newState, {dirty: true});
        },
        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, {dirty: true});
        },
        silentSetField(state, action) {
            const { name, value } = action;
            let obj = {};
            obj[name] = value;
            let newState = Object.assign({}, state, obj);
            return newState;
        },
        silentSetFields(state, action) {
            const { fields } = action;
            let obj = {};
            fields.map(f => (obj[f.name] = f.value));
            let newState = Object.assign({}, state, obj);
            return newState;
        },
        reset(state, action) {
            let newState = Object.assign({}, state, state.originData);
            return Object.assign({}, newState);
        },
        setDirty(state, action) {
            const { dirty } = action;
            let newState = Object.assign({}, state, { dirty });
            return newState;
        },
    },
    effects: {
        *importColumns(action, { select, call, put }) {
            const dataSourceDetail = yield select(state => state.dataSourceDetail);
            const sqlStr = dataSourceDetail.target;
            const oldColumns = JSON.parse(JSON.stringify(dataSourceDetail.columns));
            const { cover } = action;
            let body = {
                id: dataSourceDetail.connectCode,
                strSql: sqlStr
            };
            try{
                const res = yield call(service.fetch, {
                    url: URLS.DATASOURCE_QUERY_SQLCOLUMNS,
                    body: body,
                    timeout: 120000
                });
    
                const getColumnType = (dataType) => {
                    return DEFAULT_COLUMN_TYPE[dataType] || 'string';
                }

                // 点击查询后清除数据对象dirty状态
                yield put({ type: 'setField', name: 'targetDirty', value: false });
    
                if(res.code > 0) {
                    let colNames = [];
                    let repeatColumnName = false;
                    let columns = res.data.map((d, i) => {
                        if(colNames.findIndex(cn => cn === d.columnName) > -1) {
                            repeatColumnName = d.columnName;
                        }
                        colNames.push(d.columnName);
                        return {
                            key: d.columnName,
                            using: true,
                            name: d.columnName,
                            alias: d.columnName,
                            dataType: d.columnType,
                            columnType: getColumnType(d.columnType),
                            groupable: d.columnType === 'String',
                            filterable: true,
                        }
                    });
                    if(repeatColumnName) {
                        message.error('加载列数据失败: 存在重复列[ ' + repeatColumnName + ' ]');
                        return false;
                    }
                    if(cover) {
                        // 覆盖
                        yield put({ type: 'setField', name: 'columns', value: columns });
                    }else {
                        // 保留重复列
                        let mergeColumns = [];
                        columns.forEach(c => {
                            let tc = oldColumns.find(o => o.name === c.name );
                            if(tc) {
                                let o = {};
                                o.columnType = tc.dataType === c.dataType ? tc.columnType : getColumnType(c.dataType);
                                mergeColumns.push({ ...c, ...o, alias: tc.alias, using: tc.using, groupable: tc.groupable, filterable: tc.filterable });
                            }else {
                                mergeColumns.push(c); 
                            }
                        });
                        yield put({ type: 'setFields', fields: [
                            { name: 'columns', value: mergeColumns },
                            { name: 'notice', value: '' }
                        ] });
                    }
                }else {
                    yield put({ type: 'setFields', fields: [
                        { name: 'columns', value: [] },
                        { name: 'notice', value: res.msg }
                    ] });
                }
            }catch(e) {
                console.error(body, e)
                yield put({ type: 'setFields', fields: [
                    { name: 'columns', value: [] },
                    { name: 'notice', value: e.message + '' || e + '' }
                ] });
                message.error('加载列数据失败: ' + e.message);
            }finally {
                yield put({ type: 'setFields', fields: [
                    { name: 'fetched', value: true }
                ] });
            }
        },
    },
    subscriptions: {
        setup({ dispatch, history }) {
            dispatch({ type: 'reset' });
        }
    }
};