package cn.iocoder.yudao.module.pms.oa;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.util.io.FileUtils;
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
import cn.iocoder.yudao.module.pms.dal.dataobject.maintain.IotMaintainDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.oa.IotOaCompanyDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.oa.IotOaDepartDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.oa.IotOaPersonDO;
import cn.iocoder.yudao.module.pms.dal.mysql.maintain.IotMaintainMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.oa.IotOaCompanyMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.oa.IotOaDepartMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.oa.IotOaPersonMapper;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.*;
import java.util.stream.Collectors;

@Component
public class OaFlow {
    private final IotOaCompanyMapper iotOaCompanyMapper;
    private final IotOaDepartMapper iotOaDepartMapper;
    private final IotOaPersonMapper iotOaPersonMapper;
    private final IotMaintainMapper iotMaintainMapper;
    @Value("${oa.appid}")
    private String appid;
    @Value("${oa.cpk}")
    private String cpk;
    @Value("${oa.register}")
    private String registerUrl;
    @Value("${oa.gettoken}")
    private String tokenUrl;
    @Value("${oa.companyUrl}")
    private String companyUrl;
    @Value("${oa.departmentUrl}")
    private String departmentUrl;
    @Value("${oa.userUrl}")
    private String userUrl;
    @Value("${oa.workflowId}")
    private String workflowId;
    @Value("${oa.requestName}")
    private String requestName;
    @Value("${oa.outMaintain}")
    private String outMaintainUrl;
    @Value("${oa.userid}")
    private String userid;

    private static String spk = "";
    private static String secret = "";

    public OaFlow(IotOaCompanyMapper iotOaCompanyMapper, IotOaDepartMapper iotOaDepartMapper, IotOaPersonMapper iotOaPersonMapper, IotMaintainMapper iotMaintainMapper) {
        this.iotOaCompanyMapper = iotOaCompanyMapper;
        this.iotOaDepartMapper = iotOaDepartMapper;
        this.iotOaPersonMapper = iotOaPersonMapper;
        this.iotMaintainMapper = iotMaintainMapper;
    }


    public void register() throws Exception{
        HttpHeaders headers = new HttpHeaders();
        headers.add("appid", appid);
        headers.add("cpk", cpk);

        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(headers);
        RestTemplate restTemplate = SslSkippingRestTemplate.createRestTemplate();

        String result = restTemplate.postForObject(registerUrl, requestEntity, String.class);
        JSONObject jsonObject = JSON.parseObject(result);
        spk = String.valueOf(jsonObject.get("spk"));
        secret = String.valueOf(jsonObject.get("secret"));
        System.out.println("result register:" + result);

    }

    public String getToken() throws Exception{
//        if (StringUtils.isBlank(spk) || StringUtils.isBlank(secret)) {
            register();
//        }
        String secretEn = E9ApiTokenUtil.encryptString(spk, secret);
        HttpHeaders headers = new HttpHeaders();
        headers.add("appid", appid);
        headers.add("secret", secretEn);

        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(headers);
        RestTemplate restTemplate = SslSkippingRestTemplate.createRestTemplate();

        String result = restTemplate.postForObject(tokenUrl, requestEntity, String.class);
        JSONObject jsonObject = JSON.parseObject(result);
        String token = String.valueOf(jsonObject.get("token"));
        System.out.println("result token:" + result);
        return token;
    }

    public void getCompany() throws Exception{
        String token = getToken();
        HttpHeaders headersOut = new HttpHeaders();
        headersOut.add("token", token);
        headersOut.add("appid", appid);
        headersOut.add("userid", "cLPEaFs9moW6b3xZMl1kNNWAAo7bp61ZRRTKmpiJUe56hSxQvrC2vWtY5ogj7g5FAnUOlzYjYg9MRktKXcseh/nsvZCQGa3BAlYixlDJruV19y4Omx5dYnqu/qv2rJAqTzUS71sOwuB1M2nKlLVsphw1GF74UhGP4xsjpZP7mC8=");

        Map<String, Object> params = new HashMap<>();
        Map<String, Object> map = new HashMap<>();
        map.put("pagesize",1000000);
        params.put("params", map);
        // 3. 组合请求头和请求体
        HttpEntity<Map<String, Object>> requestEntityOut = new HttpEntity<>(params, headersOut);
        RestTemplate restTemplate = SslSkippingRestTemplate.createRestTemplate();
        String company = restTemplate.postForObject(companyUrl, requestEntityOut, String.class);
        JSONObject companyInfo = JSON.parseObject(company);
        //请求成功
        if (Objects.nonNull(companyInfo)&&"1".equals(String.valueOf(companyInfo.get("code")))){
            if (Objects.nonNull(companyInfo.get("data"))) {
                JSONObject resultJson = JSON.parseObject(companyInfo.get("data").toString());
                if (Objects.nonNull(resultJson.get("dataList"))) {
                    //先删除
                    List<Long> ids = iotOaCompanyMapper.selectList().stream().map(IotOaCompanyDO::getId).collect(Collectors.toList());
                    iotOaCompanyMapper.deleteByIds(ids);
                    JSON.parseArray(resultJson.get("dataList").toString(),IotOaCompanyDO.class).forEach(item -> {
                        IotOaCompanyDO companyDO = new IotOaCompanyDO();
                        BeanUtils.copyProperties(item,companyDO);
                        companyDO.setOaId(String.valueOf(companyDO.getId()));
                        companyDO.setId(null);
                        companyDO.setDeleted(false);
                        iotOaCompanyMapper.insert(companyDO);
                    });
                }
            }
        }
    }

    public void getDepart() throws Exception {
        String token = getToken();
        HttpHeaders headersOut = new HttpHeaders();
        headersOut.add("token", token);
        headersOut.add("appid", appid);
        headersOut.add("userid", "cLPEaFs9moW6b3xZMl1kNNWAAo7bp61ZRRTKmpiJUe56hSxQvrC2vWtY5ogj7g5FAnUOlzYjYg9MRktKXcseh/nsvZCQGa3BAlYixlDJruV19y4Omx5dYnqu/qv2rJAqTzUS71sOwuB1M2nKlLVsphw1GF74UhGP4xsjpZP7mC8=");

        Map<String, Object> params = new HashMap<>();
        Map<String, Object> map = new HashMap<>();
        map.put("pagesize",1000000);
        params.put("params", map);
        // 3. 组合请求头和请求体
        HttpEntity<Map<String, Object>> requestEntityOut = new HttpEntity<>(params, headersOut);
        RestTemplate restTemplate = SslSkippingRestTemplate.createRestTemplate();
        String company = restTemplate.postForObject(departmentUrl, requestEntityOut, String.class);
        JSONObject companyInfo = JSON.parseObject(company);
        //请求成功
        if (Objects.nonNull(companyInfo) && "1".equals(String.valueOf(companyInfo.get("code")))) {
            if (Objects.nonNull(companyInfo.get("data"))) {
                JSONObject resultJson = JSON.parseObject(companyInfo.get("data").toString());
                if (Objects.nonNull(resultJson.get("dataList"))) {
                    //先删除
                    List<Long> ids = iotOaDepartMapper.selectList().stream().map(IotOaDepartDO::getId).collect(Collectors.toList());
                    iotOaDepartMapper.deleteByIds(ids);
                    JSON.parseArray(resultJson.get("dataList").toString(), IotOaDepartDO.class).forEach(item -> {
                        IotOaDepartDO iotOaDepartDO = new IotOaDepartDO();
                        BeanUtils.copyProperties(item, iotOaDepartDO);
                        iotOaDepartDO.setOaId(String.valueOf(iotOaDepartDO.getId()));
                        iotOaDepartDO.setId(null);
                        iotOaDepartDO.setDeleted(false);
                        iotOaDepartMapper.insert(iotOaDepartDO);
                    });
                }
            }
        }
    }

    public void getPerson() throws Exception {
        String token = getToken();
        HttpHeaders headersOut = new HttpHeaders();
        headersOut.add("token", token);
        headersOut.add("appid", appid);
        headersOut.add("userid", userid);

        Map<String, Object> params = new HashMap<>();
        Map<String, Object> map = new HashMap<>();
        map.put("pagesize",1000000);
        params.put("params", map);
        // 3. 组合请求头和请求体
        HttpEntity<Map<String, Object>> requestEntityOut = new HttpEntity<>(params, headersOut);
        RestTemplate restTemplate = SslSkippingRestTemplate.createRestTemplate();
        String company = restTemplate.postForObject(userUrl, requestEntityOut, String.class);
        JSONObject companyInfo = JSON.parseObject(company);
        //请求成功
        if (Objects.nonNull(companyInfo) && "1".equals(String.valueOf(companyInfo.get("code")))) {
            if (Objects.nonNull(companyInfo.get("data"))) {
                JSONObject resultJson = JSON.parseObject(companyInfo.get("data").toString());
                if (Objects.nonNull(resultJson.get("dataList"))) {
                    //先删除
                    List<Long> ids = iotOaPersonMapper.selectList().stream().map(IotOaPersonDO::getId).collect(Collectors.toList());
                    iotOaPersonMapper.deleteByIds(ids);
                    TenantUtils.execute(1L, () -> {
                        JSON.parseArray(resultJson.get("dataList").toString(), IotOaPersonDO.class).forEach(item -> {
                            IotOaPersonDO iotOaPersonDO = new IotOaPersonDO();
                            BeanUtils.copyProperties(item, iotOaPersonDO);
                            iotOaPersonDO.setOaId(String.valueOf(iotOaPersonDO.getId()));
                            iotOaPersonDO.setId(null);
                            iotOaPersonDO.setDeleted(false);
                            iotOaPersonMapper.insert(iotOaPersonDO);
                        });
                    });
                }
            }
        }
    }

    @Autowired
    private RestTemplate restTemplate;
    private RestTemplate getNewRestTemplateWithoutCookie() {
        return new RestTemplate(new HttpComponentsClientHttpRequestFactory(
                HttpClients.custom()
                        .disableCookieManagement() // 彻底禁用Cookie，不保存、不携带
                        .setRedirectStrategy(new LaxRedirectStrategy())
                        .build()
        ));
    }

    public void createOutRepairFlow(IotMaintainDO iotMaintainDO) throws Exception {
        String token = getToken();
        HttpHeaders headersOut = new HttpHeaders();
        headersOut.add("token", token);
        headersOut.add("appid", appid);
        String person = E9ApiTokenUtil.encryptString(spk, iotMaintainDO.getApplyPersonId());
        headersOut.add("userid", person);
        headersOut.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        OutRepairFlow flow = new OutRepairFlow().setFieldName("xmjl").setFieldValue(iotMaintainDO.getProjectManager());
        OutRepairFlow flow1 = new OutRepairFlow().setFieldName("sqr").setFieldValue(iotMaintainDO.getApplyPersonId());
        List<IotOaPersonDO> dos = iotOaPersonMapper.selectList("oa_id", iotMaintainDO.getApplyPersonId());
        if (CollUtil.isEmpty(dos)) {
            throw new ServiceException(new ErrorCode(111, "不存在oa部门"));
        }
        OutRepairFlow flow2 = new OutRepairFlow().setFieldName("sqbm").setFieldValue(dos.get(0).getDepartmentid());
        OutRepairFlow flow3 = new OutRepairFlow().setFieldName("sqrq").setFieldValue(DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN));
        OutRepairFlow flow4 = new OutRepairFlow().setFieldName("clxh").setFieldValue(iotMaintainDO.getDeviceName());
        OutRepairFlow flow5 = new OutRepairFlow().setFieldName("cph").setFieldValue(iotMaintainDO.getDeviceName());
        OutRepairFlow flow6 = new OutRepairFlow().setFieldName("wxyy").setFieldValue(iotMaintainDO.getMaintainDescription());
        OutRepairFlow flow7 = new OutRepairFlow().setFieldName("ygjey").setFieldValue(String.valueOf(iotMaintainDO.getMaintainFee()));
        OutRepairFlow flow8 = new OutRepairFlow().setFieldName("wxdd").setFieldValue(Objects.isNull(iotMaintainDO.getAddress())?"": iotMaintainDO.getAddress());
        OutRepairFlow flow9 = new OutRepairFlow().setFieldName("ggxh").setFieldValue(String.valueOf(iotMaintainDO.getModel()));
        OutRepairFlow flow10 = new OutRepairFlow().setFieldName("qyrq").setFieldValue(StringUtils.substring(iotMaintainDO.getEnableDate(), 0,10));
        OutRepairFlow flow11 = new OutRepairFlow().setFieldName("wxlb").setFieldValue(String.valueOf(iotMaintainDO.getMaintainClassify()));
        OutRepairFlow flow12 = new OutRepairFlow().setFieldName("yzglxs").setFieldValue(Objects.isNull(iotMaintainDO.getKmHour())?"": iotMaintainDO.getKmHour());
        OutRepairFlow flow13 = new OutRepairFlow().setFieldName("wxcj").setFieldValue(String.valueOf(iotMaintainDO.getSupplier()));
        OutRepairFlow flow14 = new OutRepairFlow().setFieldName("gzms").setFieldValue(String.valueOf(iotMaintainDO.getDescription()));
        OutRepairFlow flow15 = new OutRepairFlow().setFieldName("wxxm").setFieldValue(String.valueOf(iotMaintainDO.getMaintainItem()));
        List<String> strings = JSON.parseArray(iotMaintainDO.getOutFile(), String.class);
        List<ImmutableMap> files = new ArrayList<>();
        strings.forEach(e ->{
            String fileName = FileUtils.getFileNameByUrlParse(e);
            String s1 = FileUtils.encodePathSegment(fileName);
            String s = StringUtils.substringBeforeLast(e, "/");
            files.add(ImmutableMap.of("filePath", s+"/"+s1,"fileName", fileName));
        });

        OutRepairFlow flow16 = new OutRepairFlow().setFieldName("fjsc").setFieldValue(JSON.toJSONString(files));
        OutRepairFlow flow17 = new OutRepairFlow().setFieldName("sfdy").setFieldValue("1");
        ImmutableList<OutRepairFlow> outRepairFlows = ImmutableList.of(flow16,flow12, flow3, flow4, flow5, flow6, flow7, flow8, flow9, flow10, flow11, flow2, flow, flow14, flow1, flow15, flow13,flow17);



        // 创建表单数据
        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
        params.add("workflowId", workflowId);
        params.add("requestName", requestName);
        params.add("mainData", JSON.toJSONString(outRepairFlows));
        Map<String, String> other = new HashMap<>();
        other.put("isnextflow", "1");
        params.add("otherParams", JSON.toJSONString(other));
        System.out.println("------------"+JSON.toJSONString(params));
        System.out.println(headersOut);

        RestTemplate noCookieRestTemplate = getNewRestTemplateWithoutCookie();


        // 3. 组合请求头和请求体
        HttpEntity<MultiValueMap<String, Object>> requestEntityOut = new HttpEntity<>(params, headersOut);
//        RestTemplate restTemplate = SslSkippingRestTemplate.createRestTemplate();
        String out = noCookieRestTemplate.postForObject(outMaintainUrl, requestEntityOut, String.class);
        JSONObject outInfo = JSON.parseObject(out);
        //请求成功
        if (Objects.isNull(outInfo) || !"success".equalsIgnoreCase(String.valueOf(outInfo.get("code")))) {
            throw new ServiceException(new ErrorCode(777, String.valueOf(outInfo.get("msg"))));
        }
        JSONObject jsonObject = JSON.parseObject(outInfo.get("data").toString());
        String requestid = String.valueOf(jsonObject.get("requestid"));
        iotMaintainDO.setRequestId(requestid);
        iotMaintainMapper.updateById(iotMaintainDO);

    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class OutRepairFlow {
        private String fieldName;
        private String fieldValue;
    }

}
