package com.engine.organization.service.impl;

import cn.hutool.core.util.StrUtil;
import com.api.hrm.bean.FieldItem;
import com.api.hrm.util.FieldType;
import com.engine.core.impl.Service;
import com.engine.organization.entity.config.dto.EditTableColumns;
import com.engine.organization.entity.config.dto.EditTableDatas;
import com.engine.organization.entity.config.params.QTXConfigParam;
import com.engine.organization.entity.config.po.QTXConfigPO;
import com.engine.organization.enums.MobileTerminalEnum;
import com.engine.organization.mapper.config.ConfigMapper;
import com.engine.organization.service.ConfigService;
import com.engine.organization.util.OrganizationDateUtil;
import com.engine.organization.util.db.MapperProxyFactory;
import com.weaver.file.ConfigOperator;
import lombok.SneakyThrows;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.codec.binary.Base64;
import weaver.general.BaseBean;
import weaver.systeminfo.SystemEnv;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.util.*;

/**
 * @Author liang.cheng
 * @Date 2023/8/18 2:38 PM
 * @Description:
 * @Version 1.0
 */
public class ConfigServiceImpl extends Service implements ConfigService {

    private static final String VALUE_ONE = "1";

    private static ConfigMapper getConfigMapper() {
        return MapperProxyFactory.getProxy(ConfigMapper.class);
    }


    @Override
    public String ssoLogin(QTXConfigParam qtx) throws UnsupportedEncodingException {
        String hkUrl;
        BaseBean bb = new BaseBean();
        String enable = bb.getPropValue("hrmOrganization", "enable");
        String userAgent = qtx.getUserAgent();
        boolean termianal = MobileTerminalEnum.containsEnumValue(userAgent);
        if (VALUE_ONE.equals(enable)) {
            QTXConfigPO qtxConfig = getConfigMapper().selectConfigInfo();
            String domain = "0".equals(qtx.getDomainIndex()) ? qtxConfig.getUrl() : qtxConfig.getSecondUrl();
            String address = termianal ? qtxConfig.getMobileAddress() : qtxConfig.getPcAddress();
            String accessKey = URLEncoder.encode(getAccessKey(qtxConfig.getAppSecret()),"utf-8");
            hkUrl = StrUtil.format("{}{}?accessKey={}&type={}&username={}&whole={}&domainIndex={}",domain,address,accessKey,qtx.getType(),qtx.getLoginId(),qtx.getWhole(),qtx.getDomainIndex());
        }else {
            String accessKey = URLEncoder.encode(getAccessKey(bb.getPropValue("qtx_sso_login", "app_secret")),"utf-8");
            String domain = "0".equals(qtx.getDomainIndex()) ? bb.getPropValue("qtx_sso_login","url") : bb.getPropValue("qtx_sso_login","url1");
            String address = termianal ? bb.getPropValue("qtx_sso_login","h5address") : bb.getPropValue("qtx_sso_login","pcaddress");
            hkUrl = StrUtil.format("{}{}?accessKey={}&type={}&username={}&whole={}&domainIndex={}",domain,address,accessKey,qtx.getType(),qtx.getLoginId(),qtx.getWhole(),qtx.getDomainIndex());
        }
        return hkUrl;
    }

    @SneakyThrows
    @Override
    public Map<String, Object> selectConfigInfo() {
        Map<String, Object> map = new HashMap<>(16);
        BaseBean bb = new BaseBean();
        List<EditTableColumns> columns = new ArrayList<>();
        columns.add(EditTableColumns.builder().dataIndex("appSecret").key("appSecret").title(SystemEnv.getHtmlLabelName(547397,user.getLanguage())).width("20%").build());
        columns.add(EditTableColumns.builder().dataIndex("url").key("url").title(SystemEnv.getHtmlLabelName(547398, user.getLanguage())).width("20%").build());
        columns.add(EditTableColumns.builder().dataIndex("secondUrl").key("secondUrl").title(SystemEnv.getHtmlLabelName(547399,user.getLanguage())).width("20%").build());
        columns.add(EditTableColumns.builder().dataIndex("pcAddress").key("pcAddress").title(SystemEnv.getHtmlLabelName(547400,user.getLanguage())).width("20%").build());
        columns.add(EditTableColumns.builder().dataIndex("mobileAddress").key("mobileAddress").title(SystemEnv.getHtmlLabelName(547401,user.getLanguage())).width("20%").build());
        columns.forEach(editTableColumns -> editTableColumns.setCom(getFieldDetailInfo(editTableColumns)));
        QTXConfigPO qtxConfigPO = getConfigMapper().selectConfigInfo();
        EditTableDatas datas = new EditTableDatas();
        if (Objects.nonNull(qtxConfigPO)) {
            BeanUtils.copyProperties(datas, qtxConfigPO);
        }
        map.put("isopenconfig",bb.getPropValue("hrmOrganization","enable"));
        map.put("columns",columns);
        map.put("datas", Collections.singletonList(datas));
        return map;
    }

    @SneakyThrows
    @Override
    public int saveConfigInfo(QTXConfigPO qtxConfigPO, String isopenconfig) {
        ConfigOperator ConfigOperator = new ConfigOperator();
        ConfigOperator.setProp("hrmOrganization.properties", "enable", isopenconfig);
        qtxConfigPO.setCreator(user.getUID());
        qtxConfigPO.setCreateDate(OrganizationDateUtil.getFormatLocalDate(LocalDate.now()));
        getConfigMapper().deleteAll();
        return getConfigMapper().insertIgnoreNull(qtxConfigPO);
    }

    /**
     *表格控件
     * @return
     */
    private static List<FieldItem> getFieldDetailInfo(EditTableColumns columns) {
        List<FieldItem> ls = new ArrayList<>();
        FieldItem fieldItem = new FieldItem();
        fieldItem.setKey(columns.getKey());
        fieldItem.setLabel("");
        fieldItem.setType(FieldType.INPUT);
        fieldItem.setViewAttr(3);
        fieldItem.setWidth(columns.getWidth());
        ls.add(fieldItem);
        return ls;
    }


    private static String getAccessKey(String appSecret) {
        String data = System.currentTimeMillis() + "||" + appSecret;
        String IV = appSecret.substring(appSecret.length() - 16);
        String keys = appSecret.substring(0, 16);
        return encryptData(data, keys, IV);
    }

    /**
     * @Description: AES加密
     * @Author: liang.cheng
     * @Date: 2023/8/18 4:45 PM
     * @param: [data, key, IV]
     * @return: java.lang.String
     */
    private static String encryptData(String data, String key, String IV) {
        try {
            //算法/模式/填充模式  AES/CBC/PKCS5Padding
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8);
            int plaintextLength = dataBytes.length;
            byte[] plaintext = new byte[plaintextLength];
            System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
            SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
            IvParameterSpec ivspec = new IvParameterSpec(IV.getBytes());
            cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
            byte[] encrypted = cipher.doFinal(plaintext);
            //输出内容，Base64处理
            return new String(Base64.encodeBase64(encrypted));
        } catch (Exception e) {
            return null;
        }
    }
}
