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

function getBodyFilter(modelFilter) {
    let { name, label, operator, operatorLabel, type, value1, value2 } = modelFilter;
    let bodyFilter = {
        columnName: name,
        columnLabel: label,
        columnType: type,
        symbol: operator,
        symbolLabel: operatorLabel,
        value: value1
    };
    if(type === 'scale' && operator === 'between') {
        bodyFilter['value'] = value1 + ',' + value2;
    }else if(type === 'time') {
        let v1 = value1.dynamic ? value1.name : moment(value1).format('YYYY-MM-DD');
        let v2 = value2.dynamic ? value2.name : moment(value2).format('YYYY-MM-DD');

        if(operator === 'between') {
            bodyFilter['value'] = v1 + ',' + v2;
        }else {
            bodyFilter['value'] = v1;
        }
    }else if(type === 'categorical' && (operator === 'contain' || operator === 'notContain')) {
        bodyFilter['value'] = JSON.stringify(value1);
    }
    return bodyFilter;
}
function getModelFilter(resFilter) {
    let { columnName, columnLabel, columnType, symbol, symbolLabel, value } = resFilter;
    let modelFilter = {
        name: columnName,
        label: columnLabel,
        type: columnType,
        operator: symbol,
        operatorLabel: symbolLabel,
        value1: value
    };
    if(columnType === 'scale' && symbol === 'between') {
        modelFilter['value1'] = value.split(',')[0];
        modelFilter['value2'] = value.split(',')[1];
    }else if(columnType === 'time') {
        let value1 = value.split(',')[0];
        let value2 = value.split(',')[1];
        let v1 = moment(value1).isValid() ? moment(value1).format('YYYY-MM-DD') : value1;
        let v2 = moment(value2).isValid() ? moment(value2).format('YYYY-MM-DD') : value2;
        
        if(symbol === 'between') {
            modelFilter['value1'] = v1;
            modelFilter['value2'] = v2;
        }else {
            modelFilter['value1'] = v1;
        }
    }else if(columnType === 'categorical' && (symbol === 'contain' || symbol === 'notContain')) {
        modelFilter['value1'] = JSON.parse(value);
    }
    return modelFilter;
}

export default {
    namespace: 'dataSourcePolicy',
    state: {
        dataSourceCode: null,
        columnData: [],
        list: []
    },
    reducers: {
        list(state, action) {
            const { list } = action;
            return { ...state, list };
        },
        modify(state, action) {
            const { policy } = action;
            let { list } = state;
            for(let i = 0; i < list.length; i++) {
                if(list[i].code === policy.code) {
                    list[i] = policy;
                    break;
                }
            }
            return { ...state, list };
        }
    },
    effects: {
        *fetchList(action, { select, call, put }) {
            const body = action.dataSourceCode;
            try {
                const res = yield call(service.fetch, {
                    url: URLS.DATASOURCE_POLICY_LIST,
                    body
                });
                if(!res.err && res.data.code > 0) {
                    let list = (res.data.data && res.data.data.length > 0) ? res.data.data.sort((a, b) => new Date(a.createDate) - new Date(b.createDate)).map(d => ({
                        code: d.strategies.id,
                        enabled: d.strategies.isOpen+'' === '1',
                        name: d.strategies.name,
                        targets: d.userGroupName.map(g => ({
                            code: g.id+'',
                            isGroup: true,
                            name: g.name
                        })).concat(d.userName.map(u => ({
                            code: u.id+'',
                            isGroup: false,
                            name: u.name
                        }))),
                        filters: d.strategies.ruleStr ? JSON.parse(d.strategies.ruleStr).map(f => getModelFilter(f)) : [],
                    })) : [];
                    yield put({ type: 'list', list });
                }else {
                    message.error('请求数据源策略列表失败: ' + (res.err || res.data.msg));
                }
            }catch(e) {
                message.error('读取数据源策略列表错误: ' + e.message);
            }
        },
        *remoteAdd(action, { put, call, select }) {
            const dataSourcePolicy = yield select(state => state.present.dataSourcePolicy);
            const dataSourceDetail = yield select(state => state.present.dataSourceDetail);
            const { policy } = action;
            const body = {
                type: 'base',
                tarId: dataSourceDetail.code,
                name: policy.name,
                rule: policy.filters.map(f => getBodyFilter(f)),
                isOpen: policy.enabled ? '1' : '0',
            };
            try {
                const res = yield call(service.fetch, {
                    url: URLS.DATASOURCE_POLICY_ADD,
                    body,
                });
                if(!res.err && res.data.code > 0) {
                    let { list } = dataSourcePolicy;
                    list.push({
                        code: res.data.data,
                        ...policy
                    });
                    yield put({ type: 'list', list });
                }else {
                    message.error('添加失败: ' + (res.err || res.data.msg));
                }
            }catch(e) {
                message.error('添加失败: ' + e.message);
            }
        },
        *remoteModify(action, { put, call, select }) {
            const dataSourceDetail = yield select(state => state.present.dataSourceDetail);
            const { policy } = action;
            const body = {
                id: policy.code,
                type: 'base',
                tarId: dataSourceDetail.code,
                name: policy.name,
                rule: policy.filters.map(f => getBodyFilter(f)),
                isOpen: policy.enabled ? '1' : '0',
            };
            try {
                const res = yield call(service.fetch, {
                    url: URLS.DATASOURCE_POLICY_UPDATE,
                    body
                });
                if(!res.err && res.data.code > 0) {
                    yield put({ type: 'modify', policy });
                }else {
                    message.error('修改失败: ' + (res.err || res.data.msg));
                }
            }catch(e) {
                message.error('修改失败: ' + e.message);
            }
        },
        *remoteDelete(action, { put, call, select }) {
            const dataSourcePolicy = yield select(state => state.present.dataSourcePolicy);
            const { code } = action;
            const body = code;
            try {
                const res = yield call(service.fetch, {
                    url: URLS.DATASOURCE_POLICY_DELETE,
                    body
                });
                if(!res.err && res.data.code > 0) {
                    let { list } = dataSourcePolicy;
                    for(let i = 0; i < list.length; i++) {
                        if(list[i].code === code) {
                            list.splice(i, 1);
                            break;
                        }
                    }
                    yield put({ type: 'list', list });
                }else {
                    message.error('删除失败: ' + (res.err || res.data.msg));
                }
            }catch(e) {
                message.error('删除失败: ' + e.message);
            }
        },
        *remoteSetTarget(action, { put, call, select }) {
            const { policy, targets } = action;
            const body = {
                stId: policy.code+'',
                type: 'base',
                obj: targets.map(t => ({
                    obId: t.code,
                    objectType: t.isGroup ? '0' : '1'
                }))
            };
            try {
                const res = yield call(service.fetch, {
                    url: URLS.DATASOURCE_POLICY_TARGET_UPDATE,
                    body
                });
                if(!res.err && res.data.code > 0) {
                    yield put({ type: 'modify', policy: {
                        ...policy,
                        targets
                    } });
                }else {
                    message.error('设置对象失败: ' + (res.err || res.data.msg));
                }
            }catch(e) {
                message.error('设置对象失败: ' + e.message);
            }
        }
    }
};