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

import com.alibaba.fastjson.JSON;
import com.microsvc.toolkit.common.response.paging.QueryInfo;
import com.yonge.cooleshow.biz.dal.entity.SysMusicCompareRecord;
import com.yonge.cooleshow.biz.dal.enums.DeviceTypeEnum;
import com.yonge.cooleshow.biz.dal.enums.FeatureType;
import com.yonge.cooleshow.biz.dal.enums.HeardLevelEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;

import java.math.BigDecimal;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.WeekFields;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.OptionalInt;

/**
 * 曲目练习记录
 * 2022-12-07 10:16:58
 */
@ApiModel(value = "MusicPracticeRecordWrapper对象", description = "曲目练习记录查询对象")
public class MusicPracticeRecordWrapper {

    @Data
	@Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @ApiModel(" MusicPracticeRecordQuery-曲目练习记录")
    public static class MusicPracticeRecordQuery implements QueryInfo {

    	@ApiModelProperty("当前页")
        private Integer page;

        @ApiModelProperty("分页行数")
        private Integer rows;

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

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


        @ApiModelProperty("最低总分")
        private BigDecimal minScore = BigDecimal.ZERO;


        @ApiModelProperty("最高总分")
        private BigDecimal maxScore = new BigDecimal(100);

        @ApiModelProperty("是否生成作品")
        private Boolean userMusicFlag;

        @ApiModelProperty("生成作品开始时间")
        private Date userMusicStartTime;

        @ApiModelProperty("生成作品结束时间")
        private Date userMusicEndTime;

        @ApiModelProperty("关键字匹配")
		private String keyword;

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

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


        @ApiModelProperty("班级ID")
        private Long classGroupId;

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

        @ApiModelProperty("功能")
        private String feature;

        @ApiModelProperty("练习类型")
        private List<String> practiceTypes;

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

        @ApiModelProperty("练习时间(按月:202209)")
        private String practiceMonth;

        @ApiModelProperty("练习来源")
        private String practiceSource;


        @ApiModelProperty("评测乐器ID")
        private Long instrumentId;


        @ApiModelProperty("声部Id")
        private String subjectId;

        @ApiModelProperty("乐团Id")
        private String orchestraId;

        @ApiModelProperty("学校Id")
        private Long schoolId;

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

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

        @ApiModelProperty("伴学老师Id")
        private Long teacherId;

        @ApiModelProperty("删除标记")
        private Boolean delFlag;

        @ApiModelProperty("练习达标时间")
        private Integer practiceTargetMinute;

        @ApiModelProperty("周练习达标匹配")
        private Boolean practiceTargetMatch;

        @ApiModelProperty("周练习匹配")
        private Boolean practiceMatch;

        @ApiModelProperty("老师统计查询")
        private Boolean teacherStatQuery;

        @ApiModelProperty("学校统计查询")
        private Boolean schoolStatQuery;

        @ApiModelProperty("完整评测标记")
        private Boolean completeEvaluation;

        @ApiModelProperty("排除学生人数")
        private List<Long> excludeStudentIds;

        @ApiModelProperty("排序字段，1：综合得分，2：音准，3：节奏：4：完整度，5：评测时间 6:生成时间，7:评测进度")
        private Integer sortType;

        @ApiModelProperty("是否升序")
        private Boolean asc;


        public String getKeyword() {
            return Optional.ofNullable(keyword).filter(StringUtils::isNotBlank).orElse(null);
        }

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

        public static MusicPracticeRecordQuery from(String json) {
            return JSON.parseObject(json, MusicPracticeRecordQuery.class);
        }

        public String getSubjectId() {
            return Optional.ofNullable(subjectId).filter(StringUtils::isNotBlank).orElse(null);
        }

        public String getOrchestraId() {
            return Optional.ofNullable(orchestraId).filter(StringUtils::isNotBlank).orElse(null);
        }

        public String getPracticeMonth() {
            return Optional.ofNullable(practiceMonth).filter(StringUtils::isNotBlank).orElse(null);
        }

        public MusicPracticeRecordQuery scoreData(Boolean scoreData) {
            this.scoreData = scoreData;
            return this;
        }


        public MusicPracticeRecordQuery userId(String userId) {
            this.userId = Long.parseLong(userId);
            return this;
        }

        public MusicPracticeRecordQuery clientType(String clientType) {
            this.clientType = clientType;
            return this;
        }
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
	@ApiModel(" MusicPracticeRecord-曲目练习记录")
    public static class MusicPracticeRecord {

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

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

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

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

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

        @ApiModelProperty("行为编号，同一编号为一次")
        private String behaviorId;

        @ApiModelProperty("评分数据")
        private String scoreData;

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

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

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

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

        @ApiModelProperty("录音文件地址")
        private String recordFilePath;

        @ApiModelProperty("录像文件地址")
        private String videoFilePath;

        @ApiModelProperty("设备类型")
        private String deviceType;

        @ApiModelProperty("源音时长")
        private Float sourceTime;

        @ApiModelProperty("演奏时长")
        private Float playTime;


        @ApiModelProperty("演奏倍率")
        private Float playRate;


        @ApiModelProperty("速度")
        private String speed;

        @ApiModelProperty("周一日期")
        private String monday;

        @ApiModelProperty("功能")
        private String feature;

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

        @ApiModelProperty("部分索引")
        private String partIndex;

        @ApiModelProperty("自定义配置 默认空字符串")
        private String customConfiguration;

        @ApiModelProperty("练习时间")
        private String practiceTime;

        @ApiModelProperty("练习来源")
        private String practiceSource;

        @ApiModelProperty("更新时间")
        private Date updateTime;

        @ApiModelProperty("创建时间")
        private Date createTime;

        @ApiModelProperty("评测乐器ID")
        private Long instrumentId;

        @ApiModelProperty("评测乐器")
        private String instrumentName;

        @ApiModelProperty("是否节奏音乐")
        private Boolean rhythmFlag;

        @ApiModelProperty("收费类型(FREE:免费;VIP:会员;CHARGE:单曲收费)")
        private String paymentType;

        @ApiModelProperty("是否生成作品")
        private Boolean userMusicFlag;

        @ApiModelProperty("生成作品时间")
        private Date userMusicTime;

        @ApiModelProperty("评测进度")
        private BigDecimal evaluationProgressNumber;

        @ApiModelProperty("评测进度")
        private String evaluationProgress;

        @ApiModelProperty("是否佩戴耳机")
        private Boolean headphoneFlag;

        @ApiModelProperty("假删除标识 0：未删除 1：已删除")
        private Boolean delFlag;

        @ApiModelProperty("曲目评测来源 TENANT 机构 PLATFORM 平台")
        private String providerType;

        @ApiModelProperty("是否隐藏评测记录 0：不隐藏 1：隐藏")
        private Boolean hiddenFlag;

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

        public static MusicPracticeRecord from(String json) {
            return JSON.parseObject(json, MusicPracticeRecord.class);
        }

        // 初始化默认值
        public MusicPracticeRecord initDefaultValue() {

            return this.customConfiguration(Optional.ofNullable(getCustomConfiguration()).orElse(""))
                .monday(Optional.ofNullable(getMonday()).orElse(LocalDate.now().with(WeekFields.of(DayOfWeek.MONDAY, 1).dayOfWeek(), DayOfWeek.MONDAY.getValue()).toString()))
                .sourceTime(Optional.ofNullable(getSourceTime()).orElse(0F))
                .playTime(Optional.ofNullable(getPlayTime()).orElse(0F))
                .speed(Optional.ofNullable(getSpeed()).orElse("90"))
                .practiceTime(Optional.ofNullable(getPracticeTime()).orElse(DateTime.now().toString("yyyyMMdd")));
        }


        public MusicPracticeRecord sourceTime(Float sourceTime) {
            this.sourceTime = sourceTime;
            return this;
        }

        public MusicPracticeRecord playTime(Float playTime) {
            this.playTime = playTime;
            return this;
        }

        public MusicPracticeRecord speed(String speed) {
            this.speed = speed;
            return this;
        }

        public MusicPracticeRecord monday(String monday) {
            this.monday = monday;
            return this;
        }

        public MusicPracticeRecord customConfiguration(String customConfiguration) {
            this.customConfiguration = customConfiguration;
            return this;
        }

        public MusicPracticeRecord practiceTime(String practiceTime) {
            this.practiceTime = practiceTime;
            return this;
        }

        public MusicPracticeRecord userId(String userId) {
            this.userId = Long.parseLong(userId);
            return this;
        }

        public MusicPracticeRecord clientType(String clientType) {
            this.clientType = clientType;
            return this;
        }
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class Entity{

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

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

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

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

        @ApiModelProperty("行为编号，同一编号为一次")
        private String behaviorId;

        @ApiModelProperty("评分数据")
        private String scoreData;

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

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

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

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

        @ApiModelProperty("录音文件地址")
        private String recordFilePath;

        @ApiModelProperty("录像文件地址")
        private String videoFilePath;

        @ApiModelProperty("设备类型")
        private String deviceType;

        @ApiModelProperty("源音时长")
        private Float sourceTime;

        @ApiModelProperty("演奏时长")
        private Float playTime;



        @ApiModelProperty("演奏倍率")
        private Float playRate;


        @ApiModelProperty("速度")
        private String speed;

        @ApiModelProperty("周一日期")
        private String monday;

        @ApiModelProperty("功能")
        private String feature;

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


        @ApiModelProperty("评测乐器ID")
        private String instrumentId;


        @ApiModelProperty("评测结果分析")
        private String resultAnalyze;

        @ApiModelProperty("部分索引")
        private String partIndex;

        @ApiModelProperty("练习时间")
        private String practiceTime;

        @ApiModelProperty("练习来源")
        private String practiceSource;

        @ApiModelProperty("自定义配置 默认空字符串")
        private String customConfiguration;


        @ApiModelProperty("是否佩戴耳机")
        private Boolean headphoneFlag;

        @ApiModelProperty("更新时间")
        private Date updateTime;

        @ApiModelProperty("创建时间")
        private Date createTime;

        @ApiModelProperty("假删除标识 0：未删除 1：已删除")
        private Boolean delFlag;


        @ApiModelProperty("曲目评测来源 TENANT 机构 PLATFORM 平台")
        private String providerType;

        public static Entity toEntity(SysMusicCompareRecord record) {
            if (record ==null) {
                return null;
            }
            return Entity.builder()
                .id(record.getId().toString())
                .userId(Optional.ofNullable(record.getUserId()).orElse(0L).toString())
                .clientType(record.getClientId()!=null?record.getClientId().toUpperCase():null)
                .musicSheetId(record.getMusicSheetId()!=null? record.getMusicSheetId().toString():null)
                .behaviorId(record.getBehaviorId())
                .scoreData(record.getScoreData())
                .score(record.getScore())
                .intonation(record.getIntonation())
                .cadence(record.getCadence())
                .integrity(record.getIntegrity())
                .recordFilePath(record.getRecordFilePath())
                .videoFilePath(record.getVideoFilePath())
                .deviceType(record.getDeviceType() !=null?record.getDeviceType().name():null)
                .sourceTime(record.getSourceTime())
                .playTime(record.getPlayTime())
                .playRate(record.getPlayRate())
                .speed(String.valueOf(OptionalInt.of(record.getSpeed()).orElse(0)))
                .monday(record.getMonday())
                .feature(record.getFeature()!=null?record.getFeature().toCbs():null)
                .heardLevel(record.getHeardLevel() !=null?record.getHeardLevel().getCode():null)
                .instrumentId(record.getInstrumentId()!=null?record.getInstrumentId().toString():null)
                .resultAnalyze(record.getResultAnalyze())
                .partIndex(record.getPartIndex())
                .practiceTime(record.getPracticeTime())
                .practiceSource(record.getPracticeSource())
                .customConfiguration(record.getCustomConfiguration())
                .headphoneFlag(record.getHeadphoneFlag())
                .updateTime(record.getCreateTime())
                .createTime(record.getCreateTime())
                .delFlag(record.getDelFlag())
                .providerType(record.getProviderType())
                .build();
        }

        public SysMusicCompareRecord toSysMusicCompareRecord(){
            SysMusicCompareRecord sysMusicCompareRecord = new SysMusicCompareRecord();
            sysMusicCompareRecord.setId((this.id!=null?Long.parseLong(this.id):null));
            sysMusicCompareRecord.setBehaviorId((this.behaviorId));
            sysMusicCompareRecord.setUserId(this.userId!=null?Long.parseLong(this.userId):null);
            sysMusicCompareRecord.setMusicSheetId(this.musicSheetId!=null?Long.parseLong(this.musicSheetId):null);
            sysMusicCompareRecord.setHeardLevel(this.heardLevel!=null? HeardLevelEnum.valueOf(this.heardLevel):null);
            sysMusicCompareRecord.setScoreData(this.scoreData);
            sysMusicCompareRecord.setScore(this.score);
            sysMusicCompareRecord.setIntonation(this.intonation);
            sysMusicCompareRecord.setCadence(this.cadence);
            sysMusicCompareRecord.setIntegrity(this.integrity);
            sysMusicCompareRecord.setRecordFilePath(this.recordFilePath);
            sysMusicCompareRecord.setVideoFilePath(this.videoFilePath);
            sysMusicCompareRecord.setClientId(this.clientType!=null?this.clientType.toLowerCase():null);
            sysMusicCompareRecord.setDeviceType(DeviceTypeEnum.valueOf(this.deviceType));
            sysMusicCompareRecord.setSourceTime(this.sourceTime);
            sysMusicCompareRecord.setPlayTime(this.playTime);
            sysMusicCompareRecord.setSpeed(this.speed!=null?Integer.parseInt(this.speed):90);
            sysMusicCompareRecord.setMonday(this.monday);
            sysMusicCompareRecord.setFeature(this.feature!=null? FeatureType.format(this.feature):null);
            sysMusicCompareRecord.setHeardLevel(this.heardLevel!=null? HeardLevelEnum.valueOf(this.heardLevel):null);
            sysMusicCompareRecord.setCreateTime(this.createTime);
            sysMusicCompareRecord.setPartIndex(this.partIndex);
            sysMusicCompareRecord.setCustomConfiguration(this.customConfiguration);
            sysMusicCompareRecord.setPracticeTime(this.practiceTime);
            sysMusicCompareRecord.setPracticeSource(this.practiceSource);
            sysMusicCompareRecord.setResultAnalyze(this.resultAnalyze);
            sysMusicCompareRecord.setHeadphoneFlag(this.headphoneFlag);
            sysMusicCompareRecord.setInstrumentId(this.instrumentId!=null?Long.parseLong(this.instrumentId):null);
            sysMusicCompareRecord.setDelFlag(this.delFlag);
            sysMusicCompareRecord.setPlayRate(this.playRate);
            sysMusicCompareRecord.setProviderType(this.providerType ==null?"PLATFORM":this.providerType);

            return sysMusicCompareRecord;

        }
    }
}
