package com.arms.api.account.service;

import com.arms.api.account.model.AlmAccount;
import com.arms.api.account.strategy.*;
import com.arms.api.serverinfo.model.enums.ServerType;
import com.arms.api.serverinfo.model.ServerInfo;
import com.arms.api.serverinfo.service.ServerInfoService;
import com.arms.api.util.errors.ErrorCode;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;


@Service
@AllArgsConstructor
@Slf4j
public class AccountStrategyService {

    private final AlmSelector almSelector;

    private final CloudJiraAccountStrategy cloudJiraAccountStrategy;

    private final OnPromiseJiraAccountStrategy onPromiseJiraAccountStrategy;

    private final OnPromiseRedmineAccountStrategy onPromiseRedmineAccountStrategy;

    private final ServerInfoService serverInfoService;

    public AccountStrategy accountSelector(ServerInfo serverInfo) {

        if (serverInfo == null || serverInfo.getType().isEmpty()) {
            log.error("AccountStrategyService::accountSelector::계정 전략 등록 Error: serverInfo_유형 {}",ErrorCode.SERVER_TYPE_INFO_ERROR.getErrorMsg());
            throw new IllegalArgumentException("계정 전략 등록 Error: serverInfo_유형 " + ErrorCode.SERVER_TYPE_INFO_ERROR.getErrorMsg());
        }

        ServerType serverType = ServerType.typeValueOf(serverInfo.getType());

        if (serverType == ServerType.CLOUD) {
            return cloudJiraAccountStrategy;
        }
        else if (serverType == ServerType.ON_PREMISS) {
            return onPromiseJiraAccountStrategy;
        }
        else if (serverType == ServerType.REDMINE_ON_PREMISS) {
            return onPromiseRedmineAccountStrategy;
        }

        throw new IllegalArgumentException("서버 유형에 존재 하지 않는 요청입니다.");
    }

    public AlmAccount verifyAccount(ServerInfo serverInfo) throws Exception{

        if (serverInfo == null) {
            log.error("AccountStrategyService::verifyAccount::계정 정보 검증하기 Error: 서버주소 {}",ErrorCode.SEARCH_INFO_ERROR.getErrorMsg());
            throw new IllegalArgumentException("계정 정보 검증하기  Error: 서버주소 " + ErrorCode.SEARCH_INFO_ERROR.getErrorMsg());
        }
        validateField(serverInfo.getUri(), ErrorCode.SERVER_URI_INFO_ERROR, "서버주소");
        validateField(serverInfo.getType(), ErrorCode.SERVER_TYPE_INFO_ERROR, "서버유형");
        validateField(serverInfoService.getDecryptPasswordOrToken(serverInfo), ErrorCode.SERVER_PW_OR_API_TOKEN_INFO_ERROR, "API 토큰 정보");
        validateField(serverInfo.getUserId(), ErrorCode.SERVER_ID_INFO_ERROR, "사용자 아이디");

        return almSelector.verifyAccount(accountSelector(serverInfo),serverInfo);

    }

    public AlmAccount getAccount(String connectId) throws Exception{

        if (connectId == null) {
            log.error("AccountStrategyService::getAccount::계정 정보 가져오기 Error: 연결_아이디 {} ", ErrorCode.PARAMETER_SERVER_ID_MISSING.getErrorMsg());
            throw new IllegalArgumentException("계정 정보 가져오기  Error: 연결_아이디 " + ErrorCode.PARAMETER_SERVER_ID_MISSING.getErrorMsg());
        }

        ServerInfo serverInfo = serverInfoService.verifyServerInfo(connectId);

        return almSelector.getAccount(this.accountSelector(serverInfo),connectId);

    }

    private void validateField(String field, ErrorCode errorCode, String fieldName) {
        if (field == null || field.isEmpty()) {
            log.error("AccountStrategyService::validateField::계정 정보 검증하기 Error: {} {}",fieldName,errorCode.getErrorMsg());
            throw new IllegalArgumentException("계정 정보 검증하기 Error: " + fieldName + " " + errorCode.getErrorMsg());
        }
    }


}
