package com.caliverse.admin.domain.service;

import com.caliverse.admin.domain.entity.REPORTTYPE;
import com.caliverse.admin.domain.entity.SEARCHTYPE;
import com.caliverse.admin.domain.entity.STATUS;
import com.caliverse.admin.domain.request.UserReportRequest;
import com.caliverse.admin.domain.response.UserReportResponse;
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.fasterxml.jackson.core.JsonProcessingException;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class UserReportService {
    private static final Logger logger = LoggerFactory.getLogger(UserReportService.class);

    private final DynamoDBService dynamoDBService;
    public UserReportResponse totalCnt(Map<String,String> requestParam){

        int resolved = 0;
        int unResolved = 0;
        List<UserReportResponse.Report> userReportList = new ArrayList<>();

        userReportList = dynamoDBService.getUserReportList(requestParam);
        Map<Boolean, Long> result = userReportList.stream()
                .collect(Collectors.partitioningBy(
                        val -> val.getState() == STATUS.RESOLVED,
                        Collectors.counting()
                ));

        resolved = result.get(true).intValue();
        unResolved = result.get(false).intValue();

        int totalCnt = userReportList.size();
        return UserReportResponse.builder()
                .resultData(UserReportResponse.ResultData.builder()
                        .totalCnt(totalCnt)
                        .resolve(resolved)
                        .unresolve(unResolved)
                        .rate(totalCnt == 0 ? "0%" : Math.round(resolved * 100.0 / totalCnt) + "%")
                        .build())
                .status(CommonCode.SUCCESS.getHttpStatus())
                .result(CommonCode.SUCCESS.getResult())
                .build();

    }
    public UserReportResponse list(Map<String,String> requestParam){
        List<UserReportResponse.Report> userReportList = new ArrayList<>();
        userReportList = dynamoDBService.getUserReportList(requestParam);

        String reportTypeFilter = CommonUtils.objectToString(requestParam.get("report_type"));
        String statusFilter = CommonUtils.objectToString(requestParam.get("status"));
        String searchType = CommonUtils.objectToString(requestParam.get("search_type"));
        String searchKey = CommonUtils.objectToString(requestParam.get("search_key"));
        String orderby = CommonUtils.objectToString(requestParam.get("orderby"));
        //페이징 처리
        int page = Integer.parseInt(requestParam.get("page_no"));
        int pageSize = Integer.parseInt(requestParam.get("page_size"));

        if (!reportTypeFilter.isEmpty() && !reportTypeFilter.equals("ALL")) {
            userReportList = userReportList.stream()
                    .filter(report -> report.getReportType() == REPORTTYPE.valueOf(reportTypeFilter))
                    .collect(Collectors.toList());
        }

        if (!statusFilter.isEmpty() &&!statusFilter.equals("ALL")) {
            userReportList = userReportList.stream()
                    .filter(report -> report.getState() == STATUS.valueOf(statusFilter))
                    .collect(Collectors.toList());
        }

        if (!searchType.isEmpty() && !searchKey.isEmpty()) {
            userReportList = userReportList.stream()
                    .filter(report -> {
                        if (searchType.equals(SEARCHTYPE.GUID.name())) {
                            return report.getReporterGuid().equals(searchKey);
                        } else if (searchType.equals(SEARCHTYPE.EMAIL.name())) {
                            return report.getManagerEmail().equals(searchKey);
                        }
                        return false;
                    })
                    .sorted(Comparator.comparing(UserReportResponse.Report::getCreateTime))
                    .collect(Collectors.toList());
        }

        if(!orderby.isEmpty()){
            if(orderby.equalsIgnoreCase("desc")){
                userReportList = userReportList.stream()
                        .sorted(Comparator.comparing(UserReportResponse.Report::getCreateTime).reversed())
                        .collect(Collectors.toList());
            }else{
                userReportList = userReportList.stream()
                        .sorted(Comparator.comparing(UserReportResponse.Report::getCreateTime))
                        .collect(Collectors.toList());
            }
        }

        int start = (page - 1) * pageSize;
        int end = Math.min(start + pageSize, userReportList.size());

        userReportList = userReportList.subList(start, end);

        // row_num 추가

        if (orderby.equalsIgnoreCase("desc")){
            for (int i = 0; i < userReportList.size(); i++) {
                userReportList.get(i).setRowNum(i + 1);
            }
        }else{
            int rowNum = userReportList.size();
            for (int i = 0; i < userReportList.size(); i++) {
                userReportList.get(i).setRowNum(rowNum--);
            }
        }
        return UserReportResponse.builder()
                .resultData(UserReportResponse.ResultData.builder()
                        .list(userReportList)
                        .pageNo(page)
                        .total(userReportList.size())
                        .totalAll(userReportList.size())
                        .build())
                .status(CommonCode.SUCCESS.getHttpStatus())
                .result(CommonCode.SUCCESS.getResult())
                .build();

    }
    public UserReportResponse reportDetail(Map<String,String> requestParam){

        UserReportResponse.ResultData userReportDetail = dynamoDBService.getUserReportDetail(requestParam);

        return UserReportResponse.builder()
                .resultData(userReportDetail)
                .status(CommonCode.SUCCESS.getHttpStatus())
                .result(CommonCode.SUCCESS.getResult())
                .build();

    }
    public UserReportResponse replyDetail(Map<String,String> requestParam){

        UserReportResponse.ResultData userReportDetail = dynamoDBService.getUserReplyDetail(requestParam);

        return UserReportResponse.builder()
                .resultData(userReportDetail)
                .status(CommonCode.SUCCESS.getHttpStatus())
                .result(CommonCode.SUCCESS.getResult())
                .build();

    }

    //답변
    public UserReportResponse reportReply(UserReportRequest userReportRequest){

        userReportRequest.setManagerEmail(CommonUtils.getAdmin().getEmail());
        dynamoDBService.reportReply(userReportRequest);

        //신고 내역 상태 및 해결일자 변경
        dynamoDBService.changeReportStatus(userReportRequest);


        return UserReportResponse.builder()
                .resultData(UserReportResponse.ResultData.builder()
                        .message(SuccessCode.SAVE.getMessage())
                        .build())
                .status(CommonCode.SUCCESS.getHttpStatus())
                .result(CommonCode.SUCCESS.getResult())
                .build();

    }
    public void dummy(Map<String, String> map){
        dynamoDBService.dummy(map);
    }
}
