package com.malk.huagao.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.malk.huagao.entity.YdNonProdPrice;
import com.malk.huagao.entity.YdProdWorkHoursPrice;
import com.malk.huagao.entity.YdUserInput;
import com.malk.huagao.mapper.YdNonProdPriceMapper;
import com.malk.huagao.mapper.YdProdWorkHoursPriceMapper;
import com.malk.huagao.mapper.YdUserInputMapper;
import com.malk.huagao.service.HuaGaoService;
import com.malk.server.aliwork.YDConf;
import com.malk.server.aliwork.YDParam;
import com.malk.server.common.McException;
import com.malk.server.dingtalk.DDR;
import com.malk.server.dingtalk.DDR_New;
import com.malk.service.aliwork.YDClient;
import com.malk.service.aliwork.YDService;
import com.malk.service.dingtalk.*;
import com.malk.service.fxiaoke.FXKClient;
import com.malk.utils.UtilDateTime;
import com.malk.utils.UtilHttp;
import com.malk.utils.UtilMap;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

@Slf4j
@Service
public class HuaGaoServiceImpl implements HuaGaoService {
    @Autowired
    private YDService ydService;

    @Autowired
    private YDClient ydClient;

    @Autowired
    private DDClient_Contacts ddClient_contacts;

    @Autowired
    private DDClient_Attendance ddClientAttendance;

    @Autowired
    private DDClient ddClient;

    @Autowired
    private DDClient_Workflow ddClient_workflow;

    @Autowired
    private YdUserInputMapper ydUserInputMapper;

    @Autowired
    private YdNonProdPriceMapper ydNonProdPriceMapper;

    @Autowired
    private YdProdWorkHoursPriceMapper ydProdWorkHoursPriceMapper;

    @Override
    public void syncKqData(LocalDateTime startTime, LocalDateTime endTime) {
        MDC.put("MDC_KEY_PID","1001");

        String stTime=UtilDateTime.formatLocal(startTime,UtilDateTime.DATE_TIME_PATTERN);
        String edTime=UtilDateTime.formatLocal(endTime,UtilDateTime.DATE_TIME_PATTERN);
        List<Map> list=ydService.queryAllFormData(YDParam.builder().formUuid("FORM-5061F7AE543B429C8241EC730A6F31653NNK").build());
        for(Map map:list){
            Map formData= UtilMap.getMap(map,"formData");
            String deptId=String.valueOf(UtilMap.getList(formData,"departmentSelectField_m8e4zaju_id").get(0));
            String price=UtilMap.getString(formData,"numberField_m8e4zajw_value");
            List<String> users=ddClient_contacts.listDepartmentUserId(ddClient.getAccessToken(),Long.parseLong(deptId));
            for (String user : users) {
                List<Map> valList=ddClientAttendance.getAttColumnVal(ddClient.getAccessToken(),user, Arrays.asList("82772106","89349019","82772125"),stTime,edTime);
                if(valList!=null&&valList.size()==3){
                    Map<String,Map<String,String>> dateMap=toDateMap(valList);
                    for (String date:dateMap.keySet()) {
                        Map<String,String> dataMap=dateMap.get(date);
                        String workTime="休息".equals(dataMap.get("82772125"))?
                                dataMap.get("89349019"): NumberUtil.add(dataMap.get("89349019"),dataMap.get("82772106")).toString();

                        //查询用户详情
                        String userName = "";

                        LambdaQueryWrapper<YdUserInput> ydUserInputLambdaQueryWrapper2 = new LambdaQueryWrapper<>();
                        ydUserInputLambdaQueryWrapper2.eq(YdUserInput::getUserId,user)
                                .isNotNull(YdUserInput::getUserName);

                        Page<YdUserInput> page = new Page<>(1, 1);
                        IPage<YdUserInput> result = ydUserInputMapper.selectPage(page, ydUserInputLambdaQueryWrapper2);

                        YdUserInput ydUserInput2 = result.getRecords().isEmpty() ? null : result.getRecords().get(0);

                        if (Objects.nonNull(ydUserInput2)){
                            userName = ydUserInput2.getUserName();
                        }else {
                            DDR_New ddrNew1 = (DDR_New) UtilHttp.doPost("https://oapi.dingtalk.com/topapi/v2/user/get", null, ddClient.initTokenParams(), UtilMap.map("userid", user), DDR_New.class);
                            Map result1 = (Map) ddrNew1.getResult();
                            userName = UtilMap.getString(result1, "name");
                        }

                        log.info("user：{},userName:{},date：{},workTime：{},price：{}",user,userName,date,workTime,price);

                        saveData(user,date,workTime,price);

                        //同步到数据库
                        LambdaQueryWrapper<YdUserInput> ydUserInputLambdaQueryWrapper = new LambdaQueryWrapper<>();
                        ydUserInputLambdaQueryWrapper.eq(YdUserInput::getUserId,user)
                                .eq(YdUserInput::getDate, date);

                        YdUserInput ydUserInput = ydUserInputMapper.selectOne(ydUserInputLambdaQueryWrapper);

                        if (Objects.nonNull(ydUserInput)){
                            ydUserInput.setUserName(userName);
                            ydUserInput.setWorkHours(workTime);
                            ydUserInput.setPrice(price);
                            ydUserInput.setTotalPrice(NumberUtil.mul(workTime,price));

                            ydUserInputMapper.update(ydUserInput,ydUserInputLambdaQueryWrapper);
                        }else {
                            try {
                                ydUserInput = new YdUserInput();
                                ydUserInput.setUserId(user);
                                ydUserInput.setUserName(userName);
                                SimpleDateFormat formatter = new SimpleDateFormat(UtilDateTime.DATE_TIME_PATTERN);
                                ydUserInput.setDate(formatter.parse(date));
                                ydUserInput.setWorkHours(workTime);
                                ydUserInput.setPrice(price);
                                ydUserInput.setTotalPrice(NumberUtil.mul(workTime,price));

                                ydUserInputMapper.insert(ydUserInput);
                            }catch (ParseException e){
                                log.info("无法解析日期字符串: {}",e.getMessage());
                            }
                        }
                    }
                }
            }
        }
    }

    @Override
    public void upsertNonProdPrice(Map map) {
        MDC.put("MDC_KEY_PID","1001");

        String formInstId = UtilMap.getString(map, "formInstId");

        Map formData = ydClient.queryData(YDParam.builder()
                .formInstId(formInstId)
                .build(), YDConf.FORM_QUERY.retrieve_id).getFormData();

        String type = UtilMap.getString(formData, "textField_m8fljzks");
        String form = UtilMap.getString(formData, "textField_m8fljzkt");
        String position = UtilMap.getString(formData, "textField_m8fljzku");
        String materialCodeLeft = UtilMap.getString(formData, "textField_m8fljzkv");
        String price = UtilMap.getString(formData, "numberField_m8fljzkw");

        LambdaQueryWrapper<YdNonProdPrice> ydNonProdPriceLambdaQueryWrapper = new LambdaQueryWrapper<>();
        ydNonProdPriceLambdaQueryWrapper.eq(YdNonProdPrice::getType,type)
                .eq(YdNonProdPrice::getForm,form)
                .eq(YdNonProdPrice::getPosition,position)
                .eq(YdNonProdPrice::getMaterialCodeLeft,materialCodeLeft);

        YdNonProdPrice ydNonProdPrice = ydNonProdPriceMapper.selectOne(ydNonProdPriceLambdaQueryWrapper);
        if (Objects.nonNull(ydNonProdPrice)){
            ydNonProdPrice.setPrice(price);

            ydNonProdPriceMapper.update(ydNonProdPrice,ydNonProdPriceLambdaQueryWrapper);
        }else {
            ydNonProdPrice = new YdNonProdPrice();
            ydNonProdPrice.setType(type);
            ydNonProdPrice.setForm(form);
            ydNonProdPrice.setPosition(position);
            ydNonProdPrice.setMaterialCodeLeft(materialCodeLeft);
            ydNonProdPrice.setPrice(price);

            ydNonProdPriceMapper.insert(ydNonProdPrice);
        }
    }

    @Override
    public void upsertWorkHoursPrice(Map map) {
        MDC.put("MDC_KEY_PID","1001");

        String formInstId = UtilMap.getString(map, "formInstId");

        Map formData = ydClient.queryData(YDParam.builder()
                .formInstId(formInstId)
                .build(), YDConf.FORM_QUERY.retrieve_id).getFormData();

        String type = UtilMap.getString(formData, "selectField_m8zib4co");
        String price = UtilMap.getString(formData, "numberField_m8zib4cp");

        LambdaQueryWrapper<YdProdWorkHoursPrice> ydProdWorkHoursPriceLambdaQueryWrapper = new LambdaQueryWrapper<>();
        ydProdWorkHoursPriceLambdaQueryWrapper.eq(YdProdWorkHoursPrice::getType,type);

        YdProdWorkHoursPrice ydProdWorkHoursPrice = ydProdWorkHoursPriceMapper.selectOne(ydProdWorkHoursPriceLambdaQueryWrapper);
        if (Objects.nonNull(ydProdWorkHoursPrice)){
            ydProdWorkHoursPrice.setPrice(price);

            ydProdWorkHoursPriceMapper.update(ydProdWorkHoursPrice,ydProdWorkHoursPriceLambdaQueryWrapper);
        }else {
            ydProdWorkHoursPrice = new YdProdWorkHoursPrice();
            ydProdWorkHoursPrice.setType(type);
            ydProdWorkHoursPrice.setPrice(price);

            ydProdWorkHoursPriceMapper.insert(ydProdWorkHoursPrice);
        }
    }

    @Override
    public void updateWorkHours(Map map1) {
        MDC.put("MDC_KEY_PID","1001");

        String formInstId = UtilMap.getString(map1, "formInstId");

        Map processInstance = ddClient_workflow.getProcessInstanceId(ddClient.getAccessToken(), formInstId);

        String user = UtilMap.getString(processInstance, "originatorUserId");
        String originatorDeptId = UtilMap.getString(processInstance, "originatorDeptId");

        String stTime="";
        String edTime="";

        List<Map> formComponentValues = UtilMap.getList(processInstance, "formComponentValues");

        for (Map formComponentValue : formComponentValues) {
            String componentType = UtilMap.getString(formComponentValue, "componentType");

            if (componentType.equals("DDDateField")){
                String bizAlias = UtilMap.getString(formComponentValue, "bizAlias");
                String value = UtilMap.getString(formComponentValue, "value");
                if (bizAlias.equals("startTime")){
                    stTime = value + ":00";
                }else if (bizAlias.equals("finishTime")){
                    edTime = value + ":00";
                }else if (bizAlias.equals("userCheckTime")){
                    stTime = value + ":00";
                    edTime = value + ":00";
                    break;
                }
            }
        }

        //部门人员单价
        List<Map> list=ydService.queryAllFormData(YDParam.builder().formUuid("FORM-5061F7AE543B429C8241EC730A6F31653NNK").build());
        for(Map map:list){
            Map formData= UtilMap.getMap(map,"formData");
            String deptId=String.valueOf(UtilMap.getList(formData,"departmentSelectField_m8e4zaju_id").get(0));
            String price=UtilMap.getString(formData,"numberField_m8e4zajw_value");

            if (!originatorDeptId.equals(deptId)){
                continue;
            }

            List<Map> valList=ddClientAttendance.getAttColumnVal(ddClient.getAccessToken(),user, Arrays.asList("82772106","89349019","82772125"),stTime,edTime);

            if(valList!=null&&valList.size()==3){
                Map<String,Map<String,String>> dateMap=toDateMap(valList);
                for (String date:dateMap.keySet()) {
                    Map<String,String> dataMap=dateMap.get(date);
                    String workTime="休息".equals(dataMap.get("82772125"))?
                            dataMap.get("89349019"): NumberUtil.add(dataMap.get("89349019"),dataMap.get("82772106")).toString();

                    log.info("加班/补卡更新员工工时 user：{},date：{},workTime：{},price：{}",user,date,workTime,price);

                    saveData(user,date,workTime,price);

                    //同步到数据库
                    LambdaQueryWrapper<YdUserInput> ydUserInputLambdaQueryWrapper = new LambdaQueryWrapper<>();
                    ydUserInputLambdaQueryWrapper.eq(YdUserInput::getUserId,user)
                            .eq(YdUserInput::getDate, date);

                    YdUserInput ydUserInput = ydUserInputMapper.selectOne(ydUserInputLambdaQueryWrapper);

                    if (Objects.nonNull(ydUserInput)){
                        ydUserInput.setWorkHours(workTime);
                        ydUserInput.setPrice(price);
                        ydUserInput.setTotalPrice(NumberUtil.mul(workTime,price));

                        ydUserInputMapper.update(ydUserInput,ydUserInputLambdaQueryWrapper);
                    }else {
                        try {
                            ydUserInput = new YdUserInput();
                            ydUserInput.setUserId(user);
                            SimpleDateFormat formatter = new SimpleDateFormat(UtilDateTime.DATE_TIME_PATTERN);
                            ydUserInput.setDate(formatter.parse(date));
                            ydUserInput.setWorkHours(workTime);
                            ydUserInput.setPrice(price);
                            ydUserInput.setTotalPrice(NumberUtil.mul(workTime,price));

                            ydUserInputMapper.insert(ydUserInput);
                        }catch (ParseException e){
                            log.info("无法解析日期字符串: {}",e.getMessage());
                        }
                    }
                }
            }
        }
    }

    /*@Override
    public void syncUserInput(LocalDateTime startTime, LocalDateTime endTime) {
        List<Map> dataList = getYdFormDataList("FORM-78BF5DE20E244369BD475C11A5CA48A0ZAQJ", "", YDConf.FORM_QUERY.retrieve_list_all);

        for (Map data : dataList) {
            Map formData = UtilMap.getMap(data, "formData");

            YdUserInput ydUserInput = new YdUserInput();
            ydUserInput.setUser(UtilMap.getList(formData, "employeeField_m8cu0g58").get(0).toString());
            ydUserInput.setUserId(UtilMap.getList(formData, "employeeField_m8cu0g58_id").get(0).toString());

            ydUserInput.setDate(new Date(UtilMap.getLong(formData,"dateField_m8e53oef")));
            ydUserInput.setWorkHours(UtilMap.getString(formData,"numberField_m8ctvm2e"));
            ydUserInput.setPrice(UtilMap.getString(formData,"numberField_m8e53oeg"));
            ydUserInput.setTotalPrice(UtilMap.getString(formData,"numberField_m8e53oeh"));

            ydUserInputMapper.insert(ydUserInput);
        }
    }*/

    /*private List<Map> getYdFormDataList(String formUuid, String searchCondition, YDConf.FORM_QUERY formQuery) {
        List<Map> list = new ArrayList<>();
        DDR_New ddrNew = new DDR_New();
        int pageNumber = 1;
        int pageSize = 100;
        do {
            ddrNew = ydClient.queryData(YDParam.builder().formUuid(formUuid)
                    .searchCondition(searchCondition)
                    .pageNumber(pageNumber)
                    .pageSize(pageSize).build(), formQuery);

            list.addAll((List<Map>) ddrNew.getData());
            pageNumber++;
        }while (ddrNew.getTotalCount() > ddrNew.getPageNumber() * pageSize);
        return list;
    }*/

    private Map<String,Map<String,String>> toDateMap(List<Map> valList){
        Map<String,Map<String,String>>  result = new HashMap<>();
        for(Map map:valList){
            String columnId=UtilMap.getString(UtilMap.getMap(map,"column_vo"),"id");
            List<Map> list=UtilMap.getList(map,"column_vals");
            for(Map map1:list){
                String date=UtilMap.getString(map1,"date");
                String value=UtilMap.getString(map1,"value");
                value=columnId.equals("82772106")?NumberUtil.round(NumberUtil.div(value,"60"),2).toString():value; // 工作时长 分钟转小时
                if(result.containsKey(date)){
                    result.get(date).put(columnId,value);
                }else{
                    result.put(date,UtilMap.map(columnId,value));
                }
            }
        }
        return result;
    }

    private void saveData(String userId,String date,String gs,String price){
        Long dateTime= UtilDateTime.getLocalDateTimeTimeStamp(UtilDateTime.parseLocalDateTime(date));
        Map saveMap=UtilMap.map("employeeField_m8cu0g58, dateField_m8e53oef, numberField_m8ctvm2e, numberField_m8e53oeg, numberField_m8e53oeh",
                Arrays.asList(userId),dateTime,gs,price,NumberUtil.mul(gs,price));
        ydClient.operateData(YDParam.builder().formUuid("FORM-78BF5DE20E244369BD475C11A5CA48A0ZAQJ")
                .searchCondition(JSONObject.toJSONString(UtilMap.map("employeeField_m8cu0g58, dateField_m8e53oef", userId,Arrays.asList(dateTime,dateTime))))
                .formDataJson(JSONObject.toJSONString(saveMap)).build(), YDConf.FORM_OPERATION.upsert);
    }
}
