
import { CardTempaleBean, DelCardTempaleBean } from "./CardTempaleModel"
import { logger } from "mslib";
import { TyExternalApiClient, generateTySqlApiClient } from "../refs/nslib"
import { Singleton, Inject } from "typescript-ioc";
import * as dayjs from "dayjs";
import { v4 as uuidv4 } from 'uuid';

/**
 * 
 * @date 2023-05-10 11:13:01
 * @author 郁忠彪
 */
class CardTempaleServerse {

    @Inject
    tyExternalApiClient: TyExternalApiClient

    //操作人姓名
    userName = '非标'

    // 操作人id
    userId = "0";

    // 区域id,默认全部
    areaId = ['-1'];

    // 默认1
    lotCount = 1;

    // 支付渠道 默认其他
    payChannel = 1000;

    // 充值方式,(0 钱(单位:分),1 月,2 天,3 小时,4次，5 时间,默认按天充值
    chargeMethod = 2;

    // 充值车的充值月数或天数或次数或金额，默认0
    chargeNumber = 0;

    // 支付金额（单位：分），默认0
    amount = 0;

    // 免费赠送的月数或天数或次数，默认0
    freeNumber = 0;

    /**
     * 新增或者修改内部车
     * @param parameters
     */
    async addOrUpCarCardNo(param: CardTempaleBean) {
        try {
            logger.info(`内部车操作请求参数：` + JSON.stringify(param))

            let { useName, carType, carList, areaId, lotCount, validFrom, validTo, id, parkId, } = param
            areaId = areaId ? areaId : this.areaId
            lotCount = lotCount ? lotCount : this.lotCount
            // 必填项字段定义
            let mustFields = {
                // "useName": "户主名",
                "carType": "车牌类型",
                "carList": "车牌列表",
                "parkId": "车场id",
            }
            let checkRes = await this.paramsIsNullCheck(param, mustFields)
            if (checkRes) {
                return this.resModeInfo(-1, checkRes, null)
            }
            // 时间检验
            if (validFrom && validTo) {
                if (dayjs(validTo).valueOf() <= dayjs().valueOf()) {
                    return this.resModeInfo(-1, '有效期结束时间不能小于当前', null)
                }
                if (dayjs(validTo).valueOf() <= dayjs(validFrom).valueOf()) {
                    return this.resModeInfo(-1, '有效期结束时间不能小于开始时间', null)
                }
            }

            let upData: any = {
                parkId,
                userId: this.userId,
                userName: this.userName,
                cardInfo: JSON.stringify({
                    cardName: useName,
                    useName,
                    remak: id ? id.toString() : ''//将第三方id保存到备注用于处理删除
                }),
                carLotList: [],
                plateNoInfo: []
            }



            // 判断是否已经存在
            let carInfoRes
            for (let carInfo of carList) {
                carInfoRes = await this.tyExternalApiClient.getCarCardInfo({ parkId: parkId, plateNo: carInfo.plateNo, state: 0 });
                if (carInfoRes) {
                    // 维护id得唯一性
                    if (id && carInfoRes.remak != id) {
                        return this.resModeInfo(-1, '和已存在id不匹配', null)
                    }
                    let upcardInfo = {
                        cardId: carInfoRes.cardId,//卡牌id
                        useName: useName ? useName : carInfoRes.useName,//用户名
                        cardName: useName ? useName : carInfoRes.useName,//卡片名，目前发现这个字段可能是保留字段 
                        remak: id ? id : ''//将第三方id保存到备注用于处理删除
                    }
                    upData.cardInfo = JSON.stringify(upcardInfo)

                    let addPlateNoInfo = []
                    // 筛选需要新增得数据
                    for (let ow of carList) {
                        addPlateNoInfo.push({ plateNo: ow.plateNo })
                        for (let on of JSON.parse(carInfoRes.plateNoInfo)) {
                            if (ow.plateNo == on.plateNo) {

                                let index = addPlateNoInfo.findIndex(item => item.plateNo == ow.plateNo);
                                if (index > -1) {
                                    // 将已经存在得弹出，不存在得新增
                                    addPlateNoInfo.splice(index, 1);
                                }
                                break
                            }
                        }
                    }

                    let delPlateNoInfo = []
                    // 筛选需要删除得数据
                    for (let ow of JSON.parse(carInfoRes.plateNoInfo)) {
                        delPlateNoInfo.push({ id: ow.id })

                        for (let on of carList) {
                            if (on.plateNo == ow.plateNo) {
                                let index = delPlateNoInfo.findIndex(item => item.id == ow.id);
                                if (index > -1) {
                                    // 将已经存在得弹出，不存在得删除
                                    delPlateNoInfo.splice(index, 1);
                                }
                                break
                            }

                        }
                    }

                    let plateNoInfo = [...delPlateNoInfo, ...addPlateNoInfo]
                    if (plateNoInfo.length > 0) {
                        upData.plateNoInfo = JSON.stringify(plateNoInfo)
                        upData.carLotList = JSON.stringify(upData.carLotList)
                        let upRes = await this.tyExternalApiClient.modifyCarCardNo(upData);
                        if (+upRes.resCode != 0) {
                            return upRes
                        }
                        if (validFrom && validTo) {
                            logger.info(dayjs(validTo).valueOf())
                            logger.info(dayjs(carInfoRes.carLotList[0].endTime).valueOf())
                            if (carInfoRes.carLotList[0].endTime && dayjs(validTo).valueOf() > dayjs(carInfoRes.carLotList[0].endTime).valueOf()) {
                                // 内部车充值
                                // 参数 validFrom充值开始时间 validTo充值开结束时间  carType车牌类型 cardId卡片id
                                return await this.payCarCardFee(validFrom, validTo, carType, carInfoRes.cardId, parkId);
                            }
                        }

                    }

                    return this.resModeInfo(0, '成功', null)
                }


            }

            // 新增操作
            if (!carInfoRes && carList.length > 0) {

                if (!useName) {
                    logger.info(`新增内部车用户名必传`)
                    return this.resModeInfo(-1, '新增内部车用户名必传', null)
                }
                let sqlApiClient = generateTySqlApiClient(parkId);
                if (id) {
                    let cardIdInfo = await sqlApiClient.selectOne(`SELECT id FROM  t_${parkId}_card WHERE  remark='${id}'`)
                    if (cardIdInfo) {
                        return this.resModeInfo(-1, 'id以存在', null)
                    }
                }

                upData.carLotList.push(

                    {
                        carType,
                        areaId: areaId,
                        lotCount: lotCount,
                        lotName: ""
                    }

                )
                upData.carLotList = JSON.stringify(upData.carLotList)
                upData.plateNoInfo = JSON.stringify(carList)
                let addRes = await this.tyExternalApiClient.addCarCardNo(upData);
                if (+addRes.resCode != 0) {
                    return addRes
                }

                // 内部车充值
                if (validFrom && validTo) {

                    // 参数 validFrom充值开始时间 validTo充值开结束时间  carType车牌类型 cardId卡片id
                    let payRes = await this.payCarCardFee(validFrom, validTo, carType, JSON.parse(addRes.data).cardId, parkId);
                    return payRes

                }
                return this.resModeInfo(0, '成功', JSON.parse(addRes.data).cardId)
            }

        } catch (e) {
            logger.info(`内部车操作异常：` + e)
            return this.resModeInfo(-1, '内部车操作异常', null)
        }

    }


    /**
         * 
         * 内部车删除
         */
    async delCarCardNo(param: DelCardTempaleBean) {

        logger.info(`内部车删除请求参数：` + JSON.stringify(param))
        try {

            let { carList, source, id, parkId } = param
            if (!carList && carList.length == 0 && !id) {
                return this.resModeInfo(-1, '车牌列表和卡片id不能同时为空', null)
            }
            let delRes
            if (id) {
                // 根据科拓卡片id
                if (source == 1) {
                    delRes = await this.tyExternalApiClient.delCarCardInfo({ parkId, cardId: id });
                    return delRes
                } else {
                    // 根据第三方id，查询科拓卡片id
                    let sqlApiClient = generateTySqlApiClient(parkId);
                    let cardIdInfo = await sqlApiClient.selectOne(`SELECT id FROM  t_${parkId}_card WHERE  remark='${id}'`)
                    if (!cardIdInfo) {
                        return this.resModeInfo(-1, '未匹配到内部车信息', null)
                    }
                    delRes = await this.tyExternalApiClient.delCarCardInfo({ parkId, cardId: cardIdInfo.id });
                    return delRes
                }

            } else {
                let upData: any = {
                    parkId,
                    userId: this.userId,
                    userName: this.userName,
                    cardInfo: {},
                    carLotList: [],
                    plateNoInfo: []
                }
                // 根据车牌删除
                let carInfoRes
                for (let plateNo of carList) {
                    carInfoRes = await this.tyExternalApiClient.getCarCardInfo({ parkId: parkId, plateNo: plateNo, state: 0 });
                    if (carInfoRes) {
                        break
                    }
                }
                // 如果卡牌名下只有一个车辆，将整个卡牌删除

                if (JSON.parse(carInfoRes.carLotList).length == 1) {
                    return await this.tyExternalApiClient.delCarCardInfo({ parkId: parkId, cardId: carInfoRes.cardId });
                }
                if (carInfoRes) {
                    let upcardInfo = {
                        cardId: carInfoRes.cardId,// 卡牌id
                        useName: carInfoRes.useName,// 用户名
                        cardName: carInfoRes.cardName,// 卡片名
                    }
                    upData.cardInfo = JSON.stringify(upcardInfo)
                    let delPlateNoInfo = []
                    // 筛选需要删除得数据
                    for (let ow of JSON.parse(carInfoRes.plateNoInfo)) {

                        for (let on of carList) {
                            if (on == ow.plateNo) {
                                delPlateNoInfo.push({ id: ow.id })
                                break
                            }

                        }
                    }

                    if (delPlateNoInfo.length > 0) {
                        upData.plateNoInfo = JSON.stringify(delPlateNoInfo)
                        let upRes = await this.tyExternalApiClient.modifyCarCardNo(upData);
                        if (+upRes.resCode != 0) {
                            return upRes
                        }
                        return this.resModeInfo(0, '成功', null)
                    }

                }
                return this.resModeInfo(0, '成功', null)
            }

        } catch (e) {
            return this.resModeInfo(-1, '异常：' + e, null)
        }



    }

    /**
          * 内部车充值
          * @param  参数 validFrom充值开始时间 validTo充值开结束时间  carType车牌类型 cardId卡片id
          */
    async payCarCardFee(validFrom, validTo, carType, cardId, parkId) {

        let payData = {
            parkId,
            userId: this.userId,
            userName: this.userName,
            cardId: cardId,
            orderNo: uuidv4(),
            carType,
            payChannel: this.payChannel,
            chargeMethod: this.chargeMethod,
            chargeNumber: this.chargeNumber,
            amount: this.amount,
            freeNumber: this.freeNumber,
            validFrom,
            validTo,
            createTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
            remark: ''
        }

        let payRes = await this.tyExternalApiClient.payCarCardFee(payData);
        return payRes
    }

    /**
        * 验证参数是否为空
        * @param data 参数
        * @param mustFields 需要验证的参数集合 string,number,object,bigint,boolean,symbol,undefined,function
        */
    paramsIsNullCheck(data, mustFields) {
        for (let item in mustFields) {
            let text = mustFields[item];
            let val = data[item];
            let type = typeof (val);
            switch (type) {
                case 'string':
                    if (val == null || val == '' || !val.length) {
                        return text + "为必填项！";
                    }
                    break;
                case 'number':
                    if (Object.is(val, NaN)) {
                        return text + "为必填项！";
                    }
                    break;
                case 'object':
                    if (val == null || !val.length) {
                        return text + "为必填项！";
                    }

                    break;
                default:
                    if (val == null) {
                        return text + "为必填项！";
                    }
                    break;
            }
        }
        return "";
    }

    resModeInfo(resCode, resMsg, date) {
        logger.info(resMsg)
        return { resCode, resMsg, date }
    }
}


export { CardTempaleServerse }