package com.zm.order.tool.server.controller;

import com.aliyun.openservices.shade.com.google.common.base.Throwables;
import com.github.dozermapper.core.Mapper;
import com.zm.order.tool.server.convert.AdminOrderConverter;
import com.zm.order.tool.server.manager.RedisManager;
import com.zm.order.tool.server.dto.LineUpRecordDTO;
import com.zm.order.tool.server.dto.OrderOperateDTO;
import com.zm.order.tool.server.dto.OrderSimpleDTO;
import com.zm.order.tool.server.dto.RefundDetailDTO;
import com.zm.order.tool.server.dto.ToolInterfaceDTO;
import com.zm.order.tool.server.dto.UpdateCompletedAtDTO;
import com.zm.order.tool.server.query.AdminOrderItemQuery;
import com.zm.order.tool.server.query.AdminOrderQuery;
import com.zm.order.tool.server.query.OrderOperationQuery;
import com.zm.order.tool.server.query.OrderQuery;
import com.zm.order.tool.server.query.RefundQuery;
import com.zm.order.tool.server.query.SearchOrderQuery;
import com.zm.order.tool.server.request.*;
import com.zm.order.tool.server.request.CreateToolInterfaceRequest;
import com.zm.order.tool.server.request.GetRefundDetailRequest;
import com.zm.order.tool.server.request.ListOrderOperationsRequest;
import com.zm.order.tool.server.request.ListOrderSimpleRequest;
import com.zm.order.tool.server.request.ListOrderSycRequest;
import com.zm.order.tool.server.request.OrderSycRequest;
import com.zm.order.tool.server.request.SearchOrderCountRequest;
import com.zm.order.tool.server.request.CompletedAtRequest;
import com.zm.order.tool.server.response.LineUpRecordVO;
import com.zm.order.tool.server.response.OrderOperateVO;
import com.zm.order.tool.server.response.OrderSimpleVo;
import com.zm.order.tool.server.response.RefundDetailVO;
import com.zm.order.tool.server.response.ToolInterfaceVO;
import com.zm.order.tool.server.response.UpdateCompletedAtVO;
import com.zm.order.tool.server.service.AdminOrderService;
import com.zm.order.tool.server.service.ExceptionConstants;
import com.zm.order.tool.server.service.impl.AdminOrderServiceImpl;
import com.zm.order.tool.server.utils.ConvertUtils;
import com.zm.util.dto.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Objects;

/**
 * @Description say something
 * @Author: ph
 * @Date: 2019/12/18 15:54
 */
@Api(value = "管理员订单", tags = "管理员服务")
@RestController
@RequestMapping("/qapi/order/admin")
public class AdminController {

    private static final Logger logger = LoggerFactory.getLogger(AdminController.class);

    @Autowired
    private Mapper mapper;

    @Autowired
    private AdminOrderConverter converter;

    @Autowired
    private AdminOrderService adminOrderService;

    @Autowired
    private RedisManager redisManager;


    private static final String GUESS_LIKE_SWITCH = "guess:like:switch";

    private static final String LEVEL_DOWN_SWITCH_ES_COUNT = "level:down:switch:es:count";


    @ApiOperation("订单同步到ES")
    @RequestMapping(value = "/order/syc", method = RequestMethod.POST)
    public Result orderSycEs(@RequestBody OrderSycRequest request) {
        Result result = new Result();
        try {
            AdminOrderQuery query = mapper.map(request, AdminOrderQuery.class);
            Result getResult = adminOrderService.orderSync(query);
            if (!getResult.isStatus()) {
                getResult.setException(getResult.exceptionInfo());
                return getResult;
            }
            result.setData(getResult.getData());
            result.setStatus(true);
        } catch (Throwable throwable) {
            logger.error("AdminController[orderSycEs] failed, request:{}, cause by:{}",
                    request.toString(), Throwables.getStackTraceAsString(throwable));
            result.setException(ExceptionConstants.SYSTEM_ERROR);
        }

        return result;
    }

    @ApiOperation("订单批量同步到ES")
    @RequestMapping(value = "list/order/syc", method = RequestMethod.POST)
    public Result<List<String>> orderSycEs(@RequestBody ListOrderSycRequest request) {
        Result<List<String>> result = new Result<>();
        try {
            AdminOrderQuery query = mapper.map(request, AdminOrderQuery.class);
            result = adminOrderService.listOrderSync(query);
        } catch (Throwable throwable) {
            logger.error("AdminController[orderSycEs] failed, request:{}, cause by:{}",
                    request.toString(), Throwables.getStackTraceAsString(throwable));
            result.setException(ExceptionConstants.SYSTEM_ERROR);
        }

        return result;
    }

    @ApiOperation("查看订单操作日志")
    @RequestMapping(value = "/operations", method = RequestMethod.POST)
    public Result<List<OrderOperateVO>> listOperation(@RequestBody ListOrderOperationsRequest request) {
        Result<List<OrderOperateVO>> result = new Result<>();
        logger.info(" request:{}", request.toString());
        try {
            OrderOperationQuery query = mapper.map(request, OrderOperationQuery.class);

            Result<List<OrderOperateDTO>> getResult = adminOrderService.getListOrderOperate(query);
            if (!getResult.isStatus()) {
                result.setException(getResult.exceptionInfo());
                return result;
            }
            List<OrderOperateDTO> data = getResult.getData();
            List<OrderOperateVO> orderOperateVO = converter.convertOrderOperationVO(data);
            result.setData(orderOperateVO);
            result.setStatus(true);
        } catch (Throwable throwable) {
            logger.error("AdminController[listOperation] failed, request:{}, cause by:{}",
                    request.toString(), Throwables.getStackTraceAsString(throwable));
            result.setException(ExceptionConstants.SYSTEM_ERROR);
        }
        return result;
    }

    @ApiOperation("统计订单数量")
    @RequestMapping(value = "/count/search", method = RequestMethod.POST)
    public Result<Integer> searchOrderCount(@RequestBody SearchOrderCountRequest request) {
        Result<Integer> result = new Result<>();
        try {
            SearchOrderQuery searchOrderQuery = mapper.map(request, SearchOrderQuery.class);
            result = adminOrderService.searchOrderCount(searchOrderQuery);
        } catch (Throwable throwable) {
            logger.error("AdminController[searchCountOrder] failed, request:{}, cause by:{}",
                    request.toString(), Throwables.getStackTraceAsString(throwable));
            result.setException(ExceptionConstants.SYSTEM_ERROR);
        }
        return result;
    }

    @ApiOperation("查询订单排队信息")
    @RequestMapping(value = "/lineUpRecord", method = RequestMethod.POST)
    public Result<List<LineUpRecordVO>> searchLineUpRecords(@RequestBody ListOrderSimpleRequest request) {
        Result<List<LineUpRecordVO>> result = new Result<>();
        try {
            AdminOrderItemQuery adminOrderItemQuery = mapper.map(request, AdminOrderItemQuery.class);
            Result<List<LineUpRecordDTO>> getResult = adminOrderService.searchLineUpRecordOrder(adminOrderItemQuery);
            if (!getResult.isStatus()) {
                result.setException(getResult.exceptionInfo());
                return result;
            }
            List<LineUpRecordVO> vo = converter.convertToLineUpVO(getResult.getData());
            result.setData(vo);
            result.setStatus(true);
        } catch (Throwable throwable) {
            logger.error("AdminController[searchLineUpRecords] failed, request:{}, cause by: {}",
                    request.toString(), Throwables.getStackTraceAsString(throwable));
            result.setException(ExceptionConstants.SYSTEM_ERROR);
        }
        return result;

    }

    @ApiOperation("创建接口信息")
    @RequestMapping(value = "/create/toolInterface", method = RequestMethod.POST)
    public Result<Long> createToolInterface(@RequestBody CreateToolInterfaceRequest request) {
        Result<Long> result = new Result<>();
        try {
            ToolInterfaceDTO toolInterfaceDTO = converter.convert(request);
            result = adminOrderService.createToolInterface(toolInterfaceDTO);
        } catch (Throwable throwable) {
            logger.error("AdminController[createToolInterface] failed, request:{}, cause by: {}",
                    request.toString(), Throwables.getStackTraceAsString(throwable));
            result.setException(ExceptionConstants.SYSTEM_ERROR);
        }
        return result;
    }

    @ApiOperation("查询接口信息")
    @RequestMapping(value = "/list/toolInterface", method = RequestMethod.POST)
    public Result<List<ToolInterfaceVO>> listToolInterface() {
        Result<List<ToolInterfaceVO>> result = new Result<>();
        try {
            Result<List<ToolInterfaceDTO>> listResult = adminOrderService.listToolInterface();
            if (!listResult.isStatus()) {
                result.setException(listResult.exceptionInfo());
                return result;
            }
            List<ToolInterfaceVO> voList = converter.convertToToolInterfaceVO(listResult.getData());
            result.setData(voList);
            result.setStatus(true);
        } catch (Throwable throwable) {
            logger.error("AdminController[listToolInterface] failed, request:{}, cause by: {}",
                    Throwables.getStackTraceAsString(throwable));
            result.setException(ExceptionConstants.SYSTEM_ERROR);
        }
        return result;
    }

    @ApiOperation("查看退款单详情")
    @RequestMapping(value = "/refund/detail", method = RequestMethod.POST)
    public Result<List<RefundDetailVO>> getRefundDetail(@RequestBody GetRefundDetailRequest request) {
        Result<List<RefundDetailVO>> result = new Result<>();
        try {
            RefundQuery query = mapper.map(request, RefundQuery.class);
            Result<List<RefundDetailDTO>> getResult = adminOrderService.getRefundDetail(query);
            if (!getResult.isStatus()) {
                result.setException(getResult.exceptionInfo());
                return result;
            }
            List<RefundDetailDTO> refundDetailDtoList = getResult.getData();
            List<RefundDetailVO> voList = converter.convert2DetailList(refundDetailDtoList);
            result.setData(voList);
            result.setStatus(true);
        } catch (Throwable throwable) {
            logger.error("RefundController[getRefundDetail] failed, request:{}, cause by: {}",
                    request.toString(), com.google.common.base.Throwables.getStackTraceAsString(throwable));
        }
        return result;
    }

    @ApiOperation("查询订单门店排队订单信息")
    @RequestMapping(value = "/lineUpRecord/toOrder", method = RequestMethod.POST)
    public Result<List<OrderSimpleVo>> searchLineUpOrder(@RequestBody ListOrderSimpleRequest request) {
        Result<List<OrderSimpleVo>> result = new Result<>();
        try {
            AdminOrderItemQuery adminOrderItemQuery = mapper.map(request, AdminOrderItemQuery.class);
            Result<List<OrderSimpleDTO>> getResult = adminOrderService.searchLineUpRecOrder(adminOrderItemQuery);
            if (!getResult.isStatus()) {
                result.setException(getResult.exceptionInfo());
                return result;
            }
            List<OrderSimpleVo> vo = converter.convertToOrderSimpleVO(getResult.getData());
            result.setData(vo);
            result.setStatus(true);
        } catch (Throwable throwable) {
            logger.error("AdminController[searchLineUpRecords] failed, request:{}, cause by: {}",
                    request.toString(), Throwables.getStackTraceAsString(throwable));
            result.setException(ExceptionConstants.SYSTEM_ERROR);
        }
        return result;

    }

    @ApiOperation("修改订单完成时间 : 返回已处理和未处理的数据")
    @RequestMapping(value = "/update/completedAt", method = RequestMethod.POST)
    public Result<UpdateCompletedAtVO> updateCompleteAt(@RequestBody CompletedAtRequest request) {
        Result<UpdateCompletedAtVO> result = new Result<>();
        try {
            OrderQuery query = mapper.map(request, OrderQuery.class);
            Result<UpdateCompletedAtDTO> getResult = adminOrderService.updateOrderCompletedAt(query);
            if (!getResult.isStatus()) {
                result.setException(getResult.exceptionInfo());
                return result;
            }
            UpdateCompletedAtVO completedAtVO = ConvertUtils.convertObject(getResult.getData(), UpdateCompletedAtVO.class);
            result.setData(completedAtVO);
            result.setStatus(true);
        } catch (Throwable throwable) {
            logger.error("AdminController[updateCompleteAt] failed, request:{}, cause by: {}",
                    request.toString(), Throwables.getStackTraceAsString(throwable));
            result.setException(ExceptionConstants.SYSTEM_ERROR);
        }
        return result;

    }

    @ApiOperation("修改退款单状态")
    @RequestMapping(value = "/update/refund", method = RequestMethod.POST)
    public Result updateRefund(@RequestBody UpdateRefundRequest request) {
        Result result = new Result<>();
        try {
            OrderQuery query = mapper.map(request, OrderQuery.class);
            result = adminOrderService.updateRefund(query);
        } catch (Throwable throwable) {
            logger.error("AdminController[updateRefund] failed, request:{}, cause by: {}",
                    request.toString(), Throwables.getStackTraceAsString(throwable));
            result.setException(ExceptionConstants.SYSTEM_ERROR);
        }
        return result;
    }


    @ApiOperation("es降级")
    @RequestMapping(value = "/es/level/down", method = RequestMethod.POST)
    public Result esAmountLevelDown(@RequestBody EsAmountLevelDownRequest request) {
        Result result = new Result();
        try {
            if (Objects.equals(request.getType(), 1)) {
                redisManager.set("level:down:switch:es", "1");
            } else if (Objects.equals(request.getType(), 2)) {
                redisManager.delete("level:down:switch:es");
            } else {
                result.setMessage("type错误");
                return result;
            }
            result.setStatus(true);
        } catch (Throwable throwable) {
            logger.error("set cache failed, key:{}, cause by:{}", Throwables.getStackTraceAsString(throwable));
        }
        return result;
    }

    @ApiOperation("接口降级")
    @RequestMapping(value = "/level/down", method = RequestMethod.POST)
    public Result levelDown(@RequestBody EsAmountLevelDownRequest request) {
        Result result = new Result();
        try {
            if (Objects.equals(request.getType(), 1)) {
                redisManager.set(request.getKey(), "1");
            } else if (Objects.equals(request.getType(), 2)) {
                redisManager.delete(request.getKey());
            } else {
                result.setMessage("type错误");
                return result;
            }
            result.setStatus(true);
        } catch (Throwable e) {
            logger.error("set cache failed, key:{}, cause by:{}", e);
        }
        return result;
    }

    @ApiOperation("扫描es 更新冗余字段")
    @RequestMapping(value = "/es/clear", method = RequestMethod.POST)
    public Result clearEs(@RequestBody ClearEsRequest request) {
        Result result = new Result();
        try {
            adminOrderService.clearEs(request.getStartTime(), request.getTime());
            result.setStatus(true);
        } catch (Throwable e) {
            logger.error("set cache failed, key:{}, cause by:{}", e);
        }
        return result;
    }

    @ApiOperation("扫描es 更新冗余字段 开关")
    @RequestMapping(value = "/es/clear/stop", method = RequestMethod.POST)
    public Result clearEsStop(@RequestBody ClearEsStopRequest request) {
        Result result = new Result();
        try {
            AdminOrderServiceImpl.flag = request.getFlag();
            result.setStatus(true);
        } catch (Throwable e) {
            logger.error("set cache failed, key:{}, cause by:{}", e);
        }
        return result;
    }


    @ApiOperation("通过id 删除接口")
    @RequestMapping(value = "/delete/tool/interface", method = RequestMethod.POST)
    public Result deleteToolInterface(@RequestBody DeleteToolInterfaceRequest request) {
        Result result = new Result<>();
        try {
            result = adminOrderService.deleteToolInterface(Long.valueOf(request.getId()));
        } catch (Throwable throwable) {
            logger.error("AdminController[deleteToolInterface] failed, request:{}, cause by: {}",
                    request.toString(), Throwables.getStackTraceAsString(throwable));
            result.setException(ExceptionConstants.SYSTEM_ERROR);
        }
        return result;

    }


    @ApiOperation("餐饮猜你喜欢 开关")
    @RequestMapping(value = "/guess/like/switch", method = RequestMethod.POST)
    public Result guessLikeSwitch(@RequestBody GuessLikeSwitchRequest request) {
        Result result = new Result();
        try {

            if (Objects.equals(request.getType(), 1)) {
                redisManager.set(GUESS_LIKE_SWITCH, "1");
            } else if (Objects.equals(request.getType(), 2)) {
                redisManager.delete(GUESS_LIKE_SWITCH);
            } else {
                result.setMessage("type错误");
                return result;
            }
            result.setStatus(true);
        } catch (Throwable throwable) {
            logger.error("set cache failed, key:{}, cause by:{}", Throwables.getStackTraceAsString(throwable));
        }
        return result;
    }


    @ApiOperation("用户下单数量 开关")
    @RequestMapping(value = "/count/user/switch", method = RequestMethod.POST)
    public Result countUserSwitch(@RequestBody CountUserSwitchRequest request) {
        Result result = new Result();
        try {

            if (Objects.equals(request.getType(), 1)) {
                redisManager.set(LEVEL_DOWN_SWITCH_ES_COUNT, "1");
            } else if (Objects.equals(request.getType(), 2)) {
                redisManager.delete(LEVEL_DOWN_SWITCH_ES_COUNT);
            } else {
                result.setMessage("type错误");
                return result;
            }
            result.setStatus(true);
        } catch (Throwable throwable) {
            logger.error("set cache failed, key:{}, cause by:{}", Throwables.getStackTraceAsString(throwable));
        }
        return result;
    }

}









