<template>
    <div
        style="height:100%;"
        v-domresize
        @domresize="resizePanel"
        :changeParams="changeParams"
    >

        <div
            style="background:#fff;"
            v-domresize
            @domresize="resizeHead"
        >

            <!-- 標題區 -->
            <div style="padding:10px 10px 10px 20px;">
                <div :style="`display:flex; align-items:center; padding:${drawer?'5px':'5px 5px 5px 20px'};`">

                    <WIcon
                        :icon="mdiAccountGroupOutline"
                        :color="'#000'"
                        :size="32"
                    ></WIcon>

                    <div style="padding-left:12px;">

                        <div style="font-size:1.4rem; color:#000;">
                            {{$t('mmUsersList')}}
                        </div>

                        <div style="padding-top:2px; font-size:0.8rem; color:#666;">
                            {{$t('mmUsersListMsg')}}
                        </div>

                    </div>

                </div>
            </div>

            <!-- 功能區 -->
            <div
                style="padding:5px; border-top:1px solid #ddd; display:flex; align-items:center;"
                _v-if="showIsEditable || isEditable"
            >

                <template v-if="showIsEditable">

                    <div style="padding:6px 0px 4px 4px;">
                        <WSwitch
                            v-model="isEditable"
                            :text="$t('modeEdit')"
                        ></WSwitch>
                    </div>

                    <div style="padding-left:10px;"></div>

                </template>

                <template v-if="true">

                    <WPopup
                        :isolated="true"
                        _show=""
                        _hide=""
                    >
                        <template v-slot:trigger>
                            <WButtonCircle
                                :paddingStyle="{v:6,h:6}"
                                :tooltip="$t('showTabCols')"
                                :icon="mdiTableHeadersEye"
                                :backgroundColor="'#fff'"
                                :backgroundColorHover="'#f2f2f2'"
                                :iconColor="'#444'"
                                :iconColorHover="'#222'"
                                :iconColorFocus="'#222'"
                                :shadow="false"
                                _click=""
                            ></WButtonCircle>
                        </template>

                        <template v-slot:content>
                            <div style="padding:10px 0px 10px 0px;">

                                <div style="padding:7px 10px; font-size:0.85rem; color:#222; background:#f2f2f2;">
                                    {{$t('showTabCols')}}
                                </div>

                                <div style="padding:7px 9px 0px 7px;">
                                    <WInputCheckbox
                                        :items="tabKeysPick"
                                        v-model="tabKeysShow"
                                        @input="toggleTabKeys"
                                    >
                                        <template v-slot="props">
                                            <div style="padding-left:3px; display:flex; align-items:center; font-size:0.85rem; height:24px; cursor:pointer;">
                                                {{getHead(props.item.data)}}
                                            </div>
                                        </template>
                                    </WInputCheckbox>
                                </div>

                            </div>
                        </template>
                    </WPopup>

                    <div style="padding-left:4px;"></div>

                </template>

                <template v-if="isEditable">

                    <WButtonCircle
                        :paddingStyle="{v:6,h:6}"
                        :tooltip="$t('userAdd')"
                        :icon="mdiPlus"
                        :backgroundColor="'#fff'"
                        :backgroundColorHover="'#f2f2f2'"
                        :iconColor="'#444'"
                        :iconColorHover="'#222'"
                        :iconColorFocus="'#222'"
                        :shadow="false"
                        @click="addItem"
                    ></WButtonCircle>

                    <div style="padding-left:4px;"></div>

                </template>

                <template v-if="isEditable && hasItemCheckOne">

                    <WButtonCircle
                        :paddingStyle="{v:6,h:6}"
                        :tooltip="$t('userCopy')"
                        :icon="mdiContentCopy"
                        :backgroundColor="'#fff'"
                        :backgroundColorHover="'#f2f2f2'"
                        :iconColor="'#444'"
                        :iconColorHover="'#222'"
                        :iconColorFocus="'#222'"
                        :shadow="false"
                        @click="copyItem"
                    ></WButtonCircle>

                    <div style="padding-left:4px;"></div>

                </template>

                <template v-if="isEditable && hasItemsCheck">

                    <WButtonCircle
                        :paddingStyle="{v:6,h:6}"
                        :tooltip="$t('userDeleteCheckUsers')"
                        :icon="mdiTrashCanOutline"
                        :backgroundColor="'#fff'"
                        :backgroundColorHover="'#f2f2f2'"
                        :iconColor="'#444'"
                        :iconColorHover="'#222'"
                        :iconColorFocus="'#222'"
                        :shadow="false"
                        @click="deleteItemsCheck"
                    ></WButtonCircle>

                    <div style="padding-left:4px;"></div>

                </template>

                <template v-if="isEditable && isModified">

                    <WButtonCircle
                        :paddingStyle="{v:6,h:6}"
                        :tooltip="$t('saveChanges')"
                        :icon="mdiCloudUploadOutline"
                        :backgroundColor="'rgba(255,0,50,0.7)'"
                        :backgroundColorHover="'rgba(255,0,50,0.8)'"
                        :iconColor="'#eee'"
                        :iconColorHover="'#fff'"
                        :iconColorFocus="'#fff'"
                        :shadow="false"
                        @click="saveUsers"
                    ></WButtonCircle>

                    <div style="padding-left:4px;"></div>

                </template>

            </div>

        </div>

        <template
            v-if="!isLoading"
        >

            <template v-if="items">
                <WAggridVueDyn
                    ref="rftable"
                    :style="`width:100%;`"
                    :height="contentHeight"
                    :opt="opt"
                >
                </WAggridVueDyn>
            </template>

        </template>

        <div
            style="padding:10px 15px; font-size:0.8rem;"
            v-else
        >
            {{$t('waitingData')}}
        </div>

    </div>
</template>

<script>
import { mdiAccountGroupOutline, mdiCloudUploadOutline, mdiTrashCanOutline, mdiTableHeadersEye, mdiPlus, mdiContentCopy } from '@mdi/js/mdi.js'
import ot from 'dayjs'
import get from 'lodash-es/get.js'
import set from 'lodash-es/set.js'
import each from 'lodash-es/each.js'
import size from 'lodash-es/size.js'
import filter from 'lodash-es/filter.js'
import sortBy from 'lodash-es/sortBy.js'
import cloneDeep from 'lodash-es/cloneDeep.js'
import haskey from 'wsemi/src/haskey.mjs'
import isestr from 'wsemi/src/isestr.mjs'
import iseobj from 'wsemi/src/iseobj.mjs'
import istimemsTZ from 'wsemi/src/istimemsTZ.mjs'
import isEmail from 'wsemi/src/isEmail.mjs'
import cstr from 'wsemi/src/cstr.mjs'
import arrPull from 'wsemi/src/arrPull.mjs'
import domShowInputDatatime from 'wsemi/src/domShowInputDatatime.mjs'
import WIcon from 'w-component-vue/src/components/WIcon.vue'
import WSwitch from 'w-component-vue/src/components/WSwitch.vue'
import WButtonCircle from 'w-component-vue/src/components/WButtonCircle.vue'
import WPopup from 'w-component-vue/src/components/WPopup.vue'
import WInputCheckbox from 'w-component-vue/src/components/WInputCheckbox.vue'
import WAggridVueDyn from 'w-component-vue/src/components/WAggridVueDyn.vue'


export default {
    components: {
        WIcon,
        WSwitch,
        WButtonCircle,
        WPopup,
        WInputCheckbox,
        WAggridVueDyn,
    },
    props: {
        drawer: {
            type: Boolean,
            default: false,
        },
    },
    data: function() {
        return {
            mdiAccountGroupOutline,
            mdiCloudUploadOutline,
            mdiTrashCanOutline,
            mdiTableHeadersEye,
            mdiPlus,
            mdiContentCopy,

            panelWidth: 100,
            panelHeight: 100,
            headHeight: 100,

            isLoading: true,
            firstSetting: true,
            showIsEditable: false,
            isEditable: false,
            isModified: false,

            tabKeys: [
                'id',
                'order',
                'account',
                'password', //後端api不提供, 前端自動渲染提供變更密碼用
                'name',
                'email',
                'description',
                'from',
                'redir',
                'isAdmin',
                'timeVerified',
                'timeExpired',
                'timeBlocked',
                'userId',
                'timeCreate',
                'userIdUpdate',
                'timeUpdate',
                'isActive',
            ],
            tabKeysPick: [
                'account',
                'password', //後端api不提供, 前端自動渲染提供變更密碼用
                'name',
                'email',
                'description',
                'from',
                'redir',
                'isAdmin',
                'timeVerified',
                'timeExpired',
                'timeBlocked',
                'userId',
                'timeCreate',
                'userIdUpdate',
                'timeUpdate',
                'isActive',
            ],
            tabKeysShow: [
                'account',
                'password', //後端api不提供, 前端自動渲染提供變更密碼用
                'name',
                'email',
                'description',
                'from',
                'redir',
                'isAdmin',
                'timeVerified',
                'timeExpired',
                'timeBlocked',
                'userId',
                'timeCreate',
                'userIdUpdate',
                'timeUpdate',
                'isActive',
            ],

            widthUsersName: null,
            widthUsersEmail: null,
            widthUsersDescription: null,

            users: [],
            items: [],
            itemsCheck: [],
            opt: null,

        }
    },
    mounted: function() {
        // console.log('mounted')

        let vo = this

        //註冊至$dg供使用
        vo.$dg.toggleItemIsAdminById = vo.toggleItemIsAdminById
        // vo.$dg.toggleItemIsVerifiedById = vo.toggleItemIsVerifiedById
        vo.$dg.toggleItemIsActiveById = vo.toggleItemIsActiveById
        vo.$dg.modifyItemPasswordById = vo.modifyItemPasswordById
        vo.$dg.modifyItemTimeVerifiedById = vo.modifyItemTimeVerifiedById
        vo.$dg.modifyItemTimeExpiredById = vo.modifyItemTimeExpiredById
        vo.$dg.modifyItemTimeBlockedById = vo.modifyItemTimeBlockedById

        //firstSetting
        if (vo.firstSetting) {
            // console.log('webInfor', vo.webInfor)

            let showModeEditUsers = get(vo, 'webInfor.showModeEditUsers', '')
            vo.showIsEditable = showModeEditUsers === 'y'
            let modeEditUsers = get(vo, 'webInfor.modeEditUsers', '')
            vo.isEditable = modeEditUsers === 'y'

            vo.widthUsersName = get(vo, 'webInfor.widthUsersName', '')
            vo.widthUsersEmail = get(vo, 'webInfor.widthUsersEmail', '')
            vo.widthUsersDescription = get(vo, 'webInfor.widthUsersDescription', '')

            vo.firstSetting = false
        }

        //token
        let token = vo.userToken
        // console.log('token', token)

        //getUsersList
        vo.$fapi.getUsersList(token)
            .then((res) => {
                // console.log(res)
                res = sortBy(res, 'order')
                vo.users = res
            })
            .catch((err) => {
                console.log(err)
                vo.errMsg = vo.$t('getDataError')
            })
            .finally(() => {
                vo.isLoading = false
            })

    },
    computed: {

        webInfor: function() {
            let wi = get(this, `$store.state.webInfor`)
            return wi
        },

        userToken: function() {
            let vo = this
            return get(vo, `$store.state.userToken`)
        },

        changeParams: function() {
            // console.log('computed changeParams')

            let vo = this

            //trigger
            let isEditable = vo.isEditable

            //items
            let items = cloneDeep(vo.users)

            //save
            vo.items = items

            //genOpt
            vo.genOpt({ isEditable })

            //isLoading
            vo.isLoading = false

            return ''
        },

        contentHeight: function() {
            let vo = this

            //h
            let h = vo.panelHeight - vo.headHeight
            h = Math.max(h, 0)

            return h
        },

        hasItemsCheck: function() {
            let vo = this

            //h
            let b = size(vo.itemsCheck) > 0

            return b
        },

        hasItemCheckOne: function() {
            let vo = this

            //h
            let b = size(vo.itemsCheck) === 1

            return b
        },

        errItemsByAccount: function() {
            let vo = this

            //rows
            let rows = get(vo, 'opt.rows', [])

            //kpErr
            let kpErr = {}
            let kpAccount = {}
            each(rows, (v, k) => {

                //account
                let account = get(v, 'account', '')

                //check
                if (!isestr(account)) {

                    //kpErr
                    kpErr[account] = vo.$t(`userAccountEmpty`)

                    return true //跳出換下一個
                }

                //check
                if (haskey(kpAccount, account)) {

                    //kpErr
                    kpErr[account] = vo.$t(`userAccountDuplicate`)

                    return true //跳出換下一個
                }

                //kpAccount
                kpAccount[account] = true

            })

            return kpErr
        },

        errItemsByEmail: function() {
            let vo = this

            //rows
            let rows = get(vo, 'opt.rows', [])

            //kpErr
            let kpErr = {}
            let kpEmail = {}
            each(rows, (v, k) => {

                //email
                let email = get(v, 'email', '')

                //check
                if (!isestr(email)) {

                    //kpErr
                    kpErr[email] = vo.$t(`userEmailEmpty`)

                    return true //跳出換下一個
                }

                //check
                if (!isEmail(email)) {

                    //kpErr
                    kpErr[email] = vo.$t(`userEmailError`)

                    return true //跳出換下一個
                }

                //check
                if (haskey(kpEmail, email)) {

                    //kpErr
                    kpErr[email] = vo.$t(`userEmailDuplicate`)

                    return true //跳出換下一個
                }

                //kpEmail
                kpEmail[email] = true

            })

            return kpErr
        },

        errItemsByRedir: function() {
            let vo = this

            //rows
            let rows = get(vo, 'opt.rows', [])

            //kpErr
            let kpErr = {}
            each(rows, (v, k) => {

                //redir
                let redir = get(v, 'redir', '')

                //check
                if (!isestr(redir)) {

                    //kpErr
                    kpErr[redir] = vo.$t(`userRedirEmpty`)

                    return true //跳出換下一個
                }

            })

            return kpErr
        },

        isError: function() {
            let vo = this

            let c = ''
            let b = false
            b = iseobj(vo.errItemsByAccount)
            if (b) {
                c = vo.$t('errInAccounts')
                return c
            }
            b = iseobj(vo.errItemsByEmail)
            if (b) {
                c = vo.$t('errInEmails')
                return c
            }
            b = iseobj(vo.errItemsByRedir)
            if (b) {
                c = vo.$t('errInRedir')
                return c
            }

            return ''
        },

        kpHead: function() {
            let vo = this

            let kp = {
                'id': vo.$t('id'),
                'order': vo.$t('order'),
                'account': vo.$t('account'),
                'password': vo.$t('password'),
                'name': vo.$t('name'),
                'email': vo.$t('email'),
                'description': vo.$t('description'),
                'from': vo.$t('from'),
                'redir': vo.$t('redir'),
                'isAdmin': vo.$t('isAdmin'),
                'timeVerified': vo.$t('userTimeVerified'),
                'timeExpired': vo.$t('userTimeExpired'),
                'timeBlocked': vo.$t('userTimeBlocked'),
                'userId': vo.$t('userId'),
                'timeCreate': vo.$t('timeCreate'),
                'userIdUpdate': vo.$t('userIdUpdate'),
                'timeUpdate': vo.$t('timeUpdate'),
                'isActive': vo.$t('isActive'),
            }

            return kp
        },

    },
    methods: {

        resizePanel: function(msg) {
            // console.log('methods resizePanel', msg)

            let vo = this

            //panelWidth, panelHeight
            vo.panelWidth = msg.snew.offsetWidth
            vo.panelHeight = msg.snew.offsetHeight

        },

        resizeHead: function(msg) {
            // console.log('methods resizeHead', msg)

            let vo = this

            //headHeight
            vo.headHeight = msg.snew.offsetHeight

        },

        getHead: function(key) {
            // console.log('methods getHead', key)

            let vo = this

            let head = get(vo, `kpHead.${key}`, '')

            return head
        },

        genOpt: function() {
            // console.log('methods genOpt')

            let vo = this

            //default
            vo.itemsCheck = []

            //opt
            let opt = null
            if (size(vo.items) > 0) {

                //ks
                let ks = vo.tabKeys
                // console.log('ks', ks)

                //kpHead
                let kpHead = vo.kpHead

                //kpCellEditable, kpRowDrag, kpHeadCheckBox
                let kpCellEditable = {}
                let kpRowDrag = {}
                let kpHeadCheckBox = {}
                if (vo.isEditable) {
                    kpCellEditable = {
                        'account': true,
                        'name': true,
                        'email': true,
                        'description': true,
                        'from': true,
                        'redir': true,
                    }
                    kpRowDrag = {
                        'account': true,
                    }
                    kpHeadCheckBox = {
                        'account': true,
                    }
                }

                //kpHeadHide
                let kpHeadHide = {
                    'id': true,
                    'order': true,
                }
                if (true) {
                    let tabKeysHide = arrPull(vo.tabKeysPick, vo.tabKeysShow)
                    each(tabKeysHide, (k) => {
                        kpHeadHide[k] = true
                    })
                }

                //opt
                opt = {
                    language: vo.$t('aggridLanguage'),
                    rows: vo.items,
                    keys: ks,
                    kpHead,
                    // autoFitColumn: true,
                    defCellEditable: false, //vo.isEditable
                    defHeadFilter: true,
                    defCellAlignH: 'left',
                    kpHeadHide,
                    kpHeadFixLeft: {
                        'account': true,
                    },
                    defHeadMinWidth: 150,
                    kpHeadWidth: {
                        'timeVerified': 250,
                        'timeExpired': 250,
                        'timeBlocked': 250,
                    },
                    kpHeadFilterType: {
                        'id': 'text',
                        'order': 'text',
                        'account': 'text',
                        'password': 'text',
                        'name': 'text',
                        'email': 'text',
                        'description': 'text',
                        'from': 'text',
                        'redir': 'text',
                        'isAdmin': 'text',
                        'timeVerified': 'text',
                        'timeExpired': 'text',
                        'timeBlocked': 'text',
                        'userId': 'text',
                        'timeCreate': 'text',
                        'userIdUpdate': 'text',
                        'timeUpdate': 'text',
                        'isActive': 'text',
                    },
                    kpCellEditable,
                    kpRowDrag,
                    kpHeadCheckBox,
                    kpHeadFilter: {
                        'password': false,
                    },
                    kpHeadSort: {
                        'password': false,
                    },
                    kpHeadFocusHighlight: { //雖然效果不完全, 但因按鈕與cell有padding可被點擊, 故還是需要開啟
                        'password': false,
                        'timeVerified': false,
                        'timeExpired': false,
                        'timeBlocked': false,
                    },
                    kpCellRender: {
                        'account': (v) => {
                            // console.log('kpCellRender account', v)

                            //err
                            let err = get(vo.errItemsByAccount, v, '')
                            // console.log(v, err)

                            //check
                            if (isestr(err)) {
                                v = `
                                    <span title="${err}">
                                        <span style="color:#F57C00;">${cstr(v)}</span>
                                        <img style="vertical-align:sub; width:16px; height:16px;" src="${vo.$ui.getIcon('warning')}" />
                                    </span>
                                `
                            }

                            return v
                        },
                        'password': (v, k, r) => {
                            // console.log('kpCellRender password', v, k, r)

                            //id
                            let id = get(r, 'id', '')
                            // console.log('id', id, k, r)

                            // `
                            let t = `
                                <div onclick="event.stopPropagation();event.preventDefault();" onmousedown="event.stopPropagation();event.preventDefault();">
                                    <button style="width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;" onclick="$vo.$dg.modifyItemPasswordById('${id}')" ${vo.isEditable ? '' : 'disabled'} >${vo.$t('userResetPassword')}</button>
                                </div>
                            `

                            return t
                        },
                        'email': (v) => {
                            // console.log('kpCellRender email', v)

                            //err
                            let err = get(vo.errItemsByEmail, v, '')
                            // console.log(v, err)

                            //check
                            if (isestr(err)) {
                                v = `
                                    <span title="${err}">
                                        <span style="color:#F57C00;">${cstr(v)}</span>
                                        <img style="vertical-align:sub; width:16px; height:16px;" src="${vo.$ui.getIcon('warning')}" />
                                    </span>
                                `
                            }

                            return v
                        },
                        'redir': (v) => {
                            // console.log('kpCellRender redir', v)

                            //err
                            let err = get(vo.errItemsByRedir, v, '')
                            // console.log(v, err)

                            //check
                            if (isestr(err)) {
                                v = `
                                    <span title="${err}">
                                        <span style="color:#F57C00;">${cstr(v)}</span>
                                        <img style="vertical-align:sub; width:16px; height:16px;" src="${vo.$ui.getIcon('warning')}" />
                                    </span>
                                `
                            }

                            return v
                        },
                        'isAdmin': (v, k, r) => {
                            // console.log('kpCellRender isAdmin', v, k, r)

                            //id
                            let id = get(r, 'id', '')
                            // console.log('id', id, k, r)

                            let t = `
                                <input type="checkbox" ${v === 'y' ? 'checked' : ''} onclick="$vo.$dg.toggleItemIsAdminById('${id}')" ${vo.isEditable ? '' : 'disabled'} />
                            `

                            return t
                        },
                        'isActive': (v, k, r) => {
                            // console.log('kpCellRender isActive', v, k, r)

                            //id
                            let id = get(r, 'id', '')
                            // console.log('id', id, k, r)

                            let t = `
                                <input type="checkbox" ${v === 'y' ? 'checked' : ''} onclick="$vo.$dg.toggleItemIsActiveById('${id}')" ${vo.isEditable ? '' : 'disabled'} />
                            `

                            return t
                        },
                        'timeVerified': (v, k, r) => {
                            // console.log('kpCellRender timeVerified', v, k, r)

                            //id
                            let id = get(r, 'id', '')
                            // console.log('id', id, k, r)

                            //vv, vm
                            let vv = ''
                            let vm = vo.$t('userTimeEmpty')
                            if (istimemsTZ(v)) { //原始數據為timemsTZ格式
                                let vt = ot(v)
                                vv = vt.format('YYYY-MM-DDTHH:mm:ss.SSSZ')
                                vm = vt.format('YYYY-MM-DD HH:mm')
                            }
                            // console.log('vv', vv)
                            // console.log('vm', vm)

                            //isVerified
                            let isVerified = vo.$s.getIsVerified(r)

                            //h
                            let iconColor = isVerified ? 'green' : 'red'
                            let text = isVerified ? vo.$t('isVerifiedY') : vo.$t('isVerifiedN')
                            let h = `
                                <div style="width:90px; display:inline-flex; align-items:center; vertical-align:middle; color:${iconColor}; ">
                                    <i class="mdi ${isVerified ? 'mdi-check-bold' : 'mdi-close-thick'}"></i>
                                    <span style="padding-left:2px;">${text}</span>
                                </div>
                            `

                            let t = `
                                <div onclick="event.stopPropagation();event.preventDefault();" onmousedown="event.stopPropagation();event.preventDefault();" style="display:flex; align-items:center;">
                                    ${h}
                                    <button style="width:126px; min-width:126px;" onclick="$vo.$dg.modifyItemTimeVerifiedById(this,'${vv}','${id}')" ${vo.isEditable ? '' : 'disabled'}>${vm}</button>
                                </div>
                            `

                            return t
                        },
                        'timeExpired': (v, k, r) => {
                            // console.log('kpCellRender timeExpired', v, k, r)

                            //id
                            let id = get(r, 'id', '')
                            // console.log('id', id, k, r)

                            //vv, vm
                            let vv = ''
                            let vm = vo.$t('userTimeEmpty')
                            if (istimemsTZ(v)) { //原始數據為timemsTZ格式
                                let vt = ot(v)
                                vv = vt.format('YYYY-MM-DDTHH:mm:ss.SSSZ')
                                vm = vt.format('YYYY-MM-DD HH:mm')
                            }
                            // console.log('vv', vv)
                            // console.log('vm', vm)

                            //isExpired
                            let isExpired = vo.$s.getIsExpired(r)

                            //h
                            let iconColor = !isExpired ? 'green' : 'red'
                            let text = isExpired ? vo.$t('isExpiredY') : vo.$t('isExpiredN')
                            let h = `
                                <div style="width:90px; display:inline-flex; align-items:center; vertical-align:middle; color:${iconColor}; ">
                                    <i class="mdi ${!isExpired ? 'mdi-check-bold' : 'mdi-close-thick'}"></i>
                                    <span style="padding-left:2px;">${text}</span>
                                </div>
                            `

                            let t = `
                                <div onclick="event.stopPropagation();event.preventDefault();" onmousedown="event.stopPropagation();event.preventDefault();" style="display:flex; align-items:center;">
                                    ${h}
                                    <button style="width:126px; min-width:126px;" onclick="$vo.$dg.modifyItemTimeExpiredById(this,'${vv}','${id}')" ${vo.isEditable ? '' : 'disabled'}>${vm}</button>
                                </div>
                            `

                            return t
                        },
                        'timeBlocked': (v, k, r) => {
                            // console.log('kpCellRender timeBlocked', v, k, r)

                            //id
                            let id = get(r, 'id', '')
                            // console.log('id', id, k, r)

                            //vv, vm
                            let vv = ''
                            let vm = vo.$t('userTimeEmpty')
                            if (istimemsTZ(v)) { //原始數據為timemsTZ格式
                                let vt = ot(v)
                                vv = vt.format('YYYY-MM-DDTHH:mm:ss.SSSZ')
                                vm = vt.format('YYYY-MM-DD HH:mm')
                            }
                            // console.log('vv', vv)
                            // console.log('vm', vm)

                            //isBlocked
                            let isBlocked = vo.$s.getIsBlocked(r)

                            //h
                            let iconColor = !isBlocked ? 'green' : 'red'
                            let text = isBlocked ? vo.$t('isBlockedY') : vo.$t('isBlockedN')
                            let h = `
                                <div style="width:90px; display:inline-flex; align-items:center; vertical-align:middle; color:${iconColor}; ">
                                    <i class="mdi ${!isBlocked ? 'mdi-check-bold' : 'mdi-close-thick'}"></i>
                                    <span style="padding-left:2px;">${text}</span>
                                </div>
                            `

                            let t = `
                                <div onclick="event.stopPropagation();event.preventDefault();" onmousedown="event.stopPropagation();event.preventDefault();" style="display:flex; align-items:center;">
                                    ${h}
                                    <button style="width:126px; min-width:126px;" onclick="$vo.$dg.modifyItemTimeBlockedById(this,'${vv}','${id}')" ${vo.isEditable ? '' : 'disabled'}>${vm}</button>
                                </div>
                            `

                            return t
                        },
                    },
                    rowsChange: (rs) => {
                        // console.log('rowsChange', rs)
                        // console.log('rowsChange cloneDeep(vo.opt.rows)', cloneDeep(vo.opt.rows))

                        //isModified
                        vo.isModified = true

                    },
                    rowChecked: (rs) => {
                        // console.log('rowChecked', rs)
                        // console.log('rowChecked cloneDeep(vo.opt.rows)', cloneDeep(vo.opt.rows))

                        //save itemsCheck
                        vo.itemsCheck = cloneDeep(rs)

                    },
                }
                // console.log('opt', opt)

            }

            //save
            vo.opt = opt

        },

        refresh: function() {
            let vo = this

            //cmp
            let cmp = get(vo, '$refs.rftable.$refs.$self')
            // console.log('cmp', cmp)

            //refresh, 因set不會觸發kpCellRender, 故須另外調用組件函數refresh, 進而觸發kpCellRender, 使能更新數據
            cmp.refresh()

        },

        toggleTabKeys: function() {
            let vo = this

            //cmp
            let cmp = get(vo, '$refs.rftable.$refs.$self')
            // console.log('cmp', cmp)

            //showKeys
            cmp.showKeys(vo.tabKeysShow)
            // console.log('tabKeysShow', vo.tabKeysShow)

        },

        modifyItemPasswordById: function(id) {
            // console.log('modifyItemPasswordById', id)

            let vo = this

            vo.$alert(`尚待開發`, { type: 'error' }) //bbb

            // //k
            // let k = 'password'

            // //check
            // if (!isestr(id)) {
            //     vo.$alert(`${vo.$t('userEditNoUserId')}`, { type: 'error' })
            //     return
            // }

            // //rows
            // let rows = get(vo, 'opt.rows', [])

            // //find
            // let r = null
            // let kr = null
            // each(rows, (v, k) => {
            //     if (get(v, 'id', '') === id) {
            //         r = v
            //         kr = k
            //         return false //跳出
            //     }
            // })

            // //check
            // if (!iseobj(r)) {
            //     vo.$alert(`${vo.$t('userEditNoUserData')}`, { type: 'error' })
            //     return
            // }

            // //v
            // let _v = get(r, k, 'n')
            // let v = _v === 'y' ? 'n' : 'y'
            // // console.log(k, v)

            // //set
            // set(vo, `opt.rows[${kr}].${k}`, v)
            // // console.log('vo.opt.rows[kr]', cloneDeep(vo.opt.rows[kr]))

            // //refresh
            // vo.refresh()

            // //isModified
            // vo.isModified = true

        },

        toggleItemByKeyAndId: function(key, id) {
            // console.log('toggleItemByKeyAndId', key, id)

            let vo = this

            //check
            if (!isestr(id)) {
                vo.$alert(`${vo.$t('userEditNoUserId')}`, { type: 'error' })
                return
            }

            //rows
            let rows = get(vo, 'opt.rows', [])

            //find
            let r = null
            let kr = null
            each(rows, (v, k) => {
                if (get(v, 'id', '') === id) {
                    r = v
                    kr = k
                    return false //跳出
                }
            })

            //check
            if (!iseobj(r)) {
                vo.$alert(`${vo.$t('userEditNoUserData')}`, { type: 'error' })
                return
            }

            //v
            let _v = get(r, key, 'n')
            let v = _v === 'y' ? 'n' : 'y'
            // console.log(key, v)

            //set
            set(vo, `opt.rows[${kr}].${key}`, v)
            // console.log('vo.opt.rows[kr]', cloneDeep(vo.opt.rows[kr]))

            //refresh
            vo.refresh()

            //isModified
            vo.isModified = true

        },

        toggleItemIsAdminById: function(id) {
            // console.log('toggleItemIsAdminById', id)

            let vo = this

            //toggleItemByKeyAndId
            vo.toggleItemByKeyAndId('isAdmin', id)

        },

        toggleItemIsActiveById: function(id) {
            // console.log('toggleItemIsActiveById', id)

            let vo = this

            //toggleItemByKeyAndId
            vo.toggleItemByKeyAndId('isActive', id)

        },

        modifyItemByKeyAndId: function(key, ele, t, id) {
            // console.log('modifyItemTimeVerifiedById', ele, t, id)

            let vo = this

            //check
            if (!isestr(id)) {
                vo.$alert(`${vo.$t('userEditNoUserId')}`, { type: 'error' })
                return
            }

            //timePrev, 須給予秒時間, 要滿足istime才能展示初始值
            let timePrev = ''
            if (istimemsTZ(t)) {
                timePrev = ot(t).format('YYYY-MM-DDTHH:mm:ss')
            }
            // console.log('timePrev', timePrev)

            //domShowInputDatatime
            let type = 'datetime-local' //'datetime-local', 'date'
            domShowInputDatatime(timePrev, { eleRef: ele, type })
                .then((timeNew) => {
                    // console.log(k, 'timeNew', timeNew)

                    //rows
                    let rows = get(vo, 'opt.rows', [])

                    //find
                    let r = null
                    let kr = null
                    each(rows, (v, k) => {
                        if (get(v, 'id', '') === id) {
                            r = v
                            kr = k
                            return false //跳出
                        }
                    })

                    //check
                    if (!iseobj(r)) {
                        vo.$alert(`${vo.$t('userEditNoUserData')}`, { type: 'error' })
                        return
                    }

                    //v
                    let vt = ot(timeNew, 'YYYY-MM-DDTHH:mm') //domShowInputDatatime數據為年月日時分
                    let v = vt.format('YYYY-MM-DDTHH:mm:ss.SSSZ') //轉回原始數據為timemsTZ格式
                    // console.log('v', v)

                    //set
                    set(vo, `opt.rows[${kr}].${key}`, v)
                    // console.log('vo.opt.rows[kr]', cloneDeep(vo.opt.rows[kr]))

                    //refresh
                    vo.refresh()

                    //isModified
                    vo.isModified = true

                })

        },

        modifyItemTimeVerifiedById: function(ele, t, id) {
            // console.log('modifyItemTimeVerifiedById', ele, t, id)

            let vo = this

            //modifyItemByKeyAndId
            vo.modifyItemByKeyAndId('timeVerified', ele, t, id)

        },

        modifyItemTimeExpiredById: function(ele, t, id) {
            // console.log('modifyItemTimeExpiredById', ele, t, id)

            let vo = this

            //modifyItemByKeyAndId
            vo.modifyItemByKeyAndId('timeExpired', ele, t, id)

        },

        modifyItemTimeBlockedById: function(ele, t, id) {
            // console.log('modifyItemTimeBlockedById', ele, t, id)

            let vo = this

            //modifyItemByKeyAndId
            vo.modifyItemByKeyAndId('timeBlocked', ele, t, id)

        },

        addItem: function() {
            // console.log('method addItem')

            let vo = this

            //cloneDeep
            let rows = get(vo, 'opt.rows', [])

            //cloneDeep
            rows = cloneDeep(rows)

            //r
            let r = vo.$ds.users.funNew()
            r.name = vo.$s.getNameNew(rows, 'name', '', vo.$t('userAddNameNew'))
            r.userId = `{${vo.$t('userAddIdNew')}}`
            r.timeCreate = `{${vo.$t('userAddIdNew')}}`
            r.userIdUpdate = `{${vo.$t('userAddIdNew')}}`
            r.timeUpdate = `{${vo.$t('userAddIdNew')}}`
            // console.log('r', r)

            //添加至最首
            rows = [
                r,
                ...rows,
            ]

            //save
            vo.users = cloneDeep(rows) //直接更新由getUsersList取得的users, 連帶驅動computed重算, 故不用另外更新vo.items與vo.opt.rows
            // console.log('cloneDeep(vo.users)', cloneDeep(vo.users))

            //isModified
            vo.isModified = true

        },

        copyItem: function() {
            // console.log('method copyItem')

            let vo = this

            //check
            if (size(vo.itemsCheck) !== 1) {
                console.log(`size(vo.itemsCheck) !== 1`, vo.itemsCheck)
                vo.$alert(`${vo.$t('anUnexpectedErrorOccurred')}`, { type: 'error' })
                return
            }

            //cloneDeep
            let rows = get(vo, 'opt.rows', [])

            //cloneDeep
            rows = cloneDeep(rows)

            //find
            let tar = vo.itemsCheck[0]
            let tarId = get(tar, 'data.id', '')
            let row = null
            each(rows, (v) => {
                let id = get(v, 'id', '')
                if (id === tarId) {
                    row = v
                    return false //跳出
                }
            })
            // console.log('tar', tar)
            // console.log('row', row)

            //check
            if (!iseobj(row)) {
                console.log(`!iseobj(row)`, row)
                vo.$alert(`${vo.$t('anUnexpectedErrorOccurred')}`, { type: 'error' })
                return
            }

            //r
            let r = cloneDeep(row)
            // let nameOld = r.name
            let _r = vo.$ds.users.funNew()
            r.id = _r.id //使用新建方式預先產生id避免重複
            // r.name = vo.$s.getNameNew(rows, 'name', nameOld, vo.$t('userCopyNameNew'))
            r.userId = `{${vo.$t('userAddIdNew')}}`
            r.timeCreate = `{${vo.$t('userAddIdNew')}}`
            r.userIdUpdate = `{${vo.$t('userAddIdNew')}}`
            r.timeUpdate = `{${vo.$t('userAddIdNew')}}`
            // console.log('r', r)

            //添加至最首
            rows = [
                r,
                ...rows,
            ]

            //save
            vo.users = cloneDeep(rows) //直接更新由getUsersList取得的users, 連帶驅動computed重算, 故不用另外更新vo.items與vo.opt.rows
            // console.log('cloneDeep(vo.users)', cloneDeep(vo.users))

            //isModified
            vo.isModified = true

        },

        deleteItemsCheck: function() {
            // console.log('method deleteItemsCheck')

            let vo = this

            //check
            if (size(vo.itemsCheck) === 0) {
                console.log(`size(vo.itemsCheck) === 0`, vo.itemsCheck)
                vo.$alert(`${vo.$t('anUnexpectedErrorOccurred')}`, { type: 'error' })
                return
            }

            //cloneDeep
            let rows = get(vo, 'opt.rows', [])

            //cloneDeep
            rows = cloneDeep(rows)

            //filter
            each(vo.itemsCheck, (v) => {
                // console.log('v', v)
                let id = get(v, 'data.id', '')
                if (!isestr(id)) {
                    console.log(`invalid id`)
                    return true //跳出換下一個
                }
                rows = filter(rows, (vv) => {
                    return vv.id !== id
                })
            })

            //clear
            vo.itemsCheck = []

            //save
            vo.users = cloneDeep(rows) //直接更新由getUsersList取得的users, 連帶驅動computed重算, 故不用另外更新vo.items與vo.opt.rows
            // console.log('cloneDeep(vo.users)', cloneDeep(vo.users))

            //isModified
            vo.isModified = true

        },

        saveUsers: function() {
            // console.log('method saveUsers')

            let vo = this

            async function core() {
                let errTemp = null

                //show loading
                vo.$ui.updateLoading(true)

                //check
                if (isestr(vo.isError)) {
                    vo.$alert(`${vo.isError}`, { type: 'error' })
                    return
                }

                //rows
                let rows = get(vo, 'opt.rows', [])

                //check
                if (size(rows) === 0) {
                    vo.$alert(`${vo.$t('userAddEmpty')}`, { type: 'error' })
                    return
                }

                //token
                let token = vo.userToken
                // console.log('token', token)

                //updateUsersList
                await vo.$fapi.updateUsersList(token, rows)
                    .catch((err) => {
                        errTemp = err
                    })

                //check
                if (errTemp !== null) {
                    vo.$alert(`${vo.$t('userSaveUsersFail')}: ${errTemp}`, { type: 'error' })
                    return
                }

                //isModified
                vo.isModified = false

                //alert
                vo.$alert(vo.$t('userSaveUsersSuccess'))

            }

            //core
            core()
                // .then((res) => {
                //     console.log('then', res)
                // })
                .catch((err) => {
                    console.log('catch', err)
                    vo.$alert(vo.$t('anUnexpectedErrorOccurred'), { type: 'error' })
                })
                .finally(() => {

                    //hide loading
                    vo.$ui.updateLoading(false)

                })

        },

    }
}
</script>

<style scoped>
</style>
