package me.zhengjie.modules.thirdparty.v1;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import me.zhengjie.annotation.AnonymousAccess;
import me.zhengjie.annotation.Limit;
import me.zhengjie.annotation.Log;
import me.zhengjie.annotation.rest.AnonymousGetMapping;
import me.zhengjie.annotation.rest.AnonymousPostMapping;
import me.zhengjie.aspect.LimitType;
import me.zhengjie.base.BaseResponse;
import me.zhengjie.base.QueryPageParams;
import me.zhengjie.domain.LocalStorage;
import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.dm.daypc.domain.DmDayPc;
import me.zhengjie.modules.dm.daypc.service.DmDayPcService;
import me.zhengjie.modules.dm.daypc.service.dto.DmDayPcQueryCriteria;
import me.zhengjie.modules.dm.foodCate.domain.DmFoodCate;
import me.zhengjie.modules.dm.foodCate.repository.DmFoodCateRepository;
import me.zhengjie.modules.dm.foodPj.domain.DmFoodPj;
import me.zhengjie.modules.dm.foodPj.service.DmFoodPjService;
import me.zhengjie.modules.dm.information.service.DmInformationService;
import me.zhengjie.modules.dm.information.service.dto.DmInformationDto;
import me.zhengjie.modules.dm.information.service.dto.DmInformationQueryCriteria;
import me.zhengjie.modules.dm.order.domain.DmOrderItem;
import me.zhengjie.modules.dm.order.domain.DmOrderRecord;
import me.zhengjie.modules.dm.order.repository.DmOrderItemRepository;
import me.zhengjie.modules.dm.order.repository.DmOrderRecordRepository;
import me.zhengjie.modules.dm.order.service.DmOrderRecordService;
import me.zhengjie.modules.dm.order.service.dto.DmOrderRecordQueryCriteria;
import me.zhengjie.modules.dm.service.domain.DmServicePj;
import me.zhengjie.modules.dm.service.repository.DmServicePjRepository;
import me.zhengjie.modules.dm.service.service.DmServicePjService;
import me.zhengjie.modules.dm.userInformation.domain.DmUserInformation;
import me.zhengjie.modules.dm.userInformation.service.DmUserInformationService;
import me.zhengjie.modules.dm.userInformation.service.dto.DmUserInformationDto;
import me.zhengjie.modules.dm.userInformation.service.dto.DmUserInformationQueryCriteria;
import me.zhengjie.modules.dmApp.domain.AppFoodPj;
import me.zhengjie.modules.dmApp.service.AppFoodPjService;
import me.zhengjie.modules.dmApp.service.dto.AppFoodPjDto;
import me.zhengjie.service.LocalStorageService;
import me.zhengjie.utils.FileUtil;
import me.zhengjie.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.util.*;

@RestController
@RequiredArgsConstructor
@Api(tags = "用户接口")
@RequestMapping("/api/thirdparty/v1/open")
public class OpenApiController {
    private final DmDayPcService dmDayPcService;
    private final DmServicePjService dmServicePjService;
    private final AppFoodPjService appFoodPjService;
    private final DmFoodPjService dmFoodPjService;
    private final LocalStorageService localStorageService;
    private final DmOrderRecordRepository dmOrderRecordRepository;
    private final DmOrderItemRepository orderItemRepository;
    private final DmFoodCateRepository dmFoodCateRepository;
    private final DmServicePjRepository dmServicePjRepository;
    private final DmOrderRecordService dmOrderRecordService;
    private final DmInformationService dmInformationService;
    private final DmUserInformationService dmUserInformationService;

    @Log("获取今日菜品-App")
    @ApiOperation("获取今日菜品-App")
    @AnonymousPostMapping(value = "/foodRepository")
    public BaseResponse<Object> foodRepository(@RequestBody QueryPageParams<DmDayPcQueryCriteria> criteria){
        SecurityUtils.CheckApiAuth(criteria);
//        dmDayPcService.foodRepository();
        return new BaseResponse<>(dmFoodCateRepository.foodApp());
    }

    @AnonymousPostMapping(value = "/createApp")
    @Log("新增服务评价")
    @ApiOperation("新增服务评价")
    public BaseResponse<Object> createApp(@RequestBody QueryPageParams<DmServicePj> resources){
        SecurityUtils.CheckApiAuth(resources);
        int count = dmServicePjService.servicePjApp(resources.getQuery().getUserCode());
        if (count >= 1){
            throw new BadRequestException("该用户已评价，今日不可评价！");
        }else {
            dmServicePjService.createApp(resources.getQuery());
        }
        return new BaseResponse<>(count);
    }

    @AnonymousPostMapping(value = "/appFoodPj")
    @Log("App菜品评价")
    @ApiOperation("App菜品评价")
    public BaseResponse<Object> appFoodPj(@RequestBody QueryPageParams<String> cardid) {
        SecurityUtils.CheckApiAuth(cardid);
        List<AppFoodPj> list = appFoodPjService.selectAppFoodPj(cardid.getQuery());
        return new BaseResponse<>(list);
    }

    @AnonymousPostMapping(value = "/createFoodPj")
    @Log("新增菜品评价")
    @ApiOperation("新增菜品评价")
    public BaseResponse<Object> createFoodPj(@RequestBody QueryPageParams<DmFoodPj> resources){
        SecurityUtils.CheckApiAuth(resources);
         Optional<DmFoodCate> byId = dmFoodCateRepository.findById(resources.getQuery().getFoodType().getId());
         resources.getQuery().setFoodType(byId.get());
        return new BaseResponse<>(dmFoodPjService.createApp(resources.getQuery()));
    }

    @AnonymousPostMapping(value = "/pictures")
    @Log("上传图片")
    @ApiOperation("上传图片")
    public BaseResponse<Object> upload(@RequestParam String timestamp, @RequestParam String nonce, @RequestParam String name, @RequestParam("file") MultipartFile file){
        QueryPageParams params = new QueryPageParams();
        params.setNonce(nonce);
        params.setTimestamp(timestamp);
        SecurityUtils.CheckApiAuth(params);
        // 判断文件是否为图片
        String suffix = FileUtil.getExtensionName(file.getOriginalFilename());
        if(!FileUtil.IMAGE.equals(FileUtil.getFileType(suffix))){
            throw new BadRequestException("只能上传图片");
        }
        LocalStorage localStorage = localStorageService.create(name, file);
        return new BaseResponse<>(localStorage);
    }

    @AnonymousAccess
    @GetMapping(value = "/countOrderAmt")
    @Log("pc端运营食堂营业额")
    @ApiOperation("pc端运营食堂营业额")
    public ResponseEntity<Object> countOrderAmt(){
        return new ResponseEntity<>(dmOrderRecordRepository.countOrderAmt(),HttpStatus.OK);
    }

    @AnonymousAccess
    @GetMapping(value = "/hyFood")
    @Log("pc端运营最受欢迎菜品")
    @ApiOperation("pc端运营最受欢迎菜品")
    public ResponseEntity<Object> hyFood(){
        return new ResponseEntity<>(orderItemRepository.hyFood(),HttpStatus.OK);
    }

    @AnonymousPostMapping(value = "/countOrderAmtApp")
    @Log("App端运营食堂营业额")
    @ApiOperation("App端运营食堂营业额")
    public BaseResponse<Object> countOrderAmtApp(@RequestBody QueryPageParams<DmOrderRecord> criteria){
        SecurityUtils.CheckApiAuth(criteria);
        return new BaseResponse<>(dmOrderRecordRepository.countOrderAmt());
    }

    @AnonymousPostMapping(value = "/hyFoodApp")
    @Log("App端运营最受欢迎菜品")
    @ApiOperation("App端运营最受欢迎菜品")
    public BaseResponse<Object> hyFoodApp(@RequestBody QueryPageParams<DmOrderItem> criteria){
        SecurityUtils.CheckApiAuth(criteria);
        return new BaseResponse<>(orderItemRepository.hyFood());
    }

    @AnonymousPostMapping(value = "/enableApp")
    @Log("pc端控制整体评价是否可见")
    @ApiOperation("pc端控制整体评价是否可见")
    public BaseResponse<Object> enableApp(@RequestBody QueryPageParams<DmOrderItem> criteria){
        SecurityUtils.CheckApiAuth(criteria);
        return new BaseResponse<>(dmServicePjService.enableApp());
    }

    @AnonymousPostMapping(value = "/findDmServicePjByUserCodeAndPjTime")
    @Log("用户服务评价详情")
    @ApiOperation("用户服务评价详情")
    public BaseResponse<Object> findDmServicePjByUserCodeAndPjTime(@RequestBody QueryPageParams<DmServicePj> criteria){
        SecurityUtils.CheckApiAuth(criteria);
        return new BaseResponse<>(dmServicePjService.getDmServicePjByUserCodeAndPjTime(criteria.getQuery().getUserCode()));
    }

    @AnonymousPostMapping(value = "/AppCountData")
    @Log("统计数据")
    @ApiOperation("App端统计数据")
    public BaseResponse<Object> appCountData(@RequestBody QueryPageParams<String> criteria){
        SecurityUtils.CheckApiAuth(criteria);

        /**
         * 声明一个map返回参数
         */

        Map<String,Object> map = new HashMap<>();

        JSONObject jsonObject = new JSONObject();

        /**
         * 查询今日购餐总额(元)
         */
        BigDecimal bigDecimal =  dmOrderRecordRepository.countOrderAmtByNow();
        /**
         * 查询今日用餐人数(人次)
         */
        Integer person = dmOrderRecordRepository.countOrderPersonByNow();
        /**
         * 查询服务评价
         */
         List<DmServicePj> dmServicePjContentByNow = dmServicePjRepository.getDmServicePjContentByNow();
        /**
         * 统计综合服务评分
         */
        Map<String, Object> dmServicePjByNow = dmServicePjRepository.getDmServicePjByNow();
        map.put("person",person);
        map.put("money",bigDecimal.toString());
        jsonObject.put("dmServicePjByNow",dmServicePjByNow);
        jsonObject.put("dmServicePjContentByNow",dmServicePjContentByNow);
        map.put("content",jsonObject);
        return new BaseResponse<>(map);
    }

    @AnonymousPostMapping(value = "/AppDayFoodData")
    @Log("今日菜品清单")
    @ApiOperation("App今日菜品清单")
    public BaseResponse<Object> AppDayFoodData(@RequestBody QueryPageParams<String> criteria){
        SecurityUtils.CheckApiAuth(criteria);

        /**
         * 查询今日菜品清单
         * data { 菜品名称,菜品单价,供应数量 }
         */
         List<Map<String, Object>> maps = dmFoodCateRepository.foodApp();
        /**
         * list 接收
         */
        List<JSONObject> jsonObjectList = new ArrayList<>();

        /**
         * 使用forEach之后 里面的变量必须要用原子类
         */
        maps.forEach(item->{
            /**
             * 声明一个json对象用来存储菜品统计信息
             */
            JSONObject jsonObject = new JSONObject();
            Map<String,Object> map = new HashMap<>();
            JSONObject object = new JSONObject();
            /**
             * 根据商品id查询今日消费了多少当前商品
             */
             Object cate_id = item.get("cate_id");
            /**
             * grade 评价平均值  code_num 评价参与人数 food_num 商品消费了多少
             */
            Map<String,Object> cate = dmOrderRecordRepository.selectOrderSumByCateId(cate_id == null?null:cate_id.toString());
            /**
             * 查询评价详情列表
             */
            List<Map<String,Object>> dmFoodPjs = dmFoodPjService.findByFoodCode(cate_id.toString());
            //供应总数
            map.put("foodSum",item.get("no").toString());
            //剩余数量
            map.put("foodResidue",Integer.valueOf(item.get("no").toString())-Integer.valueOf(cate.get("food_num").toString()) <=0? 0:Integer.valueOf(item.get("no").toString())-Integer.valueOf(cate.get("food_num").toString()));
            //商品单价
            map.put("foodPrice",item.get("price"));
            jsonObject.put("foodName",item.get("name"));
            jsonObject.put("foodPrice",item.get("price"));
            jsonObject.put("content",map);
            object.put("cate",cate);
            object.put("dmFoodPjs",dmFoodPjs);
            map.put("object",object);
            jsonObjectList.add(jsonObject);
        });

        return new BaseResponse<>(jsonObjectList);
    }

    @AnonymousPostMapping(value = "/expenseFlow")
    @Log("食堂人流量")
    @ApiOperation("食堂人流量")
    public BaseResponse<Object> expenseFlow(@RequestBody QueryPageParams<DmOrderRecordQueryCriteria> criteria){
        SecurityUtils.CheckApiAuth(criteria);
        return new BaseResponse<>(dmOrderRecordService.queryAll(criteria.getQuery()).size());
    }

    @AnonymousPostMapping(value = "/orderRecord")
    @Log("消费记录")
    @ApiOperation("消费记录")
    public BaseResponse<Object> orderRecord(@RequestBody QueryPageParams<DmOrderRecordQueryCriteria> criteria,Pageable pageable){
        SecurityUtils.CheckApiAuth(criteria);
        return new BaseResponse<>(dmOrderRecordService.queryAll(criteria.getQuery(),pageable));
    }

    @AnonymousPostMapping(value = "/informationData")
    @Log("信息发布列表")
    @ApiOperation("信息发布列表")
    public BaseResponse<Object> informationData(@RequestBody QueryPageParams<String> criteria,Pageable pageable){
        SecurityUtils.CheckApiAuth(criteria);
        Map<String,Object> map = dmInformationService.queryAll(new DmInformationQueryCriteria(),pageable);
        List<DmInformationDto> array = JSONArray.parseArray(JSONArray.toJSONString(map.get("content")),DmInformationDto.class);
        List<DmInformationDto> newArray = new ArrayList<>();
        for(DmInformationDto dmInformationDto : array){
            DmUserInformationQueryCriteria dmUserInformationQueryCriteria = new DmUserInformationQueryCriteria();
            dmUserInformationQueryCriteria.setUserId(criteria.getQuery());
            dmUserInformationQueryCriteria.setInformationId(dmInformationDto.getId());
            List<DmUserInformationDto> dmUserInformationDtos = dmUserInformationService.queryAll(dmUserInformationQueryCriteria);
            if(!ObjectUtils.isEmpty(dmUserInformationDtos)){
                dmInformationDto.setIsRead(1);
            } else {
                dmInformationDto.setIsRead(0);
            }
            newArray.add(dmInformationDto);
        }
        map.put("content",newArray);
        return new BaseResponse<>(map);
    }

    @AnonymousPostMapping(value = "/informationRead")
    @Log("信息发布已读")
    @ApiOperation("信息发布已读")
    public BaseResponse<Object> informationData(@RequestBody QueryPageParams<DmUserInformation> criteria){
        SecurityUtils.CheckApiAuth(criteria);
        dmUserInformationService.create(criteria.getQuery());
        return new BaseResponse<>(true);
    }
}