package com.liquidnet.client.admin.web.controller.zhengzai.kylin;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.liquidnet.client.admin.common.core.controller.BaseController;
import com.liquidnet.client.admin.common.utils.StringUtils;
import com.liquidnet.client.admin.zhengzai.kylin.dto.PerformanceCalendarReq;
import com.liquidnet.client.admin.zhengzai.kylin.dto.PerformanceCalendarResp;
import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.commons.lang.util.StringUtil;
import com.liquidnet.service.kylin.entity.KylinPerformances;
import com.liquidnet.service.kylin.mapper.KylinPerformancesMapper;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.*;

/**
 * @author AnJiabin <anjiabin@zhengzai.tv>
 * @version V1.0
 * @Description: TODO
 * @class: PerformanceCalendar
 * @Package com.liquidnet.client.admin.web.controller.zhengzai.kylin
 * @Copyright: LightNet @ Copyright (c) 2021
 * @date 2021/5/24 19:58
 */
@Controller
@RequestMapping("/kylin/performanceCalendar")
public class PerformanceCalendarController extends BaseController{
    private String prefix = "zhengzai/kylin/performanceCalendar";

    @Autowired
    private KylinPerformancesMapper performancesMapper;

    @RequiresPermissions("kylin:performanceCalendar:view")
    @GetMapping()
    public String performances(PerformanceCalendarReq performanceCalendarReq, ModelMap mmap)
    {
        //获取开始结束间隔天数
        List<PerformanceCalendarResp> respList = this.getPerformanceList(performanceCalendarReq);

        mmap.put("currentDate",LocalDate.now());
        mmap.put("requestParam",performanceCalendarReq);
        mmap.put("respDataList",respList);
        return prefix + "/performanceCalendar";
    }

    /**
     * 查询演出列表
     */
    @RequiresPermissions("kylin:performanceCalendar:list")
    @PostMapping("/list")
    public String list(PerformanceCalendarReq performanceCalendarReq, ModelMap mmap)
    {
        //获取开始结束间隔天数
        List<PerformanceCalendarResp> respList = this.getPerformanceList(performanceCalendarReq);

        mmap.put("requestParam",performanceCalendarReq);
        mmap.put("respDataList",respList);
        return prefix + "/performanceCalendar";
    }

    private List<PerformanceCalendarResp> getPerformanceList(PerformanceCalendarReq performanceCalendarReq){
        Map<String,String> beginAndEndMap = this.getStartAndEndTime(performanceCalendarReq);
        String startTime = beginAndEndMap.get("startTime");
        String endTime = beginAndEndMap.get("endTime");
        int days = Long.valueOf(DateUtil.intervalDays(DateUtil.parse(startTime,DateUtil.DATE_SMALL_STR)
                ,DateUtil.parse(endTime,DateUtil.DATE_SMALL_STR))).intValue() + 1;

        //查询条件
        LambdaQueryWrapper<KylinPerformances> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotNull(performanceCalendarReq.getTimeBegin())) {
            wrapper.ge(KylinPerformances::getTimeStart, DateUtil.asLocalDate(DateUtil.parse(performanceCalendarReq.getTimeBegin(),DateUtil.DATE_SMALL_STR)));
        }
        if (StringUtils.isNotNull(performanceCalendarReq.getTimeEnd())) {
            wrapper.le(KylinPerformances::getTimeStart, DateUtil.addDay(DateUtil.parse(performanceCalendarReq.getTimeEnd(),DateUtil.DATE_SMALL_STR),1));
        }

        List<KylinPerformances> list = performancesMapper.selectList(wrapper);

        String[][] dateArray2 = getDateList(DateUtil.parse(startTime,DateUtil.DATE_SMALL_STR),days);
        //初始化对象
        List<PerformanceCalendarResp> respList = initRespList(dateArray2);
        for (KylinPerformances kylinPerformances : list) {
            //定义演出对象
            PerformanceCalendarResp.PerformanceVo performanceVo = new PerformanceCalendarResp.PerformanceVo();
            performanceVo.setTitle(kylinPerformances.getTitle());
            performanceVo.setCityName(kylinPerformances.getCityName());
            performanceVo.setTimeStart(DateUtil.format(kylinPerformances.getTimeStart(),DateUtil.Formatter.yyyyMMddHHmmss));

            //页面行循环
            for(int i = 0;i< dateArray2.length;i++){
                //页面列循环
                for(int j = 0;j<dateArray2[i].length; j++){
                    String targetDate = dateArray2[i][j];
                    if(DateUtil.format(kylinPerformances.getTimeStart(),DateUtil.Formatter.yyyy_MM_dd).equalsIgnoreCase(targetDate)){
                        switch (j){
                            case 0:
                                List<PerformanceCalendarResp.PerformanceVo> monList = respList.get(i).getMonList();
                                monList.add(performanceVo);
                                break;
                            case 1:
                                List<PerformanceCalendarResp.PerformanceVo> tueList = respList.get(i).getTueList();
                                tueList.add(performanceVo);
                                break;
                            case 2:
                                List<PerformanceCalendarResp.PerformanceVo> wedList = respList.get(i).getWedList();
                                wedList.add(performanceVo);
                                break;
                            case 3:
                                List<PerformanceCalendarResp.PerformanceVo> thuList = respList.get(i).getThuList();
                                thuList.add(performanceVo);
                                break;
                            case 4:
                                List<PerformanceCalendarResp.PerformanceVo> friList = respList.get(i).getFriList();
                                friList.add(performanceVo);
                                break;
                            case 5:
                                List<PerformanceCalendarResp.PerformanceVo> satList = respList.get(i).getSatList();
                                satList.add(performanceVo);
                                break;
                            case 6:
                                List<PerformanceCalendarResp.PerformanceVo> sunList = respList.get(i).getSunList();
                                sunList.add(performanceVo);
                                break;
                            default:
                                break;

                        }
                    }
                }
            }
        }
        logger.debug("respList :{}", JSON.toJSONString(respList));
        return respList;
    }

    /**
     * days必须是7的倍数 7，14
     * @param beginDate
     * @param days
     * @return
     */
    private String[][] getDateList(Date beginDate, int days){
        //获取所有日期
        List<String> dateList = new ArrayList<>();
        for(int i=0;i<days;i++){
            dateList.add(DateUtil.format(DateUtil.addDay(beginDate,i),DateUtil.Formatter.yyyy_MM_dd));
        }

        //获取显示行数
        int rowNum = days/7;
        String[][] strArray = new String[rowNum][7];

        for(int i=0; i<rowNum; i++){
            for(int j=0; j < 7; j++){
                strArray[i][j] = dateList.get(i * 7 + j);
            }
        }

        return strArray;
    }

    private List<PerformanceCalendarResp> initRespList(String[][] dateArray2){

        List<PerformanceCalendarResp> respList = new ArrayList<>();
        for(int i = 0;i< dateArray2.length;i++){
            PerformanceCalendarResp resp = new PerformanceCalendarResp();
            for(int j = 0;j<dateArray2[i].length; j++){
                String targetDate = dateArray2[i][j];
                    switch (j){
                        case 0:
                            resp.setMonDate(targetDate);
                            resp.setMonList(new ArrayList<>());
                            break;
                        case 1:
                            resp.setTueDate(targetDate);
                            resp.setTueList(new ArrayList<>());
                            break;
                        case 2:
                            resp.setWedDate(targetDate);
                            resp.setWedList(new ArrayList<>());
                            break;
                        case 3:
                            resp.setThuDate(targetDate);
                            resp.setThuList(new ArrayList<>());
                            break;
                        case 4:
                            resp.setFriDate(targetDate);
                            resp.setFriList(new ArrayList<>());
                            break;
                        case 5:
                            resp.setSatDate(targetDate);
                            resp.setSatList(new ArrayList<>());
                            break;
                        case 6:
                            resp.setSunDate(targetDate);
                            resp.setSunList(new ArrayList<>());
                            break;
                        default:
                            break;

                    }
            }
            respList.add(resp);
        }
        return respList;
    }

    /**
     * 根据输入日期获取开始结束日期
     * @param performanceCalendarReq
     * @return
     */
    private Map<String,String> getStartAndEndTime(PerformanceCalendarReq performanceCalendarReq){
        LocalDate currDate = LocalDate.now();
        LocalDate paramBegin = LocalDate.parse(currDate.toString());
        LocalDate parseEnd = LocalDate.parse(currDate.toString());
        LocalDate monday = paramBegin.with(TemporalAdjusters.previousOrSame( DayOfWeek.MONDAY));
        LocalDate sunday = parseEnd.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY ));
        if(StringUtil.isNull(performanceCalendarReq.getTimeBegin())){
            performanceCalendarReq.setTimeBegin(monday.toString());
            performanceCalendarReq.setTimeEnd(sunday.toString());
        }else{
            paramBegin = LocalDate.parse(performanceCalendarReq.getTimeBegin());
            parseEnd = LocalDate.parse(performanceCalendarReq.getTimeEnd());
            monday = paramBegin.with(TemporalAdjusters.previousOrSame( DayOfWeek.MONDAY));
            sunday = parseEnd.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY ));
        }
        Map<String,String> hashMap = new HashMap();
        hashMap.put("startTime",monday.toString());
        hashMap.put("endTime",sunday.toString());
        return  hashMap;
    }
}
