package com.crm.web.controller;

import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.core.constant.StatusConstants;
import com.crm.rely.backend.core.dto.base.BaseResultDto;
import com.crm.rely.backend.core.dto.base.ResultWithPagerDto;
import com.crm.rely.backend.core.entity.base.SingleLongEntity;
import com.crm.rely.backend.core.exception.ServiceException;
import com.crm.rely.backend.model.constant.CustomApplyPassedValid;
import com.crm.rely.backend.model.dto.web.custom.analysis.WebCustomAnalysisInteractionDto;
import com.crm.rely.backend.model.dto.web.custom.analysis.WebCustomAnalysisSearchDto;
import com.crm.rely.backend.model.entity.custom.info.CustomInfoEntity;
import com.crm.rely.backend.model.entity.user.info.UserInfoEntity;
import com.crm.rely.backend.model.entity.web.custom.analysis.*;
import com.crm.rely.backend.service.RedisService;
import com.crm.web.service.CommonService;
import com.crm.web.service.WebCustomAnalysisService;
import com.google.common.base.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author: houn
 */
@RestController
@RequestMapping("/analysis")
public class WebCustomAnalysisController {

    @Autowired
    private WebCustomAnalysisService service;

    @Autowired
    private RedisService redisService;

    @Autowired
    private CommonService commonService;

    @RequestMapping("/get")
    public BaseResultDto get(@RequestBody SingleLongEntity entity) throws ServiceException {
//       String id= request.getParameter("id");
        WebCustomAnalysisSearchDto dto = service.searchSingle(entity.getId());

        if (!StatusConstants.PASSED_STATUS.equals(dto.getStatus())) {
            return BaseResultDto.error(Constants.INFO_NOT_FOUND);
        }
        return BaseResultDto.success(dto);
    }

    @PostMapping("/custom/list")
    public BaseResultDto getResultWebCustomAnalysisSearchList(@Validated @RequestBody WebCustomAnalysisSearchListEntity entity, CustomInfoEntity infoEntity) throws ServiceException {

        validSortName(entity.getSortName());

        if (entity.getPage() == null) {
            return BaseResultDto.error(Constants.PARAMETER_ERROR);
        }
        entity.setPlatformCustomAnalysis(null);
        entity.setCustomId(infoEntity.getId());
        ResultWithPagerDto<WebCustomAnalysisSearchDto> result = service.pageSearchList(entity);

        return result;
    }

    @PostMapping("/custom/other/list")
    public BaseResultDto searchOtherList(@Validated @RequestBody WebCustomAnalysisSearchListEntity entity, CustomInfoEntity infoEntity) throws ServiceException {
        validSortName(entity.getSortName());

        if (entity.getPage() == null) {
            return BaseResultDto.error(Constants.PARAMETER_ERROR);
        }
        entity.setReleaseStatus(1);
        entity.setPlatformCustomAnalysis(1);
        entity.setCustomId(infoEntity.getId());
        ResultWithPagerDto<WebCustomAnalysisSearchDto> result = service.pageSearchList(entity);
        if (result.getData() != null && result.getData().size() > 0) {
            result.getData().forEach(v -> {
                v.setContent(null);
            });
        }
        return result;
    }

    @PostMapping("/custom/single")
    public BaseResultDto customSingle(@RequestBody @Validated SingleLongEntity entity) throws Exception {

        WebCustomAnalysisSearchDto dto = service.searchSingle(entity.getId());

        return BaseResultDto.success(dto);
    }

    /**
     * 添加信息
     *
     * @param entity
     * @param infoEntity
     * @return
     * @throws Exception
     */
    @PostMapping("/custom/add")
    @CustomApplyPassedValid
    public BaseResultDto add(@RequestBody @Validated WebCustomAnalysisAddEntity entity, CustomInfoEntity infoEntity,
                             HttpServletRequest httpServletRequest) throws Exception {
        entity.setCustomId(infoEntity.getId());
        Runnable runnable = () -> {

            service.add(entity);
        };
        redisService.tryLock(infoEntity, httpServletRequest, runnable, "no_repeat_submit_error");

        return BaseResultDto.success();

    }

    @PostMapping("/custom/update")
    public BaseResultDto customUpdate(@RequestBody @Validated WebCustomAnalysisUpdateEntity entity,
                                      CustomInfoEntity infoEntity,
                                      HttpServletRequest httpServletRequest) throws Exception {
        if (!StatusConstants.PASSED_STATUS.equals(infoEntity.getStatus())) {
            return BaseResultDto.error(Constants.NOT_PERMIT);
        }
        entity.setCustomId(infoEntity.getId());
        Runnable runnable = () -> {

            service.update(entity);
        };
        redisService.tryLock(infoEntity, httpServletRequest, runnable, "no_repeat_submit_error");

        return BaseResultDto.success();

    }

    @PostMapping("/custom/reset")
    public BaseResultDto reset(@RequestBody @Validated WebCustomAnalysisUpdateEntity entity, CustomInfoEntity infoEntity,
                               HttpServletRequest httpServletRequest) throws Exception {
        if (!StatusConstants.PASSED_STATUS.equals(infoEntity.getStatus())) {
            return BaseResultDto.error(Constants.NOT_PERMIT);
        }
        entity.setCustomId(infoEntity.getId());
        Runnable runnable = () -> {

            service.update(entity);
        };
        redisService.tryLock(infoEntity, httpServletRequest, runnable, "no_repeat_submit_error");

        return BaseResultDto.success();

    }

    @PostMapping("/custom/delete")
    public BaseResultDto customDelete(@RequestBody @Validated WebCustomAnalysisDeleteEntity entity,
                                      CustomInfoEntity infoEntity) throws Exception {
        if (!StatusConstants.PASSED_STATUS.equals(infoEntity.getStatus())) {
            return BaseResultDto.error(Constants.NOT_PERMIT);
        }
        entity.setCustomId(infoEntity.getId());
        service.delete(entity);
        return BaseResultDto.success();
    }

    @PostMapping("/custom/interaction")
    public BaseResultDto interaction(@RequestBody @Validated WebCustomAnalysisInteractionEntity entity,
                                     CustomInfoEntity infoEntity, HttpServletRequest request) throws Exception {

        if (!StatusConstants.PASSED_STATUS.equals(infoEntity.getStatus())) {
            return BaseResultDto.error(Constants.NOT_PERMIT);
        }
        //如果都为空或者都不为空 则参数异常
        if (entity.getAgree() == null && entity.getVeto() == null) {
            return BaseResultDto.error(Constants.PARAMETER_ERROR);
        }
        if (entity.getAgree() != null && entity.getVeto() != null) {
            return BaseResultDto.error(Constants.PARAMETER_ERROR);
        }
        entity.setCustomId(infoEntity.getId());
        AtomicReference<WebCustomAnalysisInteractionDto> reference = new AtomicReference<>();
        Runnable runnable = () -> {
            WebCustomAnalysisInteractionDto dto = service.interaction(entity);
            reference.set(dto);
        };
        redisService.tryLock(infoEntity, request, runnable, "no_repeat_submit_error");
        return BaseResultDto.success(reference.get());
    }

    /**
     * 删除信息
     *
     * @param entity
     * @return
     * @throws Exception
     */
    @PostMapping("/manager/delete")
    public BaseResultDto delete(@RequestBody @Validated WebCustomAnalysisDeleteEntity entity, UserInfoEntity infoEntity) throws Exception {
        entity.setCustomId(null);
        service.delete(entity);
        return BaseResultDto.success();
    }

    /**
     * 修改信息
     *
     * @param entity
     * @return
     * @throws Exception
     */
    @PostMapping("/manager/update")
    public BaseResultDto update(@RequestBody @Validated WebCustomAnalysisManagerUpdateNumEntity entity, UserInfoEntity infoEntity) throws Exception {

        if (entity.getAgreeNum() == null) {
            entity.setAgreeNum(0);
        }
        if (entity.getVetoNum() == null) {
            entity.setVetoNum(0);
        }
        if (entity.getReleaseDayAgreeNum() == null) {
            entity.setReleaseDayAgreeNum(0);
        }
        if (entity.getReleaseDayVetoNum() == null) {
            entity.setReleaseDayVetoNum(0);
        }
        if (entity.getTopping() == null) {
            entity.setTopping(0);
        }
        service.update(entity);
        return BaseResultDto.success();
    }

    /**
     * @param entity
     * @return
     * @throws Exception
     */
    @PostMapping("/manager/search/list")
    public ResultWithPagerDto<WebCustomAnalysisSearchDto> pageSearchList(@RequestBody @Validated WebCustomAnalysisSearchListEntity entity, UserInfoEntity infoEntity) throws Exception {

        validSortName(entity.getSortName());
        ResultWithPagerDto<WebCustomAnalysisSearchDto> result = service.pageSearchList(entity);

        return result;
    }

    @PostMapping("/manager/search/single")
    public BaseResultDto<WebCustomAnalysisSearchDto> single(@RequestBody @Validated SingleLongEntity entity, UserInfoEntity infoEntity) throws Exception {

        WebCustomAnalysisSearchDto dto = service.searchSingle(entity.getId());

        return BaseResultDto.success(dto);
    }

    @PostMapping("/manager/approve")
    public BaseResultDto<WebCustomAnalysisSearchDto> approve(@RequestBody @Validated WebCustomAnalysisApproveEntity entity,
                                                             UserInfoEntity infoEntity) throws
            Exception {
        if (entity.getAgreeNum() == null) {
            entity.setAgreeNum(0);
        }
        if (entity.getVetoNum() == null) {
            entity.setVetoNum(0);
        }
        if (entity.getReleaseDayAgreeNum() == null) {
            entity.setReleaseDayAgreeNum(0);
        }
        if (entity.getReleaseDayVetoNum() == null) {
            entity.setReleaseDayVetoNum(0);
        }
        if (entity.getTopping() == null) {
            entity.setTopping(0);
        }

        service.approve(entity);

        return BaseResultDto.success();
    }

    @PostMapping("/custom/upload")
    public BaseResultDto customUpload(@RequestParam(value = "file", required = false) MultipartFile file,
                                      CustomInfoEntity infoEntity) throws Exception {
        String middlePath = "/analysis/" + infoEntity.getId();
        commonService.validated(file);
        String path = commonService.uploadFile(middlePath, file);
        return BaseResultDto.success(Constants.UPLOAD_SUCCESS, path);
    }

    @PostMapping("/manager/upload")
    public BaseResultDto upload(@RequestParam(value = "file", required = false) MultipartFile file) throws Exception {
        String middlePath = "/analysis";
        commonService.validated(file);
        String path = commonService.uploadFile(middlePath, file);
        return BaseResultDto.success(Constants.UPLOAD_SUCCESS, path);
    }

    private void validSortName(String sortName) {
        if (!Strings.isNullOrEmpty(sortName)) {
            List<String> tableFields = new ArrayList<>(20);
            tableFields.add("id");
            tableFields.add("custom_id");
            tableFields.add("title");
            tableFields.add("sub_title");
            tableFields.add("cover_image");
            tableFields.add("content");
            tableFields.add("topping");
            tableFields.add("agree_num");
            tableFields.add("veto_num");
            tableFields.add("total_interaction");
            tableFields.add("release_day_agree_num");
            tableFields.add("release_day_veto_num");
            tableFields.add("total_release_day_interaction");
            tableFields.add("status");
            tableFields.add("add_time");
            tableFields.add("add_user");
            tableFields.add("add_ip");
            tableFields.add("modify_time");
            tableFields.add("modify_user");
            tableFields.add("modify_ip");
            tableFields.add("note");
            tableFields.add("approve_user");
            tableFields.add("approve_time");
            tableFields.add("approve_desc");
            if (!tableFields.contains(sortName)) {
                throw ServiceException.exception(Constants.FAIL);
            }
        }
    }
}
