import { message, Modal, Button, Alert } from 'antd'
import { WeaLocaleProvider, WeaButtonIcon } from 'ecCom'
import { action, computed, observable, toJS } from "mobx"
import moment from 'moment'
import { i18n } from '../../public/i18n'
import { TableListStore, SearchStore, DialogStore, FormStore } from '../../public/valhalla/stores/index'
import { flattenDeep } from 'lodash'
import * as api from '../../apis/serialNumber.js'
const confirm = Modal.confirm
const getLabel = WeaLocaleProvider.getLabel;

//起始编号及预留编号设置
export default class StartReservedNumberSet {
    get entryLabels() { return ['startNumber', 'reserveNumber'].map(key => i18n.label[key]()) }

    get browserNames() { return ['multiSub', 'multiDept', 'post'].map(key => i18n.label[key]()) }



    parentStore = {}
    modifiedData = []
    browserProps = {
        iconBgcolor: '#217346',
        icon: 'icon-coms-hrm',
        isSingle: false,
        inputStyle: { width: 200 },
        viewAttr:3
    }
    @observable hasTabBtn = true
    @observable visible = false
    @observable iconIndex = 0
    @observable numberFlowRuleStore = {}
    @observable startNumberColumns = []
    @observable startNumberDatas = []
    @observable startDate = new Date()
    @observable endDate = new Date()
    @observable realDialogHeight = 0
    @observable subCompanyId = ''
    @observable deptId = ''
    @observable jobtitlesId = ''
    @observable searchStore = new SearchStore(this)
    @observable tablelistStore = new TableListStore()
    @observable dialogStore = new DialogStore(this)
    @observable formStore = new FormStore(this)
    @observable SUBCOMPANYCODE = '';
    @observable DEPARTMENTCODE = '';
    @observable JOBTITLESCODE = '';

    @computed get title() {
        return this.entryLabels[this.iconIndex]
    }

    @computed get format() {
        const { dateOptionValue } = this.numberFlowRuleStore
        return { 'year#': 'YYYY', 'month#': 'YYYY-MM', 'date#': 'yyyy-MM-dd' } [dateOptionValue]
    }

    @computed get dateLabel() {
        const { dateOptionValue } = this.numberFlowRuleStore
        return { 'year#': i18n.label.year(), 'month#': i18n.label.month1(), 'date#': i18n.label.date() } [dateOptionValue]
    }

    @computed get momentFormat() {
        return this.format && this.format.split('-').map(val => val.toUpperCase()).join('-')
    }

    @computed get dateStart() {
        const startDate = this.startDate
        return (typeof startDate == 'object') ? this.momentFormat && moment(startDate).format(this.momentFormat) : startDate
    }

    @computed get dateEnd() {
        const endDate = this.endDate
        return (typeof endDate == 'object') ? this.momentFormat && moment(endDate).format(this.momentFormat) : endDate
    }

    @computed get startNumFormParams() {
        const { dateChecked, orgChecked, postChecked, dateOptionValue, orgOptionValue } = this.numberFlowRuleStore
        const { coderuleid } = this.parentStore
        let type = ''
        if (dateChecked == '1') {
            type = { 'year#': 'YEAR', 'month#': 'MONTH', 'date#': 'DAY' } [dateOptionValue]
        }
        if (orgChecked == '1') {
            const t = { 'sub#': 'SUBCOMPANY', 'dept#': 'DEPARTMENT' }[orgOptionValue]
            type = type ? `${type},${t}` : t
        }
        if (postChecked == '1') {
            const t = 'JOBTITLES'
            type = type ? `${type},${t}` : t
        }
        return {
            coderuleid,
            type,
            dateStart: this.dateStart,
            dateEnd: this.dateEnd,
            subCompanyId: this.subCompanyId,
            deptId: this.deptId,
            jobtitlesId: this.jobtitlesId,
        }
    }

    @computed get SearchButtons() {
        if (!this.hasTabBtn) return []
        const { tableStore: { selectedRowKeys } } = this.tablelistStore
        const setDisabled = (type) => {
            return (type == 'add') ? false : (selectedRowKeys.length == 0)
        }
        return ['add', 'del'].map(type => <WeaButtonIcon ecId={`${this && this.props && this.props.ecId || ''}_WeaButtonIcon@zkszwh@${type}`} buttonType={type} type='primary' disabled={setDisabled(type)} onClick={() => this.handleButtonIconClick(type)} />)
    }

    @computed get reserveFlowNumbers() {
        const { form } = this.formStore
        const { flowcode } = form.getFormParams()
        const compareFlowcode = (a, b) => (a - b)

        return flowcode ? flattenDeep(
            flowcode.split(',').map(flowNum => {
                if (/-/.test(flowNum)) {
                    return this.getScopeNumbers(flowNum.split('-').sort(compareFlowcode).map(num => parseInt(num)))
                } else {
                    return flowNum
                }
            })
        ).sort(compareFlowcode) : []
    }

    @computed get previewDatas() {
        const { form } = this.formStore
        const formParams = form.getFormParams();

        const param = {}
        this.serialNumFieldsKey.map(key => {
            if (['SUBCOMPANY','DEPARTMENT','JOBTITLES'].includes(key)) {
                param[key] = this[`${key}CODE`]
                return;
            }
            param[key] = formParams[key];
        })
        let NUMBER = param.NUMBER;
        return this.reserveFlowNumbers.map(num => {
            param.NUMBER = num.toString().padStart(NUMBER, 0);
            return Object.values(param).join('');
        })

    }

    @computed get serialNumFieldsKey(){
        const {conditions} = this.formStore;
        if (!conditions.length) return [];
        return conditions[0].items.map(item => item.domkey[0]);
    }

    @computed get showPreviewDatas() {
        if (!this.previewDatas) return []
        const datas = this.previewDatas
        const len = datas.length
        if (len > 10) {
            return [...datas.slice(0, 5), '...', ...datas.slice(-5)]
        } else {
            return datas
        }
    }

    @computed get reserveDfButtons() {
        return [];

        const { tableStore: { selectedRowKeys, datas } } = this.tablelistStore
        const disabled = selectedRowKeys.length === 0

        return [<Button ecId={`${this && this.props && this.props.ecId || ''}_Button@mj1oez@1`} type='primary' disabled={disabled} onClick={()=>{
            const dialog = top.window.getParentDialog();
            if (dialog) {
                const number = selectedRowKeys.reduce((total,cur) => {
                    return total + datas.find(data => data.randomFieldId == cur).reservedcode
                },'') 
                dialog.close();
                dialog.callback(number);
            }
        }}>{i18n.button.sure()}</Button>]
    }

    get newReserveDfButtons() {
        return [<Button ecId={`${this && this.props && this.props.ecId || ''}_Button@uujwae@2`} type='primary' onClick={() => {
            this.handleSave(true).then(() => {
                const dialog = top.window.getParentDialog();
                if (dialog) {
                    dialog.close();
                }
            })
        }}>{i18n.button.save()}</Button>]
    }

    get DialogButtons() {
        return [<Button ecId={`${this && this.props && this.props.ecId || ''}_Button@gjg1rs@DialogButtons`} type='primary' onClick={this.handleSave}>{i18n.button.save()}</Button>]
    }

    get OtherComponents() {
        return {
            flowcode: () => <p>{i18n.label.reserveFlowNumFormat()}</p>
        }
    }

    get tableParams() {
        const { form } = this.searchStore
        return { ...form.getFormParams(), serialtype: this.parentStore.serialtype }
    }

    validateStartNum = (_params,isError) => {
         let arr = [];
        const o = {
            SUBCOMPANY:'subCompanyId',
            DEPARTMENT:'subCompanyId,deptId',
            JOBTITLES:'jobtitlesId'
        }
        _params.type.split(',').map(v => {
            if (!o[v]) return;
           if(o[v].indexOf(',') > -1){
               o[v].split(',').map(k => {
                arr.push(k);
               }) 
           }else{
            arr.push(o[v]);
           }
        })
        if(arr.every(v => _params[v])){
            return true;
        }else{
            arr.map(v => {
                if (!_params[v] && isError) {
                     const refName = `${{subCompanyId:'sub',deptId:'dept',jobtitlesId:'post'}[v]}Ref`;
                    this[refName].showError();
                }
            })
            return false;
        }
    }

    /**
     * 概述：获取起始编号可编辑列表数据
     */
    @action getStartNumForm = (params = {},cb) => {
        const _params = {
            ...this.startNumFormParams,
            ...params
        }
        if (!this.validateStartNum(_params)) return;
        
        return api.getStartNumForm(_params).then(res => {
            const { api_status, columns, dataSource } = res;
            if (api_status) {
                this.startNumberColumns = columns && this.extendColumns(columns)
                this.startNumberDatas = dataSource.map((data, i) => ({ ...data, id: data.id || i }))
                return true;
            } else {
                message.error(res.message)
            }
        })
    }

    handleIconClick = (index) => {
        this.iconIndex = index
        this.onOpen()
        this.parentStore.handleSave(false).then(() => {
            if (index == 0) {
                this.getStartNumForm()
            } else {
                this.initSearch().then(() => this.initTablelist())
            }
        })
    }

    handleButtonIconClick = (type) => {
        if (type == 'add') {
            this.dialogStore.init({
                title: i18n.label.newReservedNumber(),
                style: { width: 640, height: 580 }
            }).openDialog()
            this.initForm()
        }
        if (type == 'del') {
            this.showConfirm(i18n.confirm.deleteSelected(), this.deleteReservedCodeById)
        }
    }

    handleCondition = (datas) => {
        const { conditioninfo,coderuleid } = datas
        if (Array.isArray(conditioninfo)) {
            conditioninfo[1].items.unshift({
                conditionType: 'CUSTOM',
                domkey: ['tip'],
                custom: <Alert ecId={`${this && this.props && this.props.ecId || ''}_Alert@1amz2m`} message={<span>{i18n.label.reserveNumTip()}</span>} type="warning" showIcon />
            })
            conditioninfo.map(c => c.items.map(item => {
                if (item.domkey[0] == 'YEAR') {
                    item.value = item.value.toString()
                }
            }))
        }
        this.parentStore.coderuleid = coderuleid;
    }

    initSearch = () => {
        return this.searchStore.init({
            api: api.getAdvanceSearchCondition,
            _handleSearch: this.initTablelist,
            linkageFieldName: 'reservedcode'
        }).fetchSearchForm()
    }

    initTablelist = () => {
        const params = {...this.tableParams, checkboxType: this.isSimple ? 'single' : 'multi' }
        this.tablelistStore.init({
            api: api.getSearchReservedCodeList,
            scroll: {
                y: (this.realDialogHeight || 550) - 150
            },
            onRowClick:record => {
               if (this.isSimple) {
                const {reservedcode} = record
                const dialog = top.window.getParentDialog();
                if (dialog) {
                    dialog.close();
                    dialog.callback(reservedcode);
                }
               }
            }
        }).fetchTableList(params)
    }

    /**
     * 概述：保存起始编号
     */
    saveStartNum = () => {
        const result = this.tableEditRef.doValidate()
        if (!result.pass) return
        if (!this.validateStartNum(this.startNumFormParams,true)) {
            return 
        }
        this.showConfirm(i18n.label.isSaveDataOrNot(), () => {
            const { coderuleid } = this.parentStore
            const params = {
                datas: JSON.stringify({
                    coderuleid,
                    dataSource: this.modifiedData,
                    columns: toJS(this.startNumberColumns),
                })
            }
            api.saveStartNum(params).then(res => {
                const { api_status } = res
                if (api_status) {
                    message.success(i18n.label.sucessSave())
                    this.onCancel()
                } else {
                    message.error(res.message)
                }
            })
        })

    }

    handleSave = (isSingle) => {
        isSingle = (typeof isSingle == "boolean") ? isSingle : false

        return new Promise((resolve, reject) => {
            const { validateForm, form } = this.formStore

            validateForm(form).then(() => {
                if (this.testRE()) {
                    const { form } = this.formStore
                    const { desc } = form.getFormParams()
                    const params = {
                        serialtype: this.parentStore.serialtype,
                        reserveddesc: desc,
                        reservedcodes: this.previewDatas.join(',')
                    }
                    api.saveReservedCode(params).then(res => {
                        const { api_status,exist } = res;
                        if (api_status) {
                            if (exist) {
                                 this.showFlowcodeExist();
                                 return;
                            }
                            message.success(i18n.label.sucessSave())
                            if (!isSingle) {
                                this.dialogStore.closeDialog();
                                this.tablelistStore.fetchTableList(this.tableParams)
                            }
                            resolve()
                        } else {
                            if (typeof res.message == 'string') {
                                message.error(res.message)
                            } else {
                                this.showFlowcodeExist()
                            }
                            reject()

                        }
                    })
                }
            })
        }).catch((e) => {})
    }

    deleteReservedCodeById = () => {
        const { tableStore: { selectedRowKeys } } = this.tablelistStore
        const params = {
            ids: selectedRowKeys.join(',')
        }
        api.deleteReservedCodeById(params).then(res => {
            const {api_status,sign} = res
            if (api_status) {
                if (sign =='1') {
                    message.success(res.message)
                     this.initTablelist()
                }else{
                    message.warning(res.message)
                }
            }else{
                message.error(res.message)
            }
        })
    }

    /**
     * 概述：日期控件回调函数
     * @param  {[String]} val  [日期]
     * @param  {[String]} type [标识操作的是哪一个日期控件]
     */
    handleDatePickerChange = (val, type) => {
        this[`${type}Date`] = val
        this.getStartNumForm()
    }

    /**
     * 概述：为列添加com属性，调整列宽
     */
    extendColumns = (columns) => {
        columns.forEach(c => {
            c.width = `${100 / columns.length - 5}%`
            if (c.dataIndex == 'startnum') {
                c.com = [{ type: "INPUTNUMBER", key: "startnum", viewAttr: 3,min:0 }]
            } else {
                c.com = [{ type: "INPUT", key: c.dataIndex, viewAttr: 1 }]
            }
        })
        return columns;
    }

    handleChangeHeight = (h) => {
        this.realDialogHeight = h
    }

    handleTableEditableChange = (_datas, _other, _data) => {}

    handleTableEditableEdit = (datas, result) => {
        this.startNumberDatas = datas
        const { id,value } = result.record
        const targetIndex = this.modifiedData.findIndex(data => data.id == id)
        const record = result.record;
        record.startnum = result.value;
        if (targetIndex > -1) {
            this.modifiedData[targetIndex] = record
        } else {
            this.modifiedData.push(record)
        }
    }

    testRE = () => {
        const { form } = this.formStore
        const { flowcode } = form.getFormParams()

        const charRE = /[A-Za-z]/,
            specialCharRE = /[^A-Za-z0-9_,-]/,
            // scopeRE = /(?<=\d+)-(?=\d+)/,
            startEndRE = /^,|,$/
        if (
            charRE.test(flowcode) ||
            specialCharRE.test(flowcode) ||
            // (/-/.test(flowcode) && !scopeRE.test(flowcode)) ||
            startEndRE.test(flowcode)
        ) {
            form.showError('flowcode', i18n.label.flowcodeFormatError())
            return
        }
        return true
    }

    flowcodeCompare = () => {
        const { form } = this.formStore
        const { flowcode, currentnumber } = form.getFormParams()

        const flowArr = flowcode.split(',')
        for (let i = 0; i < flowArr.length; i++) {
            const flowNum = flowArr[i]
            if (/-/.test(flowNum)) {
                const [start] = flowNum.split('-').sort((a, b) => (a - b))
                if (parseInt(start) <= parseInt(currentnumber)) {
                    this.showFlowcodeExist()
                    return
                }
            } else {
                if (parseInt(flowNum) <= parseInt(currentnumber)) {
                    this.showFlowcodeExist()
                    return
                }
            }
        }
        return true
    }

    getScopeNumbers = (arr) => {
        const [start, end] = arr
        const nums = []
        for (let i = start; i <= end; i++) {
            nums.push(i)
        }
        return nums;
    }

    handleFormChange = (datas) => {
        const {form} = this.formStore;
       const keys = ['YEAR','MONTH','DAY','SUBCOMPANY','DEPARTMENT','JOBTITLES'];
     const targetKey = datas ?  Object.keys(datas)[0] : 'YEAR';

     if (['SUBCOMPANY','DEPARTMENT','JOBTITLES'].includes(targetKey)) {
        const id = datas[targetKey].value;
            if (!id) return;
            const params = {
                id,
                serialtype:targetKey,
            }
            this.getCodeByType(params);
        }
        
        const params ={
            dateStart: '',
            dateEnd: '',
            subCompanyId: '',
            deptId: '',
            jobtitlesId: ''
        }
        const formParams = form.getFormParams()
        const{YEAR,MONTH,DAY,SUBCOMPANY,DEPARTMENT,JOBTITLES}=formParams;
      
         let dateStart = [MONTH,DAY].reduce((total,num) => {
        if (num) {
            total  =`${total}-${num}`;
        }
        return total;
       },YEAR);
         Object.assign(params,{
            dateStart,
            dateEnd:dateStart
         });
         [SUBCOMPANY,DEPARTMENT,JOBTITLES].map((val,i) => {
           const arr = ['subCompanyId','deptId','jobtitlesId'];
           if (val) {
            Object.assign(params,{
                [arr[i]] : val
            })
           }
         })

         const _params = Object.assign({},this.startNumFormParams,params);

        ['YEAR','MONTH','DAY'].map(v => {
            if (formParams[v]) {
                _params.type = v;
            }
        })

     if (keys.includes(targetKey)) {
        if(SUBCOMPANY === '' || DEPARTMENT === '' || JOBTITLES === '')return;
         this.getStartNumForm(_params).then(()=>{
             form.updateFields({
                currentnumber:this.startNumberDatas[0].startnum
             })
         })
     }

    }

    getCodeByType = (params) => {
        api.getCodeByType(params).then(res => {
            const {code} = res;
            this[`${params.serialtype}CODE`] = code;
        })
    }

    handleBrowserChange = (ids, type) => {
        const browserMap = {
            sub: 'subCompanyId',
            dept: 'deptId',
            post: 'jobtitlesId'
        }
        const prop = browserMap[type]
        this[prop] = ids;
        if (ids) this.getStartNumForm()
    }

    validateBrowser = () => {
        const { orgChecked, orgOptionValue } = this.numberFlowRuleStore

        return new Promise((resolve, reject) => {
            if (orgChecked == '1') {
                if (orgOptionValue == 'sub#' && !this.subCompanyId) {
                    this.subRef.showError()
                    reject()
                }
                resolve()
            } else {
                resolve()
            }
        })
    }

    showConfirm = (content, callback) => {
        confirm({
            title: getLabel(131329, '信息确认'),
            content,
            okText: getLabel(33703, '确认'),
            onOk() {
                callback && callback()
            },
        });
    }

    @action onOpen = () => {
        this.visible = true
    }

    @action onCancel = () => {
        this.visible = false
        this.reset()
    }

    @action setTabBtn = (b) => {
        this.hasTabBtn = b
    }

    setRef = (ref) => {
        const name = ref && ref.props.name
        if (name) {
            this[`${name}Ref`] = ref
        } else {
            this.tableEditRef = ref
        }
    }

    rely = (scope) => {
        const { numberFlowRuleStore } = scope
        this.numberFlowRuleStore = numberFlowRuleStore
        this.parentStore = scope
    }

    initForm = () => {
        this.formStore.init({
            api: api.getReservedCodeFrom,
            isCustomRender: true,
            className: 'serialNumber'
        }).fetchForm({ serialtype: this.parentStore.serialtype }, this.handleCondition,this.handleFormChange)
    }

    reset() {
        this.subCompanyId = ''
        this.deptId = ''
        this.jobtitlesId = ''
        this.startNumberColumns = []
        this.startNumberDatas = []
    }

    showFlowcodeExist() {
        this.formStore.form.showError('flowcode', i18n.label.flowcodeExisted())
    }

    setSerialType = (type) => {
        this.parentStore.serialtype = type
    }

    setIsSimple  =(b) => {
        this.isSimple =  b
    }

}