package cn.iocoder.yudao.module.member.controller.app.activity;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.idempotent.core.annotation.Idempotent;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.member.controller.admin.activity.vo.ActivityPageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.activity.vo.ActivityRespVO;
import cn.iocoder.yudao.module.member.controller.admin.activityadddish.vo.ActivityAddDishPageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.activityadddish.vo.ActivityAddDishRespVO;
import cn.iocoder.yudao.module.member.controller.admin.activityawards.vo.ActivityAwardsRespVO;
import cn.iocoder.yudao.module.member.controller.admin.activityawardsuser.vo.ActivityAwardsUserPageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.activityawardsuser.vo.ActivityAwardsUserRespVO;
import cn.iocoder.yudao.module.member.controller.admin.activitymerchant.vo.ActivityMerchantPageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.activitymerchant.vo.ActivityMerchantRespVO;
import cn.iocoder.yudao.module.member.controller.admin.activitypay.vo.ActivityPayPageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.activityrestaurant.vo.ActivityRestaurantRespVO;
import cn.iocoder.yudao.module.member.controller.admin.activitytabledish.vo.ActivityTableDishPageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.activitytabledish.vo.ActivityTableDishRespVO;
import cn.iocoder.yudao.module.member.controller.admin.activityuser.vo.ActivityUserPageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.activityvoucheruser.vo.ActivityVoucherUserPageReqVO;
import cn.iocoder.yudao.module.member.controller.app.activity.vo.*;
import cn.iocoder.yudao.module.member.dal.dataobject.activity.ActivityDO;
import cn.iocoder.yudao.module.member.dal.dataobject.activityadddish.ActivityAddDishDO;
import cn.iocoder.yudao.module.member.dal.dataobject.activityawards.ActivityAwardsDO;
import cn.iocoder.yudao.module.member.dal.dataobject.activityawardsuser.ActivityAwardsUserDO;
import cn.iocoder.yudao.module.member.dal.dataobject.activitymenu.ActivityMenuDO;
import cn.iocoder.yudao.module.member.dal.dataobject.activitymerchant.ActivityMerchantDO;
import cn.iocoder.yudao.module.member.dal.dataobject.activitypay.ActivityPayDO;
import cn.iocoder.yudao.module.member.dal.dataobject.activityrestaurant.ActivityRestaurantDO;
import cn.iocoder.yudao.module.member.dal.dataobject.activitytable.ActivityTableDO;
import cn.iocoder.yudao.module.member.dal.dataobject.activitytabledish.ActivityTableDishDO;
import cn.iocoder.yudao.module.member.service.activity.ActivityService;
import cn.iocoder.yudao.module.member.service.activityadddish.ActivityAddDishService;
import cn.iocoder.yudao.module.member.service.activityawards.ActivityAwardsService;
import cn.iocoder.yudao.module.member.service.activityawardsuser.ActivityAwardsUserService;
import cn.iocoder.yudao.module.member.service.activitymenu.ActivityMenuService;
import cn.iocoder.yudao.module.member.service.activitymerchant.ActivityMerchantService;
import cn.iocoder.yudao.module.member.service.activitypay.ActivityPayService;
import cn.iocoder.yudao.module.member.service.activityrestaurant.ActivityRestaurantService;
import cn.iocoder.yudao.module.member.service.activitytable.ActivityTableService;
import cn.iocoder.yudao.module.member.service.activitytabledish.ActivityTableDishService;
import cn.iocoder.yudao.module.member.service.activityuser.ActivityUserService;
import cn.iocoder.yudao.module.member.service.activityvoucheruser.ActivityVoucherUserService;
import cn.iocoder.yudao.module.member.util.QRCodeWithJWTUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*;


@Tag(name = "用户 APP  - 活动")
@RestController
@RequestMapping("/member/activity1")
@Validated
public class AppActivityDrawController {

    @Resource
    private ActivityService activityService;

    @Resource
    private ActivityAwardsService activityAwardsService;

    @Resource
    private ActivityAwardsUserService activityAwardsUserService;

    @Resource
    private ActivityUserService activityUserService;

    @Resource
    private ActivityTableService activityTableService;

    @Resource
    private ActivityPayService activityPayService;

    @Resource
    private ActivityRestaurantService activityRestaurantService;

    @Resource
    private ActivityTableDishService activityTableDishService;

    @Resource
    private ActivityAddDishService activityAddDishService;

    @Resource
    private ActivityMerchantService activityMerchantService;

    @Resource
    private ActivityVoucherUserService activityVoucherUserService;

    @Resource
    private ActivityMenuService activityMenuService;

    @GetMapping("/manage/page")
    @Operation(summary = "管理员获取当天活动")
    public CommonResult<PageResult<ActivityRespVO>> getTodayActivityPage(@Valid ActivityPageReqVO pageReqVO) {
        PageResult<ActivityRespVO> pageResult = activityService.getActivityPage(pageReqVO);
        return success(pageResult);
    }

    @GetMapping("/user/page")
    @Operation(summary = "用户获取所有活动")
    public CommonResult<PageResult<ActivityRespVO>> getAllActivityPage(@Valid ActivityPageReqVO pageReqVO) {
        PageResult<ActivityRespVO> pageResult = activityService.getUserActivityPage(pageReqVO);
        return success(pageResult);
    }

    @GetMapping("/userRecord/page")
    @Operation(summary = "用户获取自己的活动记录")
    public CommonResult<PageResult<AppActivityRespVO>> getUserRecordActivityPage(@Valid ActivityUserPageReqVO pageReqVO) {
        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        pageReqVO.setUserId(loginUserId);
        return success(activityUserService.getUserRecordPage(pageReqVO));
    }

    @GetMapping("/prizeDraw")
    @Operation(summary = "抽奖")
    @Idempotent(timeout = 10)
    public CommonResult<List<ActivityAwardsUserDO>> prizeDraw(@Valid AppActivityPrizeDrawVO drawVO) {
        return success( activityService.prizeDraw(drawVO));
    }

    @GetMapping("/awardsUser/page")
    @Operation(summary = "中奖人员分页")
    public CommonResult<PageResult<ActivityAwardsUserRespVO>> getActivityAwardsUserPage(@Valid ActivityAwardsUserPageReqVO pageReqVO) {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        PageResult<ActivityAwardsUserDO> pageResult = activityAwardsUserService.getActivityAwardsUserPage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, ActivityAwardsUserRespVO.class));
    }

    @PostMapping("/user/apply")
    @Operation(summary = "用户报名")
    @Idempotent(timeout = 10)
    public CommonResult<Boolean> userApply(@Valid @RequestBody AppUserApplyVO appUserApplyVO) {
        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        appUserApplyVO.setUserId(loginUserId);
        return success( activityUserService.userApply(appUserApplyVO));
    }


    @GetMapping("/manage/get")
    @Operation(summary = "管理员获得活动详情")
    public CommonResult<ActivityRespVO> getActivity(@RequestParam("id") Long id) {
        ActivityDO activity = activityService.getActivity(id);
        ActivityRespVO bean = BeanUtils.toBean(activity, ActivityRespVO.class);
        return success(bean);
    }

    @GetMapping("/user/activity")
    @Operation(summary = "用户获得活动详情（记录）")
    public CommonResult<AppActivityRespVO> getUserActivity(@RequestParam("id") Long id) {
        AppActivityRespVO activity = activityService.getUserActivity(id,SecurityFrameworkUtils.getLoginUserId());
        return success(activity);
    }

    @GetMapping("/user/activity/applyInfo")
    @Operation(summary = "用户获得活动详情（报名）")
    public CommonResult<AppActivityRespVO> getUserActivityApplyInfo(@RequestParam("id") Long id) {
        AppActivityRespVO activity = activityService.getUserActivityApplyInfo(id,SecurityFrameworkUtils.getLoginUserId());
        return success(activity);
    }


    @GetMapping("/user/activityList")
    @Operation(summary = "用户获得可订餐的活动")
    public CommonResult<List<AppActivityRespVO>> getUserActivityList() {
        return success(activityService.getReservatList());
    }

    @GetMapping("/user/activityList/page")
    @Operation(summary = "用户获得可订餐的活动分页")
    public CommonResult<PageResult<ActivityRespVO>> getActivityReservePage(@Valid ActivityPageReqVO pageReqVO) {
        PageResult<ActivityRespVO> pageResult = activityService.getActivityReservePage(pageReqVO);
        return success(pageResult);
    }

    @GetMapping("/user/table")
    @Operation(summary = "用户获取已订餐桌号")
    public CommonResult<List<AppActivityTableRespVO>> getUserTableList(@RequestParam("activityId") Long activityId,@RequestParam("time") String time) {
        return success(BeanUtils.toBean(activityTableService.getListByActivityIdAndTime(activityId,time),  AppActivityTableRespVO.class));
    }


    @PostMapping("/user/check")
    @Operation(summary = "用户订餐桌号检测")
    public CommonResult<Boolean> userTableCheck(@RequestBody AppCheckVO vo) {
        return success(activityTableService.userTableCheck(vo));
    }

    @PutMapping("/user/unbind")
    @Operation(summary = "支付失败取消用户餐桌绑定")
    public CommonResult<Boolean> userTableUnbind(@RequestBody AppUnbindVO vo) {
        return success(activityTableService.userTableUnbind(vo));
    }

    @GetMapping("/qrCode")
    @Operation(summary = "获取核销二维码(抽奖)")
    public CommonResult<String> getQrCode(@RequestParam("activityAwardsUserId") Long activityAwardsUserId) {

        ActivityAwardsUserDO activityAwardsUserDO = activityAwardsUserService.getActivityAwardsUser(activityAwardsUserId);
        if(!"0".equals(activityAwardsUserDO.getAwardsStatus())){
            throw exception(ACTIVITY_AWARDS_USER_NOT_EFFECTIVE);
        }
        ActivityDO activity = activityService.getActivity(activityAwardsUserDO.getActivityId());
        ActivityAwardsDO activityAwards = activityAwardsService.getActivityAwards(activityAwardsUserDO.getAwardsId());


        AppQrCodeVO appQrCodeVO = new AppQrCodeVO();
        appQrCodeVO.setActivityAwardsUserId(activityAwardsUserId);
        appQrCodeVO.setNickName(activityAwardsUserDO.getNickName());
        appQrCodeVO.setMobile(activityAwardsUserDO.getMobile());
        appQrCodeVO.setPrize(activityAwards.getPrize());
        appQrCodeVO.setActivityName(activity.getActivityName());
        appQrCodeVO.setType("1");

        String qrCode = QRCodeWithJWTUtil.generateQRCode(JSONUtil.toJsonStr(appQrCodeVO), 350, 350, null);// 生
        return success(qrCode);
    }

    @PutMapping("/cancel")
    @Operation(summary = "核销(抽奖)")
    public CommonResult<Boolean> cancel(@RequestBody AppCancelVO vo) {
        return success(activityAwardsUserService.cancel(vo));
    }

    @GetMapping("/manage/applyUserList")
    @Operation(summary = "报名人员列表")
    public CommonResult<List<AppActivityUserRespVO>> applyUserList(@RequestParam("activityId") Long activityId) {
        return success(activityUserService.applyUserList(activityId));
    }

    @GetMapping("/awardsList")
    @Operation(summary = "获得活动奖项列表")
    public CommonResult<List<ActivityAwardsRespVO>> getActivityAwardsList(@RequestParam("activityId") Long activityId) {
        List<ActivityAwardsDO> list = activityAwardsService.getListByActivity(activityId);
        return success(BeanUtils.toBean(list, ActivityAwardsRespVO.class));
    }

    @GetMapping("/user/pay/page")
    @Operation(summary = "用户付款记录分页")
    public CommonResult<PageResult<AppActivityPayRespVO>> getUserActivityPayPage(@Valid ActivityPayPageReqVO pageReqVO) {
        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        pageReqVO.setUserId(loginUserId);
        PageResult<AppActivityPayRespVO> pageResult = activityPayService.getUserActivityPayPage(pageReqVO);
        if(CollectionUtil.isNotEmpty(pageResult.getList())){
            for (AppActivityPayRespVO item:pageResult.getList()){
                if(StringUtils.isBlank(item.getMenuIds())){
                    continue;
                }
                String serialNumbers = item.getSerialNumbers();
                String menuNames = item.getMenuNames();
                String[] split = serialNumbers.split(",");
                String[] split1 = menuNames.split(",");
                ArrayList<PayVO> payVOS = new ArrayList<>();

                for (int i = 0; i < split.length; i++) {
                    PayVO payVO = new PayVO();
                    payVO.setSerialNumbers(split[i]);
                    payVO.setMenuName(split1[i]);
                    payVOS.add(payVO);
                }
                item.setPayVOs(payVOS);
            }
        }
        return success(pageResult);
    }

    @GetMapping("/user/activity/reserveInfo")
    @Operation(summary = "用户获得订餐活动详情")
    public CommonResult<AppActivityRespVO> getUserActivityReserveInfo(@RequestParam("id") Long id) {
        ActivityDO activity = activityService.getActivity(id);
        AppActivityRespVO bean = BeanUtils.toBean(activity, AppActivityRespVO.class);
        ActivityRestaurantDO activityRestaurantDO = activityRestaurantService.getByActivityId(id);
        bean.setActivityRestaurantSaveDto(BeanUtils.toBean(activityRestaurantDO, ActivityRestaurantRespVO.class));
        return success(bean);
    }

    @GetMapping("/reserveQrCode")
    @Operation(summary = "获取核销二维码(订餐)")
    public CommonResult<String> getReserveQrCode(@RequestParam("activityPayId") Long activityPayId) {
        ActivityPayDO activityPay = activityPayService.getActivityPay(activityPayId);
        if(!"0".equals(activityPay.getStatus())){
            throw exception(ACTIVITY_PAY_USE);
        }

        if(StrUtil.isEmpty(activityPay.getDish())){
            //获取当天日期
            LocalDate now = LocalDate.now();
            //比较日期是否相等
            if(! now.isEqual(activityPay.getReserveTime())){
                throw exception(ACTIVITY_PAY_EXPIRE);
            }
        }


        ActivityDO activity = activityService.getActivity(activityPay.getActivityId());

        AppReserveQrCodeVO appReserveQrCodeVO = new AppReserveQrCodeVO();
        appReserveQrCodeVO.setActivityPayId(activityPayId);
        appReserveQrCodeVO.setNickName(activityPay.getNickName());
        appReserveQrCodeVO.setMobile(activityPay.getMobile());
        appReserveQrCodeVO.setActivityName(activity.getActivityName());
        appReserveQrCodeVO.setSerialNumbers(activityPay.getSerialNumbers());
        if(StrUtil.isNotBlank(activityPay.getDish())){
            appReserveQrCodeVO.setDish(activityPay.getDish());
        }
        appReserveQrCodeVO.setType("2");
        String qrCode = QRCodeWithJWTUtil.generateQRCode(JSONUtil.toJsonStr(appReserveQrCodeVO), 350, 350, null);// 生
        return success(qrCode);

    }

    @PutMapping("/reserveCancel")
    @Operation(summary = "核销(订餐)")
    public CommonResult<Boolean> reserveCancel(@RequestBody AppCancelVO vo) {
        return success(activityPayService.reserveCancel(vo));
    }

    @GetMapping("/tableList")
    @Operation(summary = "获得所有活动用餐桌子")
    public CommonResult<List<ActivityTableDishRespVO>> getActivityTableDishList(@Valid ActivityTableDishPageReqVO pageReqVO) {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<ActivityTableDishDO> list = activityTableDishService.getActivityTableDishPage(pageReqVO).getList();
        return success(BeanUtils.toBean(list, ActivityTableDishRespVO.class));
    }

    @GetMapping("/addDishList")
    @Operation(summary = "获得活动用餐桌子加菜列表")
    public CommonResult<List<ActivityAddDishRespVO>> getActivityAddDishPage(@Valid ActivityAddDishPageReqVO pageReqVO) {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<ActivityAddDishDO> list = activityAddDishService.getActivityAddDishPage(pageReqVO).getList();
        return success(BeanUtils.toBean(list, ActivityAddDishRespVO.class));
    }

    @GetMapping("/user/reserveTable")
    @Operation(summary = "用户获得订餐桌号")
    public CommonResult<List<ActivityTableDishRespVO>> getActivityAddDishPage(@Valid ActivityTableDishPageReqVO pageReqVO) {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        pageReqVO.setReserveTime(LocalDate.now());

        List<ActivityTableDO> listByActivityIdAndTimeAndUserId = activityTableService.getListByActivityIdAndTimeAndUserId(pageReqVO.getActivityId(), pageReqVO.getReserveTime(), pageReqVO.getUserId());
        if (!listByActivityIdAndTimeAndUserId.isEmpty()) {
            List<Integer> collect = listByActivityIdAndTimeAndUserId.stream().map(ActivityTableDO::getSerialNumber).collect(Collectors.toList());
            pageReqVO.setSerialNumbers(collect);
        }
        List<ActivityTableDishDO> list = activityTableDishService.getActivityTableDishPage(pageReqVO).getList();
        return success(BeanUtils.toBean(list, ActivityTableDishRespVO.class));
    }


    @GetMapping("/merchantList")
    @Operation(summary = "获得商家列表")
    public CommonResult<List<ActivityMerchantRespVO>> getMerchantList(@Valid ActivityMerchantPageReqVO pageReqVO) {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<ActivityMerchantDO> list = activityMerchantService.getActivityMerchantPage(pageReqVO).getList();
        return success(BeanUtils.toBean(list, ActivityMerchantRespVO.class));
    }


    @GetMapping("/checkVoucher")
    @Operation(summary = "判断是否能使用代金券")
    public CommonResult<Boolean> checkVoucher(@Valid ActivityVoucherVO vo) {
        return success(activityVoucherUserService.checkVoucher(vo));
    }

    @GetMapping("/user/voucherPage")
    @Operation(summary = "用户查看自己的代金券(分页)")
    public CommonResult<PageResult<AppActivityVoucherUserRespVO>> getActivityVoucherPage(@Valid ActivityVoucherUserPageReqVO pageReqVO) {
        return success(activityVoucherUserService.getActivityVoucherPage(pageReqVO));
    }

    @GetMapping("/user/voucherList")
    @Operation(summary = "查看用户的代金券（支付）")
    public CommonResult<List<AppActivityVoucherUserRespVO>> getActivityVoucherList(@Valid ActivityVoucherUserPageReqVO pageReqVO) {
        pageReqVO.setStatus("0");
        pageReqVO.setUserId(SecurityFrameworkUtils.getLoginUserId());
        return success(activityVoucherUserService.getActivityVoucherList(pageReqVO));
    }

//    @GetMapping("/manage/reserveTable")
//    @Operation(summary = "管理员查看预定桌子分页")
//    public CommonResult<PageResult<ActivityTableRespVO>> getReserveTablePage(@Valid ActivityTablePageReqVO pageReqVO) {
//        List<ActivityTableDishDO> listByActivityIdAndMerchantId = activityTableDishService.getListByActivityIdAndMerchantId(pageReqVO.getActivityId(), pageReqVO.getMerchantId());
//        if (listByActivityIdAndMerchantId.isEmpty()) {
//            return success(PageResult.empty());
//        }
//        List<Integer> collect = listByActivityIdAndMerchantId.stream().map(ActivityTableDishDO::getSerialNumber).collect(Collectors.toList());
//        pageReqVO.setSerialNumbers(collect);
//        pageReqVO.setIsReserve(true);
//        PageResult<ActivityTableDO> pageResult = activityTableService.getActivityTablePage(pageReqVO);
//        return success(BeanUtils.toBean(pageResult, ActivityTableRespVO.class));
//    }

    @GetMapping("/manage/addDishPage")
    @Operation(summary = "管理员查看加菜分页")
    public CommonResult<PageResult<AppActivityPayRespVO>> getManageAddDishPage(@Valid ActivityPayPageReqVO pageReqVO) {
        List<ActivityTableDishDO> listByActivityIdAndMerchantId = activityTableDishService.getListByActivityIdAndMerchantId(pageReqVO.getActivityId(), pageReqVO.getMerchantId());
        if (listByActivityIdAndMerchantId.isEmpty()) {
            return success(PageResult.empty());
        }
        List<Integer> collect = listByActivityIdAndMerchantId.stream().map(ActivityTableDishDO::getSerialNumber).collect(Collectors.toList());
        pageReqVO.setSerialNumberList(collect);
        PageResult<AppActivityPayRespVO> pageResult = activityPayService.getMerchantActivityPayPage(pageReqVO);
        if(CollectionUtil.isNotEmpty(pageResult.getList())){

            for (AppActivityPayRespVO item:pageResult.getList()){
                if(StringUtils.isBlank(item.getMenuIds())){
                    continue;
                }
                String serialNumbers = item.getSerialNumbers();
                String menuNames = item.getMenuNames();
                String[] split = serialNumbers.split(",");
                String[] split1 = menuNames.split(",");
                ArrayList<PayVO> payVOS = new ArrayList<>();

                for (int i = 0; i < split.length; i++) {
                    PayVO payVO = new PayVO();
                    payVO.setSerialNumbers(split[i]);
                    payVO.setMenuName(split1[i]);
                    payVOS.add(payVO);
                }
                item.setPayVOs(payVOS);
            }
        }
        return success(pageResult);
    }

    @GetMapping("/merchant")
    @Operation(summary = "获得商家")
    public CommonResult<ActivityMerchantDO> getMerchantByMobile(@Valid String mobile) {
        return success(activityMerchantService.getByMobile(mobile));
    }


    @GetMapping("/merchantMenu")
    @Operation(summary = "获得商家套餐列表")
    public CommonResult<List<ActivityMenuDO>> getMerchantByMobile(@Valid Long merchantId) {
        return success(activityMenuService.getListByMerchantId(merchantId));
    }




}