package com.caliverse.admin.domain.service;

import com.caliverse.admin.domain.dao.admin.GroupMapper;
import com.caliverse.admin.domain.dao.admin.HistoryMapper;
import com.caliverse.admin.domain.entity.*;
import com.caliverse.admin.domain.request.GroupRequest;
import com.caliverse.admin.domain.response.GroupResponse;
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 lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONObject;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Slf4j
@Service
@RequiredArgsConstructor
public class GroupService {

    private final GroupMapper groupMapper;
    private final HistoryMapper historyMapper;


    // 관리자 권한 리스트 조회
    public GroupResponse getAllGroups(){

        Map map = new HashMap();
        List<Groups> getGroupList = groupMapper.getGroupList(map);

        return GroupResponse.builder()
                .status(CommonCode.SUCCESS.getHttpStatus())
                .result(CommonCode.SUCCESS.getResult())
                .resultData(GroupResponse.ResultData.builder().groupList(getGroupList).build())
                .build();
    }

    /**
     * param: orderby
     * param: page
     * return GroupResponse.list
     */
    // 권한 설정 화면 리스트 조회
    public GroupResponse getGroupList(Map requestMap){

        //페이징 처리
        requestMap = CommonUtils.pageSetting(requestMap);

        List<Groups> groupList = groupMapper.getGroupList(requestMap);

        int allCnt = groupMapper.getAllCnt();
        return GroupResponse.builder()
                .resultData(GroupResponse.ResultData.builder()
                        .groupList(groupList)
                        .total(allCnt)
                        .totalAll(allCnt)
                        .pageNo(requestMap.get("page_no")!=null?
                                Integer.valueOf(requestMap.get("page_no").toString()):1)
                        .build())
                .status(CommonCode.SUCCESS.getHttpStatus())
                .result(CommonCode.SUCCESS.getResult())
                .build();
    }

    // 권한 설정 상세 조회
    public GroupResponse getGroupDetail(String groupId){

        Long lid = Long.valueOf(groupId);
        List<Authority> authorityList = groupMapper.getGroupAuth(lid);
        return GroupResponse.builder()
                .resultData(GroupResponse.ResultData.builder()
                        .authorityList(authorityList)
                        .groupId(lid)
                        .groupNm(groupMapper.getGroupInfo(lid).get("name"))
                        .build())
                .status(CommonCode.SUCCESS.getHttpStatus())
                .result(CommonCode.SUCCESS.getResult())
                .build();
    }

    //권한 그룹 등록
    public GroupResponse postAdminGroup(GroupRequest groupRequest){
        List<Integer> authList = Arrays.asList(1, 5, 6, 9, 10, 11, 13, 14, 15, 16, 19, 22, 24, 26, 32); //그룹 초기 권한
        Map<String, Object> map = new HashMap<>();
        groupRequest.setCreateBy(CommonUtils.getAdmin().getId());

        int groupName = groupMapper.findGroupName(groupRequest.getGroupNm());

        if(groupName == 0){
            groupMapper.postAdminGroup(groupRequest);

            map.put("groupId", groupRequest.getId());
            authList.forEach(val->{
                map.put("authId",val);
                groupMapper.insertGroupAuth(map);
            });
        }else{
            throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.DUPLICATED_GROUPNAME.getMessage());
        }

        log.info("postAdminGroup group: {}",map);

        return GroupResponse.builder()
                .status(CommonCode.SUCCESS.getHttpStatus())
                .result(CommonCode.SUCCESS.getResult())
                .resultData(GroupResponse.ResultData.builder().message(SuccessCode.SAVE.getMessage()).build())
                .build();
    }
    //그룹 권한 수정
    @Transactional(transactionManager = "transactionManager")
    public GroupResponse updateAdminGroup(String groupId,GroupRequest groupRequest){

        Map<String , Object> map = new HashMap<>();
        //로그 남기 before 그룹 설정
        List<Authority> beforeAuth = groupMapper.getGroupAuth(Long.valueOf(groupId));
        log.info("updateAdminGroup before::{}",beforeAuth);

        // group_auth 테이블 삭제 By groupId
        groupMapper.deleteGroupAuth(groupId);

        groupRequest.getGroupList().forEach(
                item-> {
                    map.put("authId", item.getAuthId());
                    map.put("groupId", groupId);
                    groupMapper.insertGroupAuth(map);
                }
        );
        //로그 남기 before 그룹 설정
        List<Authority> afterAuth = groupMapper.getGroupAuth(Long.valueOf(groupId));
        log.info("updateAdminGroup after::{}",afterAuth);
        //로그 기록
        map.put("adminId",  CommonUtils.getAdmin().getId());
        map.put("name",  CommonUtils.getAdmin().getName());
        map.put("mail",  CommonUtils.getAdmin().getEmail());
        map.put("type", HISTORYTYPE.GROUP_AUTH_UPDATE);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("groupNm",groupMapper.getGroupInfo(Long.valueOf(groupId)).get("name"));
        jsonObject.put("auth(before)",beforeAuth);
        jsonObject.put("auth(after)",afterAuth);
        map.put("content",jsonObject.toString());
        historyMapper.saveLog(map);

        return GroupResponse.builder()
                .status(CommonCode.SUCCESS.getHttpStatus())
                .result(CommonCode.SUCCESS.getResult())
                .resultData(GroupResponse.ResultData.builder().message(SuccessCode.UPDATE.getMessage()).build())
                .build();
    }
    //그룹 삭제
    @Transactional(transactionManager = "transactionManager")
    public GroupResponse deleteAdminGroup(GroupRequest groupRequest){
        Map<String, Object> map = new HashMap();
        groupRequest.getGroupList().forEach(
                item-> {
                    //순서 바뀜 안됨, 삭제 하기전 그룹명 가져오기
                    Map<String, String> groupInfo = groupMapper.getGroupInfo(item.getGroupId());

                    groupMapper.deleteGroup(item.getGroupId());
                    //로그 기록
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("groupNm",groupInfo.get("name"));

                    map.put("adminId",  CommonUtils.getAdmin().getId());
                    map.put("name",  CommonUtils.getAdmin().getName());
                    map.put("mail",  CommonUtils.getAdmin().getEmail());
                    map.put("type", HISTORYTYPE.GROUP_DELETE);
                    map.put("content",jsonObject.toString());
                    historyMapper.saveLog(map);
                }
        );
        log.info("deleteAdminGroup group: {}", map);

        return GroupResponse.builder()
                .status(CommonCode.SUCCESS.getHttpStatus())
                .result(CommonCode.SUCCESS.getResult())
                .resultData(GroupResponse.ResultData.builder().message(SuccessCode.DELETE.getMessage()).build())
                .build();
    }

}
