package org.qinan.safetyeval.app.executor;

import com.jjb.saas.system.client.user.request.UserAddCmd;
import com.zcloud.gbscommon.utils.MD5;
import com.zcloud.gbscommon.utils.Sm2Util;
import org.qinan.safetyeval.client.api.AccountApi;
import org.qinan.safetyeval.client.co.AccountCO;
import org.qinan.safetyeval.client.dto.*;
import org.qinan.safetyeval.domain.entity.AccountEntity;
import org.qinan.safetyeval.domain.query.AccountQuery;
import org.qinan.safetyeval.domain.query.PageResult;
import org.qinan.safetyeval.domain.service.AccountDomainService;
import org.qinan.safetyeval.infrastructure.adapter.auth.AuthUserContextAdapter;
import org.qinan.safetyeval.infrastructure.adapter.gbs.GbsUserFacadeClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 用户执行器（App层）
 *
 * @author safety-eval
 */
@Service
public class AccountExecutor implements AccountApi {

    @Lazy
    @Autowired(required = false)
    private AccountDomainService accountDomainService;
    @Autowired
    private GbsUserFacadeClient gbsUserFacadeClient;
    @Value("${def.password:a123456}")
    private String defPassword;
    @Value("${def.publicKey:0402df2195296d4062ac85ad766994d73e871b887e18efb9a9a06b4cebc72372869b7da6c347c129dee2b46a0f279ff066b01c76208c2a052af75977c722a2ccee}")
    private String publicKey;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SingleResponse<AccountCO> add(AccountAddCmd cmd) {
        AccountEntity entity = new AccountEntity();
        entity.setUserName(cmd.getUserName());
        entity.setAccount(cmd.getAccount());
        entity.setPhone(cmd.getPhone());
        entity.setPassword(cmd.getPassword());
        entity.setProfileUrl(cmd.getProfileUrl());
        entity.setType(cmd.getType());
        AccountEntity result = accountDomainService.add(entity);
        return SingleResponse.success(toCO(result));
    }

    @Override
    public SingleResponse<AccountCO> get(Long id) {
        AccountEntity entity = accountDomainService.get(id);
        return SingleResponse.success(toCO(entity));
    }

    @Override
    public SingleResponse<AccountCO> modify(AccountModifyCmd cmd) {
        AccountEntity entity = new AccountEntity();
        entity.setId(cmd.getId());
        entity.setUserName(cmd.getUserName());
        entity.setAccount(cmd.getAccount());
        entity.setPhone(cmd.getPhone());
        entity.setPassword(cmd.getPassword());
        entity.setProfileUrl(cmd.getProfileUrl());
        entity.setType(cmd.getType());

        AccountEntity result = accountDomainService.modify(entity);
        return SingleResponse.success(toCO(result));
    }

    @Override
    public SingleResponse<Void> delete(Long id) {
        accountDomainService.delete(id);
        return SingleResponse.success();
    }

    @Override
    public PageResponse<AccountCO> page(AccountPageQuery query) {
        AccountQuery domainQuery = new AccountQuery();
        domainQuery.setPageNum(query.getCurrent());
        domainQuery.setPageSize(query.getSize());
        domainQuery.setTenantId(AuthUserContextAdapter.getCurrentTenantId());
        domainQuery.setUserName(query.getUserName());
        domainQuery.setAccount(query.getAccount());
        domainQuery.setPhone(query.getPhone());
        domainQuery.setType(query.getType());

        PageResult<AccountEntity> pageResult = accountDomainService.page(domainQuery);

        return PageResponse.of(
                pageResult.getRecords().stream()
                        .map(this::toCO)
                        .collect(java.util.stream.Collectors.toList()),
                pageResult.getTotal());
    }

    @Override
    public SingleResponse<AccountCO> syncUserToGBS(String account) {
        AccountEntity result = accountDomainService.syncUserToGBS(account);
        // 同步gbs用户
        UserAddCmd userAddCmd = new UserAddCmd();
        userAddCmd.setId(result.getId());
        userAddCmd.setAccount(result.getAccount());
        userAddCmd.setTenantId(result.getTenantId());
        userAddCmd.setName(result.getUserName());
        String encrypt = Sm2Util.encryptHex(MD5.md5(defPassword), publicKey);
        userAddCmd.setPassword(encrypt);
        gbsUserFacadeClient.add(userAddCmd);
        return SingleResponse.success(toCO(result));
    }

    private AccountCO toCO(AccountEntity entity) {
        if (entity == null) {
            return null;
        }
        AccountCO co = new AccountCO();
        co.setId(entity.getId());
        co.setUserName(entity.getUserName());
        co.setAccount(entity.getAccount());
        co.setPhone(entity.getPhone());
        co.setProfileUrl(entity.getProfileUrl());
        co.setType(entity.getType());
        co.setTenantId(entity.getTenantId());
        return co;
    }
}
