package com.yeejoin.amos.boot.module.common.biz.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yeejoin.amos.boot.biz.common.utils.DateUtils;
import com.yeejoin.amos.boot.module.common.api.dto.DutyCarDto;
import com.yeejoin.amos.boot.module.common.api.entity.DutyPersonShift;
import com.yeejoin.amos.boot.module.common.api.entity.DynamicFormColumn;
import com.yeejoin.amos.boot.module.common.api.entity.DynamicFormInstance;
import com.yeejoin.amos.boot.module.common.api.entity.Firefighters;
import com.yeejoin.amos.boot.module.common.api.feign.EquipFeignClient;
import com.yeejoin.amos.boot.module.common.api.mapper.FirefightersMapper;
import com.yeejoin.amos.boot.module.common.api.service.IDutyCarService;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.foundation.utils.Bean;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author DELL
 */
@Service
public class DutyCarServiceImpl extends DutyCommonServiceImpl implements IDutyCarService {

    @Autowired
    DynamicFormInstanceServiceImpl dynamicFormInstanceService;

    @Autowired
    FirefightersMapper firefightersMapper;

    @Autowired
    EquipFeignClient equipFeignClient;

    String driverPostTypeCode = "5";

    @Autowired
    EquipFeignClient equipFeign;

    @Override
    public String getGroupCode() {
        return "dutyCar";
    }

    @Override
    public DutyCarDto save(DutyCarDto dutyCarDto) {
        // BUG 2807 更新人员车辆排版值班的保存逻辑 如果没有填写数据则保存空数据 。 同步修改 查询 导出相关逻辑 by kongfm 2021-09-14
        //1.保存行数据
        String groupCode = this.getGroupCode();
        String userId = dutyCarDto.getUserId();
        List<DynamicFormInstance> instances = dynamicFormInstanceService
                .list(new LambdaQueryWrapper<DynamicFormInstance>().eq(DynamicFormInstance::getFieldCode, "userId")
                        .eq(DynamicFormInstance::getFieldValue, userId)
                        .eq(DynamicFormInstance::getGroupCode, this.getGroupCode()));
        Long instanceId = null;

        if(StringUtils.isNotEmpty(dutyCarDto.getDutyAreaId())) {
            // 根据建筑id 查找建筑
            ResponseModel<Map<String, Object>> response = null;
            try {
                response = equipFeign.getFormInstanceById(Long.parseLong(dutyCarDto.getDutyAreaId()));
            } catch (NumberFormatException e) {
                throw new BadRequest("值班区域id异常！");
            }
            Map<String, Object> result = response.getResult();
            dutyCarDto.setDutyArea(result.get("name").toString());
        }
        Map<String, Object> map = Bean.BeantoMap(dutyCarDto);
        if (!instances.isEmpty()) {
            // 0.定位instanceId，准备进行更新操作
            instanceId = instances.get(0).getInstanceId(); // 已经有了走更新方法
            //1.查询已有数据
            List<DynamicFormInstance> hasInstances = dynamicFormInstanceService.list(new LambdaQueryWrapper<DynamicFormInstance>().eq(DynamicFormInstance::getInstanceId, instanceId));
            //2.list 转 map
            Map<Object, DynamicFormInstance> instanceMap = Bean.listToMap(hasInstances, "fieldCode", DynamicFormInstance.class);
            //3.查询列数据，已列为主
            List<DynamicFormColumn> columns = dynamicFormColumnService.list(new LambdaQueryWrapper<DynamicFormColumn>().eq(DynamicFormColumn::getGroupCode, groupCode));
            //4.已列为主 填充动态表单数据
            List<DynamicFormInstance> entrys = new ArrayList<>();
            for (DynamicFormColumn column : columns) {
                DynamicFormInstance formInstance = instanceMap.get(column.getFieldCode());
                if (!ObjectUtils.isEmpty(formInstance)) {
                    //有的更新
                    formInstance.setFieldValue(map.get(column.getFieldCode()) != null ? map.get(column.getFieldCode()).toString() : "");
                } else {
                    //没有的新增
                    formInstance = new DynamicFormInstance();
                    buildFormInstanceData(instanceId, map, column, formInstance);
                }
                entrys.add(formInstance);
            }
            if(!entrys.isEmpty()){
                dynamicFormInstanceService.saveOrUpdateBatch(entrys);
            }

        } else {
            instanceId =  dynamicFormInstanceService.commonSave(groupCode,map);
        }

        if(dutyCarDto.getDutyShift() != null && dutyCarDto.getDutyShift().size() == 0) {
            Calendar startDate = Calendar.getInstance();
            startDate.setTime(DateUtils.longStr2Date(dutyCarDto.getStartTime()));
            int dates = startDate.getActualMaximum(Calendar.DAY_OF_MONTH);
            startDate.set(Calendar.DAY_OF_MONTH, 1);
            List<DutyPersonShift> dutyShift = new ArrayList<>(dates);
            for (int i = 0 ; i < dates ; i ++) {
                DutyPersonShift temp = new DutyPersonShift();
                temp.setAppKey(RequestContext.getAppKey());
                temp.setDutyDate(startDate.getTime());
                temp.setIsDelete(false);
                temp.setInstanceId(instanceId);
                dutyShift.add(temp);
                startDate.add(Calendar.DAY_OF_YEAR,1);
            }
            dutyPersonShiftService.saveOrUpdateBatch(dutyShift);
        }

        //2.保存值班信息
        insertPersonShift(instanceId, dutyCarDto);
        //3.返回保存后的数据
        return dutyCarDto;


    }

    @Override
    public DutyCarDto update(Long instanceId, DutyCarDto dutyCarDto) {
        String groupCode = this.getGroupCode();
        //1.查询已有数据
        List<DynamicFormInstance> instances = dynamicFormInstanceService.list(new LambdaQueryWrapper<DynamicFormInstance>().eq(DynamicFormInstance::getInstanceId, instanceId));
        //2.list 转 map
        Map<Object, DynamicFormInstance> instanceMap = Bean.listToMap(instances, "fieldCode", DynamicFormInstance.class);
        //3.查询列数据，已列为主
        List<DynamicFormColumn> columns = dynamicFormColumnService.list(new LambdaQueryWrapper<DynamicFormColumn>().eq(DynamicFormColumn::getGroupCode, groupCode));
        //页面数据转Map
        Map<String, Object> map = Bean.BeantoMap(dutyCarDto);
        //4.已列为主 填充动态表单数据
        List<DynamicFormInstance> entrys = new ArrayList<>();
        updateFormValue(entrys, map, instanceId, columns, instanceMap);
        if (!entrys.isEmpty()) {
            dynamicFormInstanceService.saveOrUpdateBatch(entrys);
        }
        //5.更新值班信息人日期数据
        insertPersonShift(instanceId, dutyCarDto);
        return dutyCarDto;
    }

    private void insertPersonShift(Long instanceId, DutyCarDto dutyCarDto) {
        Set<DutyPersonShift> personShiftList = dutyCarDto.getDutyShift().stream().map(dto -> {
            // BUG 2807 修改时发现BUG 车辆保存有问题 by kongfm 2021-09-14
            // 根据instanceId 和 日期查找 如果有则更新
            DutyPersonShift dutyPersonShift = dutyPersonShiftService.getOne(new LambdaQueryWrapper<DutyPersonShift>().eq(DutyPersonShift::getInstanceId,instanceId).eq(DutyPersonShift::getDutyDate,dto.getDutyDate()));
            if(dutyPersonShift == null) {
                dutyPersonShift = new DutyPersonShift();
            }
            dto.setInstanceId(instanceId);
            Bean.copyExistPropertis(dto, dutyPersonShift);
            dutyPersonShift.setAppKey(RequestContext.getAppKey());
            return dutyPersonShift;
        }).collect(Collectors.toSet());
        if (!personShiftList.isEmpty()) {
            dutyPersonShiftService.saveOrUpdateBatch(personShiftList);
        }
    }

    private void buildFormInstanceData(Long instanceId, Map<String, Object> map, DynamicFormColumn column, DynamicFormInstance formInstance) {
        fillFormInstanceData(instanceId, map, column, formInstance, sequence.nextId());
    }

    @Override
    public JSONObject isFireCarDriver() {
        JSONObject result = new JSONObject();
        result.put("isDriver", false);
        result.put("carStatus", "");
        result.put("carId", "");

        String loginUserId = RequestContext.getExeUserId();
        // 根据登陆人id查询对应消防人员
        Firefighters firefighters =
                firefightersMapper.selectOne(new LambdaQueryWrapper<Firefighters>().eq(Firefighters::getSystemAccount,
                loginUserId));
        if (ValidationUtil.isEmpty(firefighters)) {
            return result;
        }
        // 消防人员id
        Long fighterId = firefighters.getSequenceNbr();

        // 当前值班班次id
        List<Long> shiftIdList = getDutyShiftIdList();
        if (ValidationUtil.isEmpty(shiftIdList)) {
            return result;
        }
        // 当前值班人员-车辆信息
        List<Map<String, Object>> personList = dayDutyPersonList(DateUtils.getDateNowShortStr(), shiftIdList.get(0),
                driverPostTypeCode);
        if (ValidationUtil.isEmpty(personList)) {
            return result;
        }

        personList = personList.stream().filter(m -> fighterId.equals(m.get("userId"))).collect(Collectors.toList());
        if (ValidationUtil.isEmpty(personList)) {
            return result;
        }

        result.put("isDriver", true);
        result.put("carId", personList.get(0).get("carId"));

        ResponseModel<Map<String, Object>> resultModel =
                equipFeignClient.queryCarSimpleInfoById((Long) personList.get(0).get("carId"));
        Map<String, Object> carInfo = resultModel.getResult();
        result.put("carStatus", carInfo.get("carStatus"));
        return result;
    }
}
