package com.caliverse.admin.domain.service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.caliverse.admin.domain.dao.admin.HistoryMapper;
import com.caliverse.admin.domain.dao.admin.WhiteListMapper;
import com.caliverse.admin.domain.entity.Admin;
import com.caliverse.admin.domain.entity.HISTORYTYPE;
import com.caliverse.admin.domain.entity.WhiteList;
import com.caliverse.admin.domain.request.WhiteListRequest;
import com.caliverse.admin.domain.response.WhiteListResponse;
import com.caliverse.admin.global.common.code.CommonCode;
import com.caliverse.admin.global.common.code.ErrorCode;
import com.caliverse.admin.global.common.code.SuccessCode;
import com.caliverse.admin.global.common.exception.RestApiException;
import com.caliverse.admin.global.common.utils.CommonUtils;
import com.caliverse.admin.global.common.utils.ExcelUtils;

import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;

@Service
@RequiredArgsConstructor
public class WhiteListService {
    private static final Logger logger = LoggerFactory.getLogger(WhiteListService.class);
    private final ExcelUtils excelUtils;
    private final WhiteListMapper whiteListMapper;
    private final HistoryMapper historyMapper;
    private final DynamoDBService dynamoDBService;
    public WhiteListResponse getWhiteList(Map<String, String> requestParams){

        List<WhiteList> whiteList = whiteListMapper.getWhiteList();

        return WhiteListResponse.builder()
                .resultData(WhiteListResponse.ResultData.builder()
                        .list(whiteList).build())
                .status(CommonCode.SUCCESS.getHttpStatus())
                .result(CommonCode.SUCCESS.getResult())
                .build();
    }
    public WhiteListResponse excelUpload(MultipartFile file){

        List<WhiteList> list = new ArrayList<>();
        // 파일 존재하지 않는 경우
        if (file.isEmpty()) {
            throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.NOT_EXIT_EXCEL.getMessage() );   //Excel 파일을 선택해주세요.
        }

        List<String> listData = excelUtils.getListData(file, 1, 0);

        // 엑셀 파일내 중복된 데이터 있는지 체크
        if(excelUtils.hasDuplicates(listData)){
            throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.DUPLICATE_EXCEL.getMessage() );   //Excel 파일을 선택해주세요.
        }

        listData.forEach(
                item->{
                    WhiteList whiteList = new WhiteList();
                    //adminDB 조회
                    int cnt = whiteListMapper.getCountByGuid(item.toString());
                    if(cnt == 0 ){
                        whiteList.setGuid(item.toString());
                    }else{
                        throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.ADMINDB_EXIT_ERROR.getMessage());
                    }
                    //gameDB #char isWhiteUser 값 체크
                    Map<String, AttributeValue> whiteAttr = dynamoDBService.getItem("char#" + item, "char#" + item);
                    //guid 검증
                    if(whiteAttr.size() == 0){
                        throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.GUID_CHECK.getMessage());
                    }
                    //화이트리스트 확정까지 보류
//                    boolean isWhiteUser = dynamoDBService.isWhiteOrBlackUser(whiteAttr.get("isWhiteUser"));
//                    if (isWhiteUser) {
//                        throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.DYNAMODB_EXIT_ERROR.getMessage());
//                    }

                    list.add(whiteList);
                }
        );
        return WhiteListResponse.builder()
                .resultData(WhiteListResponse.ResultData.builder()
                        .list(list).message(SuccessCode.EXCEL_UPLOAD.getMessage()).build())
                .status(CommonCode.SUCCESS.getHttpStatus())
                .result(CommonCode.SUCCESS.getResult())
                .build();
    }

    // 단일 등록
    @Transactional(transactionManager = "transactionManager")
    public WhiteListResponse postWhiteList(WhiteListRequest whiteListRequest){
        HashMap<String,Object> map = new HashMap<>();
        Admin admin = CommonUtils.getAdmin();
        map.put("status", WhiteList.STATUS.REJECT);
        map.put("createBy", admin.getId());

        int cnt = whiteListMapper.getCountByGuid(whiteListRequest.getGuid());
        if(cnt > 0 ){
            throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.ADMINDB_EXIT_ERROR.getMessage());
        }
        //gameDB #char isWhiteUser 값 체크
        Map<String, AttributeValue> whiteAttr = dynamoDBService.getItem("user_base#" + whiteListRequest.getGuid()
                , "empty");

        //guid 검증
        if(whiteAttr.size() == 0){
            throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.GUID_CHECK.getMessage());
        }
        //화이트리스트 확정까지 보류
//        boolean isWhiteUser = dynamoDBService.isWhiteOrBlackUser(whiteAttr.get("isWhiteUser"));
//        if (isWhiteUser) {
//            throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.DYNAMODB_EXIT_ERROR.getMessage());
//        }
        map.put("guid",whiteListRequest.getGuid());
        map.put("nickname",dynamoDBService.getNickNameByGuid(whiteListRequest.getGuid()));
        whiteListMapper.postWhiteList(map);

        //dynamoDB char# 테이블에 isWhiteUser : true 값을 insert
        dynamoDBService.insertUpdateData(whiteListRequest.getGuid(),"isWhiteUser",true);
        return WhiteListResponse.builder()
                .resultData(WhiteListResponse.ResultData.builder()
                        .message(SuccessCode.REGISTRATION.getMessage()).build())
                .status(CommonCode.SUCCESS.getHttpStatus())
                .result(CommonCode.SUCCESS.getResult())
                .build();
    }
    //복수 등록
    @Transactional(transactionManager = "transactionManager")
    public WhiteListResponse multiPost(MultipartFile file){
        HashMap<String,Object> map = new HashMap<>();
        // 파일 존재하지 않는 경우
        if (file.isEmpty()) {
            throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.NOT_EXIT_EXCEL.getMessage() );   //Excel 파일을 선택해주세요.
        }

        List<String> listData = excelUtils.getListData(file, 1, 0);

        // 엑셀 파일내 중복된 데이터 있는지 체크
        if(excelUtils.hasDuplicates(listData)){
            throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.DUPLICATE_EXCEL.getMessage() );   //Excel 파일을 선택해주세요.
        }

        Admin admin = CommonUtils.getAdmin();
        map.put("status", WhiteList.STATUS.REJECT);
        map.put("createBy", admin.getId());

        listData.forEach(
                item->{
                    map.put("guid",item.toString());
                    map.put("nickname",dynamoDBService.getNickNameByGuid(item.toString()));
                    whiteListMapper.postWhiteList(map);

                    //dynamoDB char# 테이블에 isWhiteUser : true 값을 insert
                    dynamoDBService.insertUpdateData(item.toString(),"isWhiteUser", true);
                }
        );

        return WhiteListResponse.builder()
                .resultData(WhiteListResponse.ResultData.builder()
                        .message(SuccessCode.REGISTRATION.getMessage()).build())
                .status(CommonCode.SUCCESS.getHttpStatus())
                .result(CommonCode.SUCCESS.getResult())
                .build();
    }
    public void excelDownLoad(HttpServletResponse response){

        // 리스트 다시 가져옴
        List<WhiteList> whiteList = whiteListMapper.getWhiteList();

        String sheetName = "Caliverse_whitelist";

        String headerNames[] = new String[]{"Num","GUID","닉네임","반영상태","등록자(이메일주소)"};

        String[][] bodyDatass = new String[whiteList.size()][5];
        for (int i = 0; i < whiteList.size(); i++) {
            WhiteList entry = whiteList.get(i);
            bodyDatass[i][0] = String.valueOf(entry.getRowNum());
            bodyDatass[i][1] = entry.getGuid();
            bodyDatass[i][2] = entry.getNickname();
            bodyDatass[i][3] = entry.getStatus().name();
            bodyDatass[i][4] = entry.getCreateBy();
        }
        String outfileName = "Caliverse_whitelist";
        try {
            excelUtils.excelDownload(sheetName, headerNames, bodyDatass ,outfileName, response);
        }catch (IOException exception){
            logger.error(exception.getMessage());
        }

    }
    @Transactional(transactionManager = "transactionManager")
    // 승인
    public WhiteListResponse updateWhiteList(WhiteListRequest whiteListRequest){

        whiteListRequest.getList().forEach(
                item->{
                whiteListMapper.updateStatus(item.getId());
            }
        );

        return WhiteListResponse.builder()
                .resultData(WhiteListResponse.ResultData.builder()
                        .message(SuccessCode.UPDATE.getMessage()).build())
                .status(CommonCode.SUCCESS.getHttpStatus())
                .result(CommonCode.SUCCESS.getResult())
                .build();
    }
    @Transactional(transactionManager = "transactionManager")
    public WhiteListResponse deleteWhiteList(WhiteListRequest whiteListRequest){
        Map<String,Object> map = new HashMap<>();
        whiteListRequest.getList().forEach(
                item->{
                    whiteListMapper.deleteWhiteList(item.getId());
                    //로그 기록
                    Map<String,String> resMap = whiteListMapper.getGuidById(item.getId());
                    map.put("adminId",  CommonUtils.getAdmin().getId());
                    map.put("name",  CommonUtils.getAdmin().getName());
                    map.put("mail",  CommonUtils.getAdmin().getEmail());
                    map.put("type", HISTORYTYPE.WHITELIST_DELETE);
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("guid",resMap.get("guid"));
                    jsonObject.put("name",resMap.get("nickname"));
                    map.put("content",jsonObject.toString());
                    historyMapper.saveLog(map);
                    dynamoDBService.insertUpdateData(CommonUtils.objectToString(resMap.get("guid")),"isWhiteUser",false);
                }
        );

        // 리스트 다시 가져옴
        List<WhiteList> whiteList = whiteListMapper.getWhiteList();
        return WhiteListResponse.builder()
                .resultData(WhiteListResponse.ResultData.builder()
                        .list(whiteList).message(SuccessCode.DELETE.getMessage()).build())
                .status(CommonCode.SUCCESS.getHttpStatus())
                .result(CommonCode.SUCCESS.getResult())
                .build();
    }

}
