import isEmpty from 'lodash/isEmpty';
import {
    message
} from 'antd';
import {
    indexOf
} from 'lodash';
import {WeaTools} from 'ecCom'
import React,{PureComponent} from 'react'
import { i18n } from '../public/i18n.js'

const dbKeys = ["PERCENT", "PLAN", "PRECISION", "PRIMARY", "PRINT", "PROC", "PROCEDURE", "PUBLIC", "RAISERROR",
    "READ", "READTEXT", "RECONFIGURE", "REFERENCES", "REPLICATION", "RESTORE", "RESTRICT", "RETURN", "REVOKE",
    "RIGHT", "ROLLBACK", "ROWCOUNT", "ROWGUIDCOL", "RULE", "SAVE", "SCHEMA", "SELECT", "SESSION_USER", "SET",
    "SETUSER", "SHUTDOWN", "SOME", "STATISTICS", "SYSTEM_USER", "TABLE", "TEXTSIZE", "THEN", "TO", "TOP", "TRAN",
    "TRANSACTION", "TRIGGER", "TRUNCATE", "TSEQUAL", "UNION", "UNIQUE", "UPDATE", "UPDATETEXT", "USE", "USER",
    "VALUES", "VARYING", "VIEW", "WAITFOR", "WHEN", "WHERE", "WHILE", "WITH", "WRITETEXT", "EXCEPT", "EXEC", "EXECUTE",
    "EXISTS", "EXIT", "FETCH", "FILE", "FILLFACTOR", "FOR", "FOREIGN", "FREETEXT", "FREETEXTTABLE", "FROM", "FULL",
    "FUNCTION", "GOTO", "GRANT", "GROUP", "HAVING", "HOLDLOCK", "IDENTITY", "IDENTITY_INSERT", "IDENTITYCOL", "IF", "IN",
    "INDEX", "INNER", "INSERT", "INTERSECT", "INTO", "IS", "JOIN", "KEY", "KILL", "LEFT", "LIKE", "LINENO", "LOAD", "NATIONAL",
    "NOCHECK", "NONCLUSTERED", "NOT", "NULL", "NULLIF", "OF", "OFF", "OFFSETS", "ON", "OPEN", "OPENDATASOURCE", "OPENQUERY",
    "OPENROWSET", "OPENXML", "OPTION", "OR", "ORDER", "OUTER", "OVER", "ADD", "ALL", "ALTER", "AND", "ANY", "AS", "ASC", "AUTHORIZATION",
    "BACKUP", "BEGIN", "BETWEEN", "BREAK", "BROWSE", "BULK", "BY", "CASCADE", "CASE", "CHECK", "CHECKPOINT", "CLOSE", "CLUSTERED",
    "COALESCE", "COLLATE", "COLUMN", "COMMIT", "COMPUTE", "CONSTRAINT", "CONTAINS", "CONTAINSTABLE", "CONTINUE", "CONVERT", "CREATE",
    "CROSS", "CURRENT", "CURRENT_DATE", "CURRENT_TIME", "CURRENT_TIMESTAMP", "CURRENT_USER", "CURSOR", "DATABASE", "DBCC", "DEALLOCATE",
    "DECLARE", "DEFAULT", "DELETE", "DENY", "DESC", "DISK", "DISTINCT", "DISTRIBUTED", "DOUBLE", "DROP", "DUMMY", "DUMP", "ELSE", "END", "ERRLVL",
    "ESCAPE", "ACCESS", "ADD", "ALL", "ALTER", "AND", "ANY", "AS", "ASC", "AUDIT", "BETWEEN", "BY", "CHAR", "CHECK", "CLUSTER", "COLUMN", "COMMENT",
    "COMPRESS", "CONNECT", "CREATE", "CURRENT", "DATE", "DECIMAL", "DEFAULT", "DELETE", "DESC", "DISTINCT", "DROP", "ELSE", "EXCLUSIVE", "EXISTS",
    "FILE", "FLOAT", "FOR", "FROM", "GRANT", "GROUP", "HAVING", "IDENTIFIED", "IMMEDIATE", "IN", "INCREMENT", "INDEX", "INITIAL", "INSERT", "INTEGER",
    "INTERSECT", "INTO", "IS", "LEVEL", "LIKE", "LOCK", "LONG", "MAXEXTENTS", "MINUS", "MLSLABEL", "MODE", "MODIFY", "NOAUDIT", "NOCOMPRESS", "NOT",
    "NOWAIT", "NULL", "NUMBER", "OF", "OFFLINE", "ON", "ONLINE", "OPTION", "OR", "ORDER", "PCTFREE", "PRIOR", "PRIVILEGES", "PUBLIC", "RAW", "RENAME",
    "RESOURCE", "REVOKE", "ROW", "ROWID", "ROWNUM", "ROWS", "SELECT", "SESSION", "SET", "SHARE", "SIZE", "SMALLINT", "START", "SUCCESSFUL", "SYNONYM",
    "SYSDATE", "TABLE", "THEN", "TO", "TRIGGER", "UID", "UNION", "UNIQUE", "UPDATE", "USER", "VALIDATE", "VALUES", "VARCHAR", "VARCHAR2", "VIEW", "WHENEVER",
    "WHERE", "WITH"
]

export const validate = (conditions, params = {}) => {
    if (!isEmpty(conditions)) {
        for (let i = 0, leg = conditions.length; i < leg; i++) {
            let cd = conditions[i];
            for (let j = 0, length = cd.items.length; j < length; j++) {
                let c = cd.items[j];
                if (c) {
                    let domkey = c.domkey[0];
                    let viewAttr = c.viewAttr;
                    if (c.conditionType == 'BROWSER') viewAttr = c.browserConditionParam.viewAttr;
                    if (viewAttr == '3' && !params[domkey]) {
                        if (domkey == 'managerid' || domkey == 'belongto') { //直接上级 主账号不用校验
                        } else {
                            //message.warning(domkey+'必要信息不完整！');
                            message.warning('必要信息不完整！');
                            return false;
                        }
                    }
                }
            }
        }
    }
    return true;
}

export const getFormParamValue = (conditions = {}, fieldname) => {
    let fieldvalue = '';
    if (!isEmpty(conditions)) {
        for (let i = 0, leg = conditions.length; i < leg; i++) {
            let cd = conditions[i];
            for (let j = 0, length = cd.items.length; j < length; j++) {
                let c = cd.items[j];
                if (c) {
                    let domkey = c.domkey[0];
                    if (domkey == fieldname) {
                        fieldvalue = c.value;
                    }
                }
            }
        }
    }
    return fieldvalue;
}

export const transParams = (formParams) => {
    let params = {};
    for (let key in formParams) {
        if (formParams[key] === !!formParams[key])
            params[key] = !!formParams[key] ? '1' : '0';
        else
            params[key] = formParams[key];
    }
    return params;
}

export const findTabCount = (str) => {
    const bIndex = str.lastIndexOf('(');
    const eIndex = str.lastIndexOf(')');
    let title = '',
        count = '';
    try {
        title = str.substring(0, bIndex);
        count = str.substring(bIndex + 1, eIndex);
    } catch (err) {

    }
    return {
        title,
        count
    }
}

export const calFormHeight = (groupLength, children) => {
    let childrenLength = 0;
    children.map(c => {
        if (c.colSpan != null) {
            childrenLength += c.colSpan == 2 ? 1 : 2;
        } else
            childrenLength += 1;
    })
    let height = (childrenLength / 2 + childrenLength % 2) * 52 + 10;
    if (groupLength > 1)
        height += groupLength * 45;
    if (height > 300)
        return 300;
    return height;
}

export const validDBKeys = (value) => {
    if (indexOf(dbKeys, value.toUpperCase()) >= 0) {
        message.error("不能使用数据库保留字作为字段名!");
        return {
            isValid: false,
            value: ''
        };
    }
    return {
        isValid: true,
        value
    };
}

export const validNumber = (value) => {
    if (isNaN(parseInt(value)))
        return 0;
    return value;
}

export const getColumIndex = (num) => {
    const n = 65;
    const loopIndex = num / 26;
    if (loopIndex < 1)
        return String.fromCharCode(n + num % 26);
    else
        return `${String.fromCharCode(n + parseInt(loopIndex - 1))}${String.fromCharCode(n + num % 26)}`
}

export const calColumnIndex = (val) => {
    const arr = Array.from(val);
    let num = 0;
    if (arr.length === 1)
        num = arr[0].charCodeAt() - 64;
    else {
        arr.map((c, i) => {
            if (i === 0)
                num += (c.charCodeAt() - 64) * 26;
            else
                num += c.charCodeAt() - 64;
        })
    }

    return num;
}

export const convertCalendarDate = (date) => {
    const y = date.getYear();
    let d = date.getDayOfMonth();
    if (d < 10)
        d = '0' + d;
    let m = date.getMonth() + 1;
    if (m < 10)
        m = '0' + m;
    return `${y}-${m}-${d}`;
}

export class AttachToNumberField extends PureComponent{
   constructor(props) {
        super(props);
        
        this.state = {
            canRe:false,
            canCheck:false,
            canNew:false,
        }
        this.typeMap = {
            subcompanycode: 'SUBCOMPANY',
            departmentcode: 'DEPARTMENT',
            jobtitlecode: 'JOBTITLES',
            workcode: 'USER'
        }

    }
    componentWillMount() {
        const {field:{domkey:[targetKey]}} = this.props;
        this.targetKey = targetKey;
        this.type = this.typeMap[this.targetKey];
    }
    componentDidMount() {
        this.init(this.props.isEdit)
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.form != this.props.form) {
            this.init(nextProps.isEdit)
        }
    }

    init  =(isEdit) => {
        WeaTools.callApi('/api/hrm/codeSetting/getHasSelect','GET',{}).then(res => {
            if (res) {
                //后台设置页面开关关闭，接口不会返回对应的权限，所以这里做下兼容
                const target = res[this.type] || {hasSelect:false,hasRight:false};
                const {hasSelect,hasRight} = target;
                this.setState({
                    canRe:hasSelect && isEdit,
                    canCheck:hasSelect,
                    canNew:hasRight
                })
            }
        })
    }

    handleClick = (e) => {
        const urlMap = {
            select: {
                title: i18n.label.selectReserveNumber(),
                url: addContentPath(`/spa/hrm/engine.html#/hrmengine/reservedNumber?type=${this.type}&isSimple=1`)
            },
            add: {
                title: i18n.label.newReserveNumber(),
                url: addContentPath(`/spa/hrm/engine.html#/hrmengine/newReservedNumberContent?type=${this.type}`)
            }
        }

        const { title, url } = urlMap[e.target.id]

        ecCom.WeaTools.createDialog({
            title,
            url,
            moduleName: 'hrm',
            style: { width: 800, height: 600 },
            callback: this.updateFormField,
            onCancel: () => { // 关闭通信
            }
        }).show();
    }
    updateFormField = (value) => {
        const {form} = this.props;
        form.updateFields({
            [this.targetKey]: value
        })
    }
    //重新生成编号
    reNumber = () => {
        const {form,useId} = this.props;
        const fieldMap = {
                subcompanycode: 'subshowid',
                departmentcode: 'showid',
                jobtitlecode: 'jobactivityid',
                workcode:'useid'
            },
            fieldname = fieldMap[this.targetKey]

        WeaTools.callApi('/api/hrm/codeSetting/regenerateCode', 'POST', {
            serialtype: this.type,
            [`${this.type.toLocaleLowerCase()}id`]: form.getFormParams()[fieldname] || useId
        }).then(res => {
            const{api_status,code} = res;
            if (api_status) {
                if (code) {
                    this.updateFormField(code)
                }else{
                    message.error(res.api_errormsg)
                }
            }
        })
    }


    render() {
        const {canRe,canCheck,canNew} = this.state;
        return (
            <div>
                { canRe && <a onClick={this.reNumber}>{i18n.label.reNumber()}</a>}
                { canCheck && <a onClick={this.handleClick}  style={{marginLeft:canRe && 10}} id='select'>{i18n.label.selectReserveNumber()}</a>}
                { canCheck && canNew && <a style={{marginLeft: 10}} onClick={this.handleClick} id='add'>{i18n.label.newReserveNumber()}</a> }
            </div>
        )
    }
}

/**
 * 添加多级路径
 *
 * @param {*} url
 */
export const addContentPath = (url) => {
  const ecologyContentPath = window.ecologyContentPath || '';
  if (url && ecologyContentPath) {
    //避免重复添加ecologyContentPath
    //避免传入的参数不是链接
    if (url.startsWith('/') && !url.startsWith(ecologyContentPath)) {
      url = ecologyContentPath + url;
    }
  }
  return url;
};

function Stack() {
    this.dataStore = [];
    this.push = function(element) {
        this.dataStore.push(element)
    };
    this.pop = function() {
        return this.dataStore.pop();
    };
    this.peek = function() {
        return this.dataStore[this.dataStore.length - 1];
    }
    this.length = function(){
        return this.dataStore.length
    }
    this.clear = function(){
        this.dataStore = [];
    }
}

export function UnRe() {
    //操作栈
    this.reStack = new Stack();
    //撤销栈
    this.unStack = new Stack();
    //是否可以恢复
    this.canRe = function() {
        return this.reStack.length() > 1
    };
    //是否可以撤销
    this.canUn = function() {
        return this.unStack.length() > 0
    };
    //恢复
    this.redo = function() {
        if (this.canRe()) {
            this.unStack.push(this.reStack.pop())
        }
    }
    //撤销
    this.undo = function() {
        if (this.canUn()) {
            this.reStack.push(this.unStack.pop());
        }
    }
    //获取当前需要展示的数据
    this.peek = function() {
        return this.reStack.peek();
    }
    //插入
    this.insert  =function(element){
        this.reStack.push(element);
    }
    //清空
    this.clear = function(){
        this.reStack.clear();
        this.unStack.clear();
    }
}