package org.jeecg.modules.app.controller.commercial;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.app.form.ClassPostponeForm;
import org.jeecg.modules.app.form.CourseQueryUsersForm;
import org.jeecg.modules.app.form.TemporaryCourseForm;
import org.jeecg.modules.app.service.IAppIsinService;
import org.jeecg.modules.app.vo.*;
import org.jeecg.modules.system.app.entity.*;
import org.jeecg.modules.system.app.form.VerifyForm;
import org.jeecg.modules.system.app.service.*;
import org.springframework.web.bind.annotation.*;

import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Tag(name = "App商家端课程相关接口")
@RestController
@AllArgsConstructor
@RequestMapping("/app/course")
public class CommercialController {

    private final IAppOrderService appOrderService;

    private final IAppOrderProInfoService appOrderProInfoService;

    private final IAppCoureseService appCoureseService;

    private final IAppCoursesPriceRulesService appCoursesPriceRulesService;

    private final IAppCoursesVerificationRecordService appCoursesVerificationRecordService;

    private final IFamilyMembersService familyMembersService;

    private final IAppIsinService appIsinService;

    private final IAppInstructorService appInstructorService;

    /**
     * 查询部门下的课程
     *
     * @param orgCode
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Operation(summary = "查询部门下的课程 ")
    @GetMapping("/getPageCourse")
    public Result<IPage<AppCoursesPageVO>> getPageCourse(@Schema(description = "部门编号") @RequestParam(name = "orgCode") String orgCode,
                                                         @Schema(description = "页数") @RequestParam(name = "pageNo") Integer pageNo,
                                                         @Schema(description = "条数") @RequestParam(name = "pageSize") Integer pageSize) {
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        String userId = null;
        //如果是教练
        String roleCode = loginUser.getRoleCode();
        if (roleCode.contains("instructor")) {
            userId = loginUser.getId();
        }
        Page<AppCoursesPageVO> page = new Page<>(pageNo, pageSize);
        IPage<AppCoursesPageVO> pageList = appCoureseService.getPageCourse(page,orgCode,userId);
        return Result.OK(pageList);
    }

    /**
     * 课程详情
     *
     * @param courseId
     * @return
     */
    @Operation(summary = "课程详情")
    @GetMapping("/getCourseInfo/{courseId}")
    public Result<List<CoursesPriceRulesVO>> getCourseInfo(@Schema(description = "课程ID") @PathVariable("courseId") String courseId) {
        return Result.OK(appCoureseService.getCourseInfo(courseId));
    }

    /**
     * 拍照验课上传图片
     *
     * @param verifyForm
     * @return
     */
    @Operation(summary = "拍照验课上传图片")
    @PostMapping("/courseUploadImage")
    public Result<Boolean> courseUploadImage(@RequestBody VerifyForm verifyForm) {
        return Result.OK(appCoursesVerificationRecordService.courseUploadImage(verifyForm));
    }

    /**
     * 拍照验课人员查看
     *
     * @param form
     * @return
     */
    @Operation(summary = "拍照验课人员查看")
    @PostMapping("/courseQueryUsers")
    public Result<List<AppCoursesVerificationRecord>> courseQueryUsers(@RequestBody CourseQueryUsersForm form) {
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        //如果不是教练
        String roleCode = loginUser.getRoleCode();
        if (!roleCode.contains("instructor")) {
            loginUser.setId(null);
        }
        List<AppCoursesVerificationRecord> verificationRecords =
                appCoursesVerificationRecordService.courseQueryUsersList(form.getCoursePriceRulesId(),form.getOrPostpone(), form.getVerifyStatus(),loginUser.getId());
        List<AppCoursesVerificationRecord> temporaryCourseList =
                appCoursesVerificationRecordService.queryTemporaryCourseUser(form.getCoursePriceRulesId(),form.getOrPostpone(),form.getVerifyStatus(),loginUser.getId());
        verificationRecords.addAll(temporaryCourseList);
        List<AppCoursesVerificationRecord> list = verificationRecords.stream()
                .collect(Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(AppCoursesVerificationRecord::getUseUserId))),
                        ArrayList::new
                ));
        return Result.OK(list);
    }

    /**
     * 根据姓名查询用户
     *
     * @param name
     * @return
     */
    @Operation(summary = "根据姓名查询用户 ")
    @GetMapping("/getFamilyMembersByName")
    public Result<List<FamilyMembers>> getFamilyMembersByName(@RequestParam(name = "courseId") String courseId,@RequestParam(name = "name") String name) {
        List<AppOrderProInfo> orderProInfoList = appOrderProInfoService.list(Wrappers.<AppOrderProInfo>lambdaQuery().eq(AppOrderProInfo::getProductId, courseId));
        List<String> familUserIds = orderProInfoList.stream().map(AppOrderProInfo::getFamilyUserId).distinct().collect(Collectors.toList());
        List<FamilyMembers> list = familyMembersService.list(Wrappers.<FamilyMembers>lambdaQuery().like(FamilyMembers::getFullName, name));
        // 去除list中存在于familUserIds的元素
        List<FamilyMembers> differenceList = list.stream()
                .filter(e -> !familUserIds.contains(e.getId()))
                .collect(Collectors.toList());
        List<FamilyMembers> unique = differenceList.stream().collect(
                Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(FamilyMembers::getPhone))),
                        ArrayList::new)
        );
        return Result.OK(unique);
    }

    /**
     * 临时约课
     *
     * @param temporaryCourseForm
     * @return
     */
    @Operation(summary = "临时约课")
    @PostMapping("/temporaryCourse")
    public Result<Boolean> temporaryCourse(@RequestBody TemporaryCourseForm temporaryCourseForm) {
        return Result.OK(appCoureseService.temporaryCourse(temporaryCourseForm));
    }

    /**
     * 课时延期学生列表
     *
     * @param coursePriceRulesId
     * @return
     */
    @Operation(summary = "课时延期学生列表")
    @GetMapping("/getClassPostponeUsers")
    public Result<List<FamilyUserVO>> getClassPostponeUsers(@Schema(description = "课时ID") @RequestParam(name = "coursePriceRulesId") String coursePriceRulesId) {
        return Result.OK(appCoureseService.getClassPostponeUsers(coursePriceRulesId));
    }

    /**
     * 课时延期（创建补课课时）
     *
     * @param form
     * @return
     */
    @Operation(summary = "课时延期（创建补课课时）")
    @PostMapping("/classPostpone")
    public Result<Boolean> classPostpone(@RequestBody ClassPostponeForm form) {
        return Result.OK(appCoureseService.classPostpone(form));
    }

    /**
     * 扫码核销查询订单详情
     *
     * @param orderId
     * @return
     */
    @Operation(summary = "扫码核销查询订单详情")
    @GetMapping("/scanCodeQueryOrder")
    public Result<ScanCodeQueryOrderVO> scanCodeQueryOrder(@Schema(description = "课时ID") @RequestParam(name = "orderId") String orderId) {
        return Result.OK(appOrderService.scanCodeQueryOrder(orderId));
    }

    /**
     * 扫码核销确认
     *
     * @param orderProInfoIds
     * @return
     */
    @Operation(summary = "扫码核销确认")
    @PutMapping("/scanCodeVerification")
    public Result<Boolean> scanCodeVerification(@RequestBody List<String> orderProInfoIds) {
        return Result.OK(appOrderService.scanCodeVerification(orderProInfoIds));
    }

    /**
     * 查询补课课表
     * @return
     */
    @Operation(summary = "查询补课课表")
    @GetMapping("/queryMakeUpClassTable")
    public Result<List<AppCoursesPriceRules>> queryMakeUpClassTable() {
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        List<AppCoursesPriceRules> list = appCoursesPriceRulesService.list(Wrappers.<AppCoursesPriceRules>lambdaQuery()
                .eq(AppCoursesPriceRules::getCoursesType, 1)
                .eq(AppCoursesPriceRules::getOrgCode, loginUser.getOrgCode()));
        return Result.OK(list);
    }

    /**
     * 查询部门下的核销记录
     *
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Operation(summary = "查询部门下的使用核销记录")
    @GetMapping("/pageAppIsinVerifyRecords")
    public Result<IPage<AppIsinVerifyVO>> pageAppIsinVerifyRecords(@Schema(description = "页数") @RequestParam(name = "pageNo") Integer pageNo,
                                                                   @Schema(description = "条数") @RequestParam(name = "pageSize") Integer pageSize) {
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        List<AppInstructor> list = appInstructorService.list();
        List<AppInstructor> collect = list.stream().filter(e -> Objects.equals(loginUser.getId(), e.getUserId())).collect(Collectors.toList());
        String orgCode = loginUser.getOrgCode();
        Page<AppIsinVerifyVO> page = new Page<>(pageNo, pageSize);
        //是否为教练
        if (CollUtil.isNotEmpty(collect)){
            Page<AppIsinVerifyVO> pageList = appIsinService.pageAppIsinVerifies(page, orgCode);
            return Result.OK(pageList);
        }
        Page<AppIsinVerifyVO> pageList = appIsinService.pageAppIsinVerifyRecords(page, orgCode);
        return Result.OK(pageList);
    }

    /**
     * 使用核销记录撤销
     *
     * @param appIsinId
     * @return
     */
    @Operation(summary = "使用核销记录撤销 ")
    @PutMapping("/repealVerifyRecord")
    public Result<String> repealVerifyRecord(@Schema(description = "appIsinId") @RequestParam(name = "appIsinId") String appIsinId) throws ParseException {
        return Result.OK(appIsinService.repealVerifyRecord(appIsinId));
    }
}
