package com.friday.tooldriver.service.rpa.taieoc;

import com.friday.base.database.annotation.ListPage;
import com.friday.base.common.response.DubboResult;
import com.friday.operation.api.keepalive.constant.taieoc.TableName;
import com.friday.operation.api.keepalive.constant.taieoc.TaieOcConstants;
import com.friday.operation.api.keepalive.dto.taieoc.*;
import com.friday.operation.api.keepalive.service.taieoc.IGroupManage;
import com.friday.operation.api.tooldriver.constant.SupplierEnum;
import com.friday.operation.api.tooldriver.dto.common.DriverBase;
import com.friday.operation.api.tooldriver.dto.rpa.GroupDto;
import com.friday.tooldriver.constants.TaieOcManageCode;
import com.friday.tooldriver.mapper.taieoc.OcGroupMapper;
import com.friday.tooldriver.mapper.taieoc.OcMapper;
import com.friday.tooldriver.mapper.taieoc.OcTenantMapper;
import com.friday.tooldriver.po.taieoc.OcGroupPo;
import com.friday.tooldriver.po.taieoc.OcInfoPo;
import com.friday.tooldriver.po.taieoc.OcTenantPo;
import com.friday.tooldriver.service.strategy.CapabilityDriverImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class GroupManageImpl implements IGroupManage {

    @Autowired
    private OcTenantMapper ocTenantMapper;

    @Autowired
    private OcGroupMapper ocGroupMapper;

    @Autowired
    private OcMapper ocMapper;

    @Autowired
    private CapabilityDriverImpl rpaDriverService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public DubboResult createGroup(OcTenantSelectDto tenantSelectDto, GroupDto group) {
        try {
            List<OcTenantPo> tenantPos = ocTenantMapper.selectOcTenant(OcTenantFilterDto.ocTenantFilterBuilder()
                            .ocTenantId(Long.parseLong(tenantSelectDto.getOcTenantKey()))
                    .build());
            if(CollectionUtils.isEmpty(tenantPos)){
                return DubboResult.newFailure(TaieOcManageCode.TENANT_NOT_EXIST.getCode(), TaieOcManageCode.TENANT_NOT_EXIST.getMessage());
            }
            // 调用驱动接口在中控上增加组信息
            DubboResult<GroupDto> rpaDriverServiceGroup = rpaDriverService.createGroup(DriverBase.builder()
                    .tenantKey(tenantSelectDto.getOcTenantKey())
                    .build(), group);
            if(!rpaDriverServiceGroup.success()){
                throw new RuntimeException(rpaDriverServiceGroup.getException());
            }
            GroupDto dto = rpaDriverServiceGroup.getObject();
            // 非神码厂商中控组信息落库
            List<OcInfoPo> ocInfo = ocMapper.selectOcInfo(OcTenantFilterDto.ocTenantFilterBuilder().ocTenantId(Long.parseLong(tenantSelectDto.getOcTenantKey())).build());
            if(!SupplierEnum.RPASupplierEnum.SMARTRPA.getSupplierName().equals(ocInfo.get(0).getSupplier())){
                OcGroupPo ocGroupPo = OcGroupPo.builder()
                        .ocTenantInfoId(Long.parseLong(tenantSelectDto.getOcTenantKey()))
                        .groupName(group.getName())
                         .groupKey(dto.getKey())
                        .parentId(Long.parseLong(group.getParentKey()))
                        .build();
                ocGroupMapper.insert(ocGroupPo);
            }else{
                ocGroupMapper.update(OcGroupPo.builder().id(Long.parseLong(dto.getKey())).groupKey(dto.getKey()).build());
            }
            return DubboResult.newSuccess(TaieOcManageCode.SUCCESS.getMessage());
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            log.error(TaieOcManageCode.INTERNAL_ERROR.toString(), e);
            return DubboResult.newFailure(TaieOcManageCode.INTERNAL_ERROR.getCode(), TaieOcManageCode.INTERNAL_ERROR.getMessage());
        }
    }

    @Override
    @ListPage(tableName = TableName.OC_TENANT_PAGE_NAME)
    public DubboResult<ArrayList<GroupPageDto>> queryGroups(OcGroupFilterDto filterDto) {
        try {
            DubboResult<ArrayList<GroupPageDto>> result;
            List<OcGroupPo> groupPos = ocGroupMapper.selectGroup(filterDto);
            ArrayList<GroupPageDto> groupDto = groupPos.stream().map(this::createPageDto)
                    .collect(Collectors.toCollection(ArrayList::new));
            result = DubboResult.newSuccess(groupDto);
            result.setMessage(TaieOcManageCode.SUCCESS.getMessage());
            return result;
        } catch (Exception e) {
            log.error(TaieOcManageCode.INTERNAL_ERROR.toString(), e);
            return DubboResult.newFailure(TaieOcManageCode.INTERNAL_ERROR.getCode(), TaieOcManageCode.INTERNAL_ERROR.getMessage());
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public DubboResult deleteGroupByKey(String key){
        try {
            Long groupId = Long.parseLong(key);
            ocGroupMapper.deleteByPrimaryKey(groupId);
            // 调用驱动接口在中控上删除组信息
            OcGroupPo ocGroupPo = ocGroupMapper.selectByPrimaryKey(groupId);
            OcTenantPo ocTenantPo = ocTenantMapper.selectByPrimaryKey(ocGroupPo.getOcTenantInfoId());
            rpaDriverService.deleteGroupByKey(DriverBase.builder()
                            .tenantKey(String.valueOf(ocTenantPo.getId()))
                    .build(),ocGroupPo.getGroupKey());
            return DubboResult.newSuccess();
        } catch (Exception e) {
            log.error(TaieOcManageCode.INTERNAL_ERROR.toString(), e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return DubboResult.newFailure(TaieOcManageCode.INTERNAL_ERROR.getCode(), TaieOcManageCode.INTERNAL_ERROR.getMessage());
        }
    }

    @Override
    public DubboResult<GroupPageDto> queryGroupDetail(Long groupId) {
        try {
            DubboResult<GroupPageDto> result;
            OcGroupPo groupPo = ocGroupMapper.selectByPrimaryKey(groupId);
            GroupPageDto pageDto = createPageDto(groupPo);
            result = DubboResult.newSuccess(pageDto);
            result.setMessage(TaieOcManageCode.SUCCESS.getMessage());
            return result;
        } catch (Exception e) {
            log.error(TaieOcManageCode.INTERNAL_ERROR.toString(), e);
            return DubboResult.newFailure(TaieOcManageCode.INTERNAL_ERROR.getCode(), TaieOcManageCode.INTERNAL_ERROR.getMessage());
        }
    }

    private GroupPageDto createPageDto(OcGroupPo groupPo) {
        GroupPageDto pageDto = OcGroupPo.createPage(groupPo);
        OcTenantPo ocTenantPo = ocTenantMapper.selectByPrimaryKey(groupPo.getOcTenantInfoId());
        pageDto.setTenant(ocTenantPo.getOcTenant());
        OcInfoPo ocInfoPo = ocMapper.selectByPrimaryKey(ocTenantPo.getOcInfoId());
        pageDto.setOcInfo(ocInfoPo.getOcInfo());
        pageDto.setSupplier(ocInfoPo.getSupplier());
        return pageDto;
    }

}
