package com.yonge.cooleshow.biz.dal.wrapper.music;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.yonge.cooleshow.biz.dal.enums.*;
import com.yonge.cooleshow.biz.dal.enums.music.MusicCompareType;
import com.yonge.cooleshow.biz.dal.vo.MusicAlbumVo;
import com.yonge.cooleshow.biz.dal.vo.MusicSheetVo;
import com.yonge.cooleshow.common.enums.YesOrNoEnum;
import com.yonge.toolset.base.page.PageInfo;
import com.yonge.toolset.base.page.QueryInfo;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.checkerframework.checker.units.qual.A;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * Created by Eric.Shang on 2022/10/17.
 */
public class MusicCompareWrapper {

    /**
     * 统计汇总查询条件
     */
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @EqualsAndHashCode(callSuper = false)
    public static class StatQueryInfo extends QueryInfo {

        @ApiModelProperty("客户端类型 TEACHER(老师端) STUDENT(学生端)")
        private ClientEnum clientType;

        @ApiModelProperty("用户ID ")
        private Long userId;

        @ApiModelProperty("排序类型 ")
        private MusicCompareType compareType;

        @ApiModelProperty("排序字段")
        private String compareField;

        @ApiModelProperty("排序方式 升序(ASC) 降序(DESC)")
        private String sortType;

        @ApiModelProperty("练习曲目")
        private Boolean trainMusic;

        @ApiModelProperty("评测曲目")
        private Boolean evaluateMusic;

        @ApiModelProperty("曲目ID")
        private Long musicId;

        @ApiModelProperty("曲目名称")
        private String musicName;

        @ApiModelProperty("开始时间")
        private Long startTime;

        @ApiModelProperty("结束时间")
        private Long endTime;

        public static StatQueryInfo from(String record) {

            return JSON.parseObject(record, StatQueryInfo.class);
        }

        public String getCompareField() {
            return getCompareType().getSortField();
        }

        public String jsonString() {
            return JSON.toJSONString(this);
        }


        public StatQueryInfo trainMusic(Boolean trainMusic) {
            this.trainMusic = trainMusic;
            return this;
        }

        public StatQueryInfo evaluateMusic(Boolean evaluateMusic) {
            this.evaluateMusic = evaluateMusic;
            return this;
        }
    }

    /**
     * 曲目统计汇总信息
     */
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class RecordStat implements Serializable {

        @ApiModelProperty("练习曲目总数")
        private Long trainMusicNums;

        @ApiModelProperty("使用时长")
        private Long trainDuration;

        @ApiModelProperty("使用次数")
        private Long trainFrequency;

        @ApiModelProperty("评测曲目总数")
        private Long evaluateMusicNums;

        @ApiModelProperty("评测时长")
        private Long evaluateDuration;

        @ApiModelProperty("评测次数")
        private Long evaluateFrequency;

        private List<RecordInfo> recordInfos;

        public String jsonString() {

            return JSON.toJSONString(this);
        }


        public RecordStat trainMusicNums(Long trainMusicNums) {
            this.trainMusicNums = trainMusicNums;
            return this;
        }

        public RecordStat trainDuration(Long trainDuration) {
            this.trainDuration = trainDuration;
            return this;
        }

        public RecordStat trainFrequency(Long trainFrequency) {
            this.trainFrequency = trainFrequency;
            return this;
        }

        public RecordStat evaluateMusicNums(Long evaluateMusicNums) {
            this.evaluateMusicNums = evaluateMusicNums;
            return this;
        }

        public RecordStat evaluateDuration(Long evaluateDuration) {
            this.evaluateDuration = evaluateDuration;
            return this;
        }

        public RecordStat evaluateFrequency(Long evaluateFrequency) {
            this.evaluateFrequency = evaluateFrequency;
            return this;
        }
    }

    /**
     * 曲目统计信息
     */
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class RecordInfo implements Serializable {

        @ApiModelProperty("主键ID")
        private Long id;

        @ApiModelProperty("曲目ID")
        private Long musicSheetId;

        @ApiModelProperty("客户端标识")
        private ClientEnum clientId;

        @ApiModelProperty("用户编号")
        private Long userId;

        @ApiModelProperty("曲目名称")
        private String musicName;

        @ApiModelProperty("作曲人")
        private String composer;

        @ApiModelProperty("音乐标签编号")
        private String musicTag;

        @ApiModelProperty("音乐标签")
        private String musicTagName;

        @ApiModelProperty("使用时长")
        private Long trainDuration;

        @ApiModelProperty("使用次数")
        private Long trainFrequency;

        @ApiModelProperty("评测时长")
        private Long evaluateDuration;

        @ApiModelProperty("评测次数")
        private Long evaluateFrequency;

        @ApiModelProperty("最近使用时间")
        private Long recentTime;

        public String jsonString() {
            return JSON.toJSONString(this);
        }

        public RecordInfo trainDuration(Long trainDuration) {
            this.trainDuration = trainDuration;
            return this;
        }

        public RecordInfo trainFrequency(Long trainFrequency) {
            this.trainFrequency = trainFrequency;
            return this;
        }

        public RecordInfo evaluateDuration(Long evaluateDuration) {
            this.evaluateDuration = evaluateDuration;
            return this;
        }

        public RecordInfo evaluateFrequency(Long evaluateFrequency) {
            this.evaluateFrequency = evaluateFrequency;
            return this;
        }

        public RecordInfo recentTime(Long recentTime) {
            this.recentTime = recentTime;
            return this;
        }
    }

    /**
     * 曲目练习记录查询
     */
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class RecordQueryInfo implements Serializable {

        @ApiModelProperty("用户ID ")
        private Long userId;

        @ApiModelProperty("曲目编号 ")
        private Long musicSheetId;

        @ApiModelProperty("客户端类型 ")
        private String clientId;

        @ApiModelProperty("功能类型 ")
        private FeatureType feature;

        @ApiModelProperty("评测结果数据 ")
        private Boolean scoreData;
    }

    /**
     * 曲目评测查询条件
     */
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @EqualsAndHashCode(callSuper = false)
    public static class EvaluteQueryInfo extends QueryInfo {

        @ApiModelProperty("客户端类型 TEACHER(老师端) STUDENT(学生端)")
        private ClientEnum clientType;

        @ApiModelProperty("用户ID ")
        private Long userId;

        @ApiModelProperty("曲目ID ")
        private Long musicId;

        @ApiModelProperty("评测难度")
        private HeardLevelEnum heardLevel;

        @ApiModelProperty("评测类型")
        private FeatureType feature;

        @ApiModelProperty("评测结果数据 ")
        private Boolean scoreData;

        @ApiModelProperty("开始时间")
        private Date startTime;

        @ApiModelProperty("结束时间")
        private Date endTime;

        public static EvaluteQueryInfo from(String record) {

            return JSON.parseObject(record, EvaluteQueryInfo.class);
        }

        public FeatureType getFeature() {
            return Optional.ofNullable(feature).orElse(FeatureType.CLOUD_STUDY_EVALUATION);
        }
    }

    /**
     * 曲目评测记录信息
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class RecordEvaluate implements Serializable {

        @ApiModelProperty("评测记录ID ")
        private Long id;

        @ApiModelProperty("评测难度: 入门级,进阶级,大师级")
        private HeardLevelEnum heardLevel;

        @ApiModelProperty("总分 ")
        private BigDecimal score;

        @ApiModelProperty("音准 ")
        private BigDecimal intonation;

        @ApiModelProperty("节奏")
        private BigDecimal cadence;

        @ApiModelProperty("完成度 ")
        private BigDecimal integrity;

        @ApiModelProperty("评测时间")
        @JsonFormat(pattern = MK.TIME_PATTERN, timezone = MK.TIME_ZONE)
        private Date createTime;
    }

    /**
     * 用户曲目练习时间统计
     */
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class UserMusicCompareRecord implements Serializable {

        @ApiModelProperty("练习时长 ")
        private Long trainTime;

        @ApiModelProperty("评测时长 ")
        private Long evaluateTime;

        public String jsonString() {
            return JSON.toJSONString(this);
        }

    }


    /**
     * 用户曲目练习时间统计
     */
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class MusicSearch extends QueryInfo {

        @ApiModelProperty("声部ID ")
        private Integer subjectId;

        @ApiModelProperty("名称 ")
        private String name;

        @ApiModelProperty(value = "提供方 TENANT 机构 PLATFORM 平台")
        private SourceTypeEnum providerType;

        @ApiModelProperty("类型 MUSIC 曲目 ALBUM专辑")
        private String type;

        @ApiModelProperty(value = "机构专辑ID",hidden = true)
        private List<Long> tenantAlbumIds;

        @ApiModelProperty(hidden = true)
        private Long userId;
    }



    /**
     * 用户曲目练习时间统计
     */
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class SearchData {

        @ApiModelProperty("下拉名称 ")
        private List<MusicName> musicNames;

        @ApiModelProperty("曲目分页")
        private PageInfo<MusicSheetVo> music;

        @ApiModelProperty("专辑分页")
        private PageInfo<MusicAlbumVo> album;
    }


    /**
     * 用户曲目练习时间统计
     */
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class MusicName{

        @ApiModelProperty("曲目/专辑ID ")
        private Long id;

        @ApiModelProperty("名称 ")
        private String name;

        @ApiModelProperty("收藏 0：否，1：是")
        private YesOrNoEnum favorite = YesOrNoEnum.NO;

        @ApiModelProperty(value = "是否热门曲谱(0:否;1:是)")
        private YesOrNoEnum hotFlag = YesOrNoEnum.NO;  //是否热门曲谱(0:否;1:是)

        @ApiModelProperty("类型 MUSIC 曲目 ALBUM专辑")
        private String type;

        @ApiModelProperty("排序")
        private Integer sort = 0;

        @ApiModelProperty("机构专辑ID,逗号隔开")
        private String tenantAlbumId;
    }
}
