package com.tuoheng.admin.service.third.oidc;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tuoheng.admin.constant.OidcUrlConstant;
import com.tuoheng.admin.constant.SystemConstant;
import com.tuoheng.admin.dto.ClientRoleDto;
import com.tuoheng.admin.entity.Tenant;
import com.tuoheng.admin.entity.User;
import com.tuoheng.admin.enums.ClientEnum;
import com.tuoheng.admin.enums.MarkEnum;
import com.tuoheng.admin.mapper.TenantMapper;
import com.tuoheng.admin.request.oidc.OidcCreateUserRequest;
import com.tuoheng.common.core.config.common.CommonConfig;
import com.tuoheng.common.core.utils.JsonResult;
import com.tuoheng.common.core.utils.SecurityUserUtils;
import com.tuoheng.common.core.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class AddOidcUserService {

    @Autowired
    @Qualifier("restTemplate")
    private RestTemplate restTemplate;

    @Autowired
    private TenantMapper tenantMapper;

    public JsonResult add(User user, String password, Tenant tenant) {
        OidcCreateUserRequest request = this.buildOidcCreateUserRequest(user, password, tenant);
        //设置请求头
        HttpHeaders resultRequestHeader = new HttpHeaders();
        resultRequestHeader.add("Authorization", "Bearer " + SecurityUserUtils.token());
        HttpEntity httpEntity = new HttpEntity(request, resultRequestHeader);
        String url = CommonConfig.oidcUrl + OidcUrlConstant.USER_CREATE;
        ResponseEntity<JsonResult> response;
        try {
            response = restTemplate.exchange(url, HttpMethod.POST, httpEntity, JsonResult.class);
        } catch (Exception e) {
            log.info("oidc新增用户异常, url:{}", url);
            log.info("oidc新增用户异常, httpEntity:{}", httpEntity);
            return JsonResult.error("oidc新增用户失败");
        }
        if (null == response || !response.hasBody()) {
            log.error("oidc新增用户响应失败，response为空");
            log.info("oidc新增用户异常, url:{}", url);
            log.info("oidc新增用户异常, httpEntity:{}", httpEntity);
            return JsonResult.error("oidc新增用户响应失败");
        }
        if (response.getBody().getCode() != JsonResult.SUCCESS) {
            log.error("oidc新增用户响应失败" + response.getBody());
            return JsonResult.error(response.getBody().getMsg());
        }
        return JsonResult.success();
    }

    /**
     * 封装请求->oidc认证信息
     *
     * @param user
     * @return
     */
    private OidcCreateUserRequest buildOidcCreateUserRequest(User user, String password, Tenant tenant) {
        OidcCreateUserRequest oidcCreateUserRequest = new OidcCreateUserRequest();
        oidcCreateUserRequest.setUsername(user.getUsername());
        oidcCreateUserRequest.setPassword(password);
        if (ObjectUtil.isNull(tenant)) {
            //  普通用户新增
            Tenant tenantTmp = tenantMapper.selectOne(new LambdaQueryWrapper<Tenant>()
                    .eq(Tenant::getId, user.getTenantId())
                    .eq(Tenant::getMark, MarkEnum.VALID.getCode()));
            oidcCreateUserRequest.setTenantFlag(0);
            oidcCreateUserRequest.setTenantName(tenantTmp.getUsername());
        } else {
            oidcCreateUserRequest.setTenantFlag(1);
            oidcCreateUserRequest.setCode(tenant.getCode());
            oidcCreateUserRequest.setName(tenant.getName());
            oidcCreateUserRequest.setTenantName(tenant.getName());
        }
        List<ClientRoleDto> clientRoleDtoList = new ArrayList<>();
        ClientRoleDto clientRoleDto;
        if (StringUtils.isNotEmpty(user.getClientId())) {
            String[] clientIdArr = user.getClientId().split(",");
            for (String clientIdStr : clientIdArr) {
                int clientId = Integer.valueOf(clientIdStr);
                ClientEnum clientEnum = ClientEnum.parse(clientId);
                if (null != clientEnum) {
                    clientRoleDto = new ClientRoleDto();
                    clientRoleDto.setClientId(clientEnum.getDescription());
                    clientRoleDto.setRoleId(user.getRoleId());
                    clientRoleDtoList.add(clientRoleDto);
                }
            }
        }
        oidcCreateUserRequest.setClientRoleDtoList(clientRoleDtoList);
        return oidcCreateUserRequest;
    }
}
