package cn.axzo.msg.center.message.controller;

import cn.axzo.msg.center.api.response.MessageDetailRes;
import cn.axzo.msg.center.message.domain.param.MessageGroupNodeStatisticParam;
import cn.axzo.msg.center.message.domain.param.PendingMessagePushParam;
import cn.axzo.msg.center.message.service.PendingMessageNewService;
import cn.axzo.msg.center.message.service.todo.TodoRangeQueryService;
import cn.axzo.msg.center.message.service.todo.TodoSimpleQueryService;
import cn.axzo.msg.center.message.service.todo.TodoWorkerQueryService;
import cn.axzo.msg.center.message.service.todo.manage.TodoManager;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import cn.axzo.msg.center.service.enums.TodoQueryType;
import cn.axzo.msg.center.service.enums.TodoType;
import cn.axzo.msg.center.service.pending.client.PendingMessageClient;
import cn.axzo.msg.center.service.pending.request.CompletePendingBySubCodeRequest;
import cn.axzo.msg.center.service.pending.request.CompletePendingMessageByIdRequest;
import cn.axzo.msg.center.service.pending.request.CompletePendingMessageRequest;
import cn.axzo.msg.center.service.pending.request.PendingMessageByBizCodeRequest;
import cn.axzo.msg.center.service.pending.request.PendingMessageCountUncompletedRequest;
import cn.axzo.msg.center.service.pending.request.PendingMessageFixedTemplatePageRequest;
import cn.axzo.msg.center.service.pending.request.PendingMessageIterateRequest;
import cn.axzo.msg.center.service.pending.request.PendingMessagePageRequest;
import cn.axzo.msg.center.service.pending.request.PendingMessagePushRequest;
import cn.axzo.msg.center.service.pending.request.PendingMessageQueryRequest;
import cn.axzo.msg.center.service.pending.request.PendingMessageStatisticForWorkerRequest;
import cn.axzo.msg.center.service.pending.request.PendingMessageStatisticRequest;
import cn.axzo.msg.center.service.pending.request.PersonTodoToBeDoneStatRequest;
import cn.axzo.msg.center.service.pending.request.PresetButtonPressedRequest;
import cn.axzo.msg.center.service.pending.request.RevokePendingMessageByIdRequest;
import cn.axzo.msg.center.service.pending.request.SetHideRequest;
import cn.axzo.msg.center.service.pending.request.TodoHandoverRequest;
import cn.axzo.msg.center.service.pending.request.UpdateBusinessFinalBizStateRequest;
import cn.axzo.msg.center.service.pending.request.UpdatePendingMessageByIdRequest;
import cn.axzo.msg.center.service.pending.response.AnalysisPage;
import cn.axzo.msg.center.service.pending.response.PendingMessageIterateResponse;
import cn.axzo.msg.center.service.pending.response.PendingMessageResponse;
import cn.axzo.msg.center.service.pending.response.PendingMessageSimpleDTO;
import cn.axzo.msg.center.service.pending.response.PendingMessageStatisticResponse;
import cn.axzo.msg.center.service.pending.response.PendingMessageStatisticResponseV2;
import cn.axzo.msg.center.service.pending.response.PersonTodoToBeDoneStatResponse;
import cn.axzo.msg.center.service.pending.response.PushPendingMessageDTO;
import cn.azxo.framework.common.model.CommonResponse;
import cn.azxo.framework.common.model.Page;
import cn.hutool.core.date.StopWatch;
import com.alibaba.fastjson.JSON;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author cold_blade
 * @version 1.0
 * @description
 * @date 2023/10/5
 */
@Slf4j
@RestController
@RequiredArgsConstructor
public class PendingMessageNewController implements PendingMessageClient {

    private final PendingMessageNewService pendingMessageNewService;
    private final TodoManager todoManager;
    private final TodoRangeQueryService todoRangeQueryService;
    private final TodoSimpleQueryService todoSimpleQueryService;
    private final TodoWorkerQueryService todoWorkerQueryService;

    @Override
    public CommonResponse<List<PendingMessageStatisticResponse>> groupStatistic(PendingMessageStatisticRequest request) {
        // dummy
        return CommonResponse.success(Collections.emptyList());
    }

    @Override
    public CommonResponse<PendingMessageStatisticResponseV2> groupStatisticV2(PendingMessageStatisticRequest request) {
        PendingMessageStatisticResponseV2 resp = todoRangeQueryService
                .countStatGrouped(MessageGroupNodeStatisticParam.from(request));
        return CommonResponse.success(resp);
    }

    @Override
    public CommonResponse<PendingMessageStatisticResponseV2> groupStatisticForWorker(
            PendingMessageStatisticForWorkerRequest request) {
        PendingMessageStatisticResponseV2 resp = todoWorkerQueryService.countStatGroupedForWorker(request);
        return CommonResponse.success(resp);
    }

    @Override
    public CommonResponse<Integer> countUncompleted(PendingMessageCountUncompletedRequest request) {
        log.info("countUncompleted, request={}", JSON.toJSONString(request));
        Integer count = todoRangeQueryService.countStat(MessageGroupNodeStatisticParam.from(request));
        return CommonResponse.success(count);
    }

    @Override
    public CommonResponse<AnalysisPage<PendingMessageResponse>> pageQuery(PendingMessagePageRequest request) {
        log.info("pageQuery, request={}", JSON.toJSONString(request));
        StopWatch stopWatch = new StopWatch("todo-pageQuery");
        stopWatch.start("total");
        try {
            return CommonResponse.success(todoRangeQueryService.pageQuery(request));
        } finally {
            stopWatch.stop();
            log.info(stopWatch.prettyPrint(TimeUnit.MILLISECONDS));
        }
    }

    @Override
    public CommonResponse<PersonTodoToBeDoneStatResponse> personTodoToBeDoneStat(PersonTodoToBeDoneStatRequest request) {
        log.info("personTodoToBeDoneStat, request={}", JSON.toJSONString(request));
        PersonTodoToBeDoneStatResponse resp = todoRangeQueryService.personTodoToBeDoneStat(request);
        return CommonResponse.success(resp);
    }

    @Override
    public CommonResponse<Integer> handover(TodoHandoverRequest request) {
        log.info("handover, request={}", JSON.toJSONString(request));
        int count = todoManager.handover(request);
        return CommonResponse.success(count);
    }

    @Override
    public CommonResponse<List<PendingMessageResponse>> getPendingMessageByAppWorker(PendingMessageFixedTemplatePageRequest request) {
        log.info("getPendingMessageByAppWorker, request={}", JSON.toJSONString(request));
        return CommonResponse.success(todoWorkerQueryService.getWorkerCalendar(request));
    }

    @Override
    public CommonResponse<Page<MessageDetailRes>> compatiblePageQuery(PendingMessagePageRequest request) {
        return CommonResponse.success(pendingMessageNewService.compatiblePageQuery(request));
    }

    @Override
    public CommonResponse<PendingMessageResponse> query(PendingMessageQueryRequest request) {
        log.info("query, request={}", JSON.toJSONString(request));
        PendingMessageResponse resp = todoSimpleQueryService.query(request);
        if (resp != null)
            resp.setQueryType(request.getQueryType());
        return CommonResponse.success(resp);
    }

    @Override
    public CommonResponse<PendingMessageResponse> detail(
            String msgIdentityCode, TerminalTypeEnum terminalType, TodoQueryType queryType) {
        PendingMessageResponse response = todoSimpleQueryService.getDetail(msgIdentityCode, terminalType, queryType);
        return CommonResponse.success(response);
    }

    @Override
    public CommonResponse<PendingMessageResponse> getLatestTodoByBiz(
            String templateCode, String bizCode, String subBizCode, String todoType) {
        PendingMessageResponse response = todoSimpleQueryService
                .getLatestTodoByBiz(templateCode, bizCode, subBizCode, TodoType.valueOf(todoType));
        return CommonResponse.success(response);
    }

    @Override
    public CommonResponse<List<PushPendingMessageDTO>> push(PendingMessagePushRequest request) {
        log.info("push, request={}", JSON.toJSONString(request));
        return CommonResponse.success(todoManager.send(PendingMessagePushParam.from(request)));
    }

    @Override
    public CommonResponse<Page<PendingMessageIterateResponse>> iterate(PendingMessageIterateRequest request) {
        return CommonResponse.success(pendingMessageNewService.iterate(request));
    }

    @Override
    public CommonResponse<Boolean> complete(String requestNo) {
        log.info("complete, request={}", JSON.toJSONString(requestNo));
        return CommonResponse.success(todoManager.completeByRequestNo(requestNo));
    }

    @Override
    public CommonResponse<Boolean> completeById(CompletePendingMessageByIdRequest param) {
        log.info("completeById, request={}", JSON.toJSONString(param));
        return CommonResponse.success(todoManager.completeById(param));
    }

    @Override
    public CommonResponse<Boolean> revoke(String requestNo) {
        log.info("revoke, request={}", requestNo);
        return CommonResponse.success(todoManager.revokeByRequestNo(requestNo));
    }

    @Override
    public CommonResponse<Boolean> revokeByMsgId(String msgId) {
        log.info("revokeByMsgId, request={}", msgId);
        return CommonResponse.success(todoManager.revokeByIdCode(msgId));
    }

    @Override
    public CommonResponse<Boolean> completeByTemplateCodeBizCode(CompletePendingMessageRequest param) {
        log.info("completeByTemplateCodeBizCode, request={}", JSON.toJSONString(param));
        return CommonResponse.success(todoManager.completeByBizCode(param));
    }

    @Override
    public CommonResponse<Boolean> updateBusinessFinalBizState(UpdateBusinessFinalBizStateRequest param) {
        log.info("updateBusinessFinalBizState, request={}", JSON.toJSONString(param));
        return CommonResponse.success(todoManager.updateBusinessFinalBizState(param));
    }

    @Override
    public CommonResponse<Boolean> completeByTemplateCodeSubBizCode(CompletePendingBySubCodeRequest param) {
        log.info("completeByTemplateCodeSubBizCode, request={}", JSON.toJSONString(param));
        return CommonResponse.success(todoManager.completeBySubBizCode(param));
    }

    @Override
    public CommonResponse<Boolean> rollbackTemplateCodeSubBizCode(@RequestBody @Valid CompletePendingBySubCodeRequest param) {
        log.info("rollbackByTemplateCodeSubBizCode, request={}", JSON.toJSONString(param));
        return CommonResponse.success(todoManager.rollbackBySubBizCode(param));
    }

    @Override
    public CommonResponse<Boolean> revokeByTemplateCodeBizCode(CompletePendingMessageRequest param) {
        log.info("revokeByTemplateCodeBizCode, request={}", JSON.toJSONString(param));
        return CommonResponse.success(todoManager.revokeByBizCode(param));
    }

    @Override
    public CommonResponse<Boolean> revokeById(RevokePendingMessageByIdRequest param) {
        log.info("revokeById, request={}", JSON.toJSONString(param));
        return CommonResponse.success(todoManager.revokeById(param));
    }

    @Override
    public CommonResponse<Boolean> updateById(UpdatePendingMessageByIdRequest param) {
        log.info("updateById, request={}", JSON.toJSONString(param));
        return CommonResponse.success(todoManager.updateBusinessById(param));
    }

    @Override
    public CommonResponse<List<PendingMessageSimpleDTO>> getLatestByBizCode(PendingMessageByBizCodeRequest param) {
        log.info("getLatestByBizCode, request={}", JSON.toJSONString(param));
        return CommonResponse.success(todoSimpleQueryService.getLatestTodosByBiz(param));
    }

    @Override
    public CommonResponse<Boolean> setHide(SetHideRequest req) {
        log.info("setHide, request={}", JSON.toJSONString(req));
        Boolean response = null;
        try {
            response = todoManager.setHide(req);
            return CommonResponse.success(response);
        } finally {
            log.info("setHide. request={}, response={}", req, response);
        }
    }

    @Override
    public CommonResponse<Boolean> batchSetProcessing(List<String> identityCodes) {
        log.info("setProcessing, request={}", JSON.toJSONString(identityCodes));
        Boolean result = null;
        try {
            result = todoManager.batchSetProcessing(identityCodes, null);
            return CommonResponse.success(result);
        } finally {
            log.info("setProcessing. request={}, response={}", identityCodes, result);
        }
    }

    @Override
    public CommonResponse<Boolean> batchSetProcessingByBizCodes(List<String> subBizCodes) {
        log.info("setProcessing, request={}", JSON.toJSONString(subBizCodes));
        Boolean result = null;
        try {
            result = todoManager.batchSetProcessing(null, subBizCodes);
            return CommonResponse.success(result);
        } finally {
            log.info("setProcessing. request={}, response={}", subBizCodes, result);
        }
    }

    @Override
    public CommonResponse<Boolean> firePresetButtonPressed(PresetButtonPressedRequest req) {
        log.info("firePresetButtonPressed, request={}", JSON.toJSONString(req));
        boolean result = todoManager.firePresetButtonPressed(req);
        // 产品要求提示信息
        return CommonResponse.success(200, "处理成功", result);
    }

    @Override
    public CommonResponse<Boolean> setCopiedToMeRead(Long personId, String identityCode) {
        log.info("setReadOnlyRead, personId={}, identityCode={}", personId, identityCode);
        boolean result = todoManager.setCopiedToMeRead(personId, identityCode);
        return CommonResponse.success(result);
    }
}
