package com.yonge.cooleshow.tenant.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
import com.yonge.cooleshow.auth.api.entity.SysUser;
import com.yonge.cooleshow.biz.dal.dto.search.StudentSearch;
import com.yonge.cooleshow.biz.dal.entity.Student;
import com.yonge.cooleshow.biz.dal.entity.TenantActivationCode;
import com.yonge.cooleshow.biz.dal.entity.TenantAlbumPurchase;
import com.yonge.cooleshow.biz.dal.entity.TenantGroup;
import com.yonge.cooleshow.biz.dal.entity.TenantGroupAlbum;
import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
import com.yonge.cooleshow.biz.dal.service.OssFileService;
import com.yonge.cooleshow.biz.dal.service.StudentService;
import com.yonge.cooleshow.biz.dal.service.TenantActivationCodeService;
import com.yonge.cooleshow.biz.dal.service.TenantAlbumPurchaseService;
import com.yonge.cooleshow.biz.dal.service.TenantGroupAlbumService;
import com.yonge.cooleshow.biz.dal.service.TenantGroupService;
import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
import com.yonge.cooleshow.biz.dal.vo.StudentHomeVo;
import com.yonge.cooleshow.biz.dal.vo.StudentVo;
import com.yonge.cooleshow.biz.dal.wrapper.OssFileWrapper;
import com.yonge.cooleshow.biz.dal.wrapper.StudentWrapper;
import com.yonge.cooleshow.common.controller.BaseController;
import com.yonge.cooleshow.common.entity.HttpResponseResult;
import com.yonge.cooleshow.common.enums.UserLockFlag;
import com.yonge.cooleshow.common.enums.UserStatusEnum;
import com.yonge.cooleshow.common.enums.YesOrNoEnum;
import com.yonge.toolset.base.exception.BizException;
import com.yonge.toolset.base.page.PageInfo;
import com.yonge.toolset.mybatis.support.PageUtil;
import com.yonge.toolset.utils.easyexcel.ErrMsg;
import com.yonge.toolset.utils.easyexcel.ExcelDataReader;
import com.yonge.toolset.utils.easyexcel.ExcelException;
import com.yonge.toolset.utils.easyexcel.ExcelUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("${app-config.url.tenant:}/student")
@Api(value = "学生表", tags = "学生表")
public class StudentController extends BaseController {

    @Autowired
    private StudentService studentService;
    @Resource
    private SysUserFeignService sysUserFeignService;
    @Autowired
    private TenantInfoService tenantInfoService;

    @Autowired
    private TenantActivationCodeService tenantActivationCodeService;

    @Autowired
    private OssFileService ossFileService;

    @Autowired
    private TenantGroupService tenantGroupService;
    @Autowired
    private TenantAlbumPurchaseService tenantAlbumPurchaseService;
    @Autowired
    private TenantGroupAlbumService tenantGroupAlbumService;

    @GetMapping("/detail/{id}")
    @ApiOperation(value = "详情", notes = "传入id")
    public HttpResponseResult<StudentVo> detail(@PathVariable("id") Long id) {
        StudentVo detail = studentService.detail(id);
        if (detail != null && detail.getTenantGroupId() != null) {
            TenantGroup group = tenantGroupService.getById(detail.getTenantGroupId());
            detail.setTenantGroupName(group == null ? "" : group.getName());
        }
        return succeed(detail);
    }

    @PostMapping("/page")
    @ApiOperation(value = "查询分页", notes = "传入StudentSearch")
    public HttpResponseResult<PageInfo<StudentVo>> page(@RequestBody StudentSearch query) {
        TenantInfo tenantInfo = getTenantInfo();
        query.setTenantId(tenantInfo.getId());
        query.setDelFlag(YesOrNoEnum.NO);
        query.setLockFlag(UserLockFlag.NORMAL);
        query.setOrderBy("u.username_ asc");

        Long tenantAlbumPurchaseId = query.getTenantAlbumPurchaseId();
        if (tenantAlbumPurchaseId != null) {
            // 查询关联这个专辑对应的小组学生
            TenantAlbumPurchase tenantAlbumPurchase = tenantAlbumPurchaseService.getById(tenantAlbumPurchaseId);
            Long tenantAlbumId = tenantAlbumPurchase.getTenantAlbumId();
            List<String> tenantGroupIds = tenantGroupAlbumService.lambdaQuery()
                    .eq(TenantGroupAlbum::getTenantAlbumId, tenantAlbumId)
                    .eq(TenantGroupAlbum::getDelFlag, false)
                    .eq(TenantGroupAlbum::getStatus, true)
                    .list().stream().map(TenantGroupAlbum::getTenantGroupId).map(String::valueOf).distinct().collect(Collectors.toList());
            if (CollectionUtils.isEmpty(tenantGroupIds)) {
                // 没有小组
                return succeed(PageUtil.getPageInfo(PageUtil.getPage(query), new ArrayList<>()));
            }
            String tenantGroupId = query.getTenantGroupId();
            if (StringUtils.isNotEmpty(tenantGroupId)) {
                if(!tenantGroupIds.contains(tenantGroupId)){
                    return succeed(PageUtil.getPageInfo(PageUtil.getPage(query), new ArrayList<>()));
                }
            } else {
                query.setTenantGroupId(String.join(",", tenantGroupIds));
            }
        }

        IPage<StudentVo> pages = studentService.selectPage(PageUtil.getPage(query), query);
        List<StudentVo> rows = pages.getRecords();

        if (rows.isEmpty()) {
            return succeed(PageUtil.pageInfo(pages));
        }

        //如果真实姓名字段为空 把真实姓名赋值给昵称
        rows.stream().forEach(r -> {
            if (StringUtils.isEmpty(r.getRealName())) {
                if (StringUtils.isNotEmpty(r.getUsername()))
                    r.setRealName(r.getUsername());
            }
        });


        Map<String, List<TenantActivationCode>> groupByPhone = new HashMap<>();
        if (!rows.isEmpty() && query.getTenantAlbumPurchaseId() != null) {
            List<String> studentPhones =
                    rows.stream().map(StudentVo::getPhone).filter(StringUtils::isNotEmpty).collect(Collectors.toList());
            groupByPhone = tenantActivationCodeService.lambdaQuery()
                    .eq(TenantActivationCode::getTenantAlbumPurchaseId, query.getTenantAlbumPurchaseId())
                    .in(TenantActivationCode::getActivationPhone, studentPhones)
                    .list().stream().collect(Collectors.groupingBy(TenantActivationCode::getActivationPhone));
        }
        List<Long> tenantGroupIds = rows.stream().map(Student::getTenantGroupId)
                .filter(next -> next != null && next != -1L).distinct().collect(Collectors.toList());
        Map<Long, String> tenantGroupIdNameMap = new HashMap<>();
        if (!tenantGroupIds.isEmpty()) {
            Map<Long, String> tenantGroupMap = tenantGroupService.lambdaQuery()
                    .eq(TenantGroup::getTenantId, tenantInfo.getId())
                    .in(TenantGroup::getId, tenantGroupIds)
                    .list().stream().collect(Collectors.toMap(TenantGroup::getId, TenantGroup::getName));
            tenantGroupIdNameMap.putAll(tenantGroupMap);
        }


        for (StudentVo vo : rows) {
            vo.setSendActiveCodeNum(groupByPhone.getOrDefault(vo.getPhone(), new ArrayList<>()).size());
            if (StringUtils.isNotEmpty(vo.getPhone())) {
                vo.setPhone(vo.getPhone().replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"));
            }
            if (vo.getDelFlag() == YesOrNoEnum.YES) {
                vo.setUserStatus(UserStatusEnum.CLOSED);
            } else {
                if (vo.getLockFlag() == UserLockFlag.LOCKED) {
                    vo.setUserStatus(UserStatusEnum.LOCKED);
                } else {
                    vo.setUserStatus(UserStatusEnum.NORMAL);
                }
            }
            vo.setTenantGroupName(tenantGroupIdNameMap.getOrDefault(vo.getTenantGroupId(), ""));
        }
        return succeed(PageUtil.pageInfo(pages));
    }

    @PostMapping("/exportStudent")
    @ApiOperation(value = "导出学生", notes = "传入TeacherSearch")
    public HttpResponseResult<OssFileWrapper.ExportFile> exportTeacher(@RequestBody StudentSearch query) {
        TenantInfo tenantInfo = getTenantInfo();
        query.setTenantId(tenantInfo.getId());
        query.setDelFlag(YesOrNoEnum.NO);
        query.setLockFlag(UserLockFlag.NORMAL);
        query.setOrderBy("u.username_ asc");
        query.setPage(1);
        query.setRows(9999);

        IPage<StudentVo> pages = studentService.selectPage(PageUtil.getPage(query), query);
        List<StudentVo> rows = pages.getRecords();

        if (rows.isEmpty()) {
            throw new BizException("没有可导出数据");
        }

        List<Long> tenantGroupIds = rows.stream().map(Student::getTenantGroupId)
                .filter(next -> next != null && next != -1L).distinct().collect(Collectors.toList());
        Map<Long, String> tenantGroupIdNameMap = new HashMap<>();
        if (!tenantGroupIds.isEmpty()) {
            Map<Long, String> tenantGroupMap = tenantGroupService.lambdaQuery()
                    .eq(TenantGroup::getTenantId, tenantInfo.getId())
                    .in(TenantGroup::getId, tenantGroupIds)
                    .list().stream().collect(Collectors.toMap(TenantGroup::getId, TenantGroup::getName));
            tenantGroupIdNameMap.putAll(tenantGroupMap);
        }

        List<StudentWrapper.ExportStudentTemplate> templateList = rows.stream().map(next -> {
            StudentWrapper.ExportStudentTemplate template = new StudentWrapper.ExportStudentTemplate();
            template.setUserName(next.getUsername());
            template.setPhone(next.getPhone());
            template.setSubjectName(next.getSubjectName());
            template.setTenantGroupName(tenantGroupIdNameMap.getOrDefault(next.getTenantGroupId(), ""));
            return template;
        }).collect(Collectors.toList());

        String format = new SimpleDateFormat("yyyyMMddHHmm").format(new Date());
        OssFileWrapper.ExportFile exportFile = ossFileService.uploadFile(templateList,
                StudentWrapper.ExportStudentTemplate.class, format, "学生", "student");
        return succeed(exportFile);
    }

    @PostMapping("/save")
    @ApiOperation(value = "新增/修改", notes = "传入Student")
    public HttpResponseResult<Boolean> save(
            @Validated @RequestBody com.yonge.cooleshow.tenant.vo.StudentVo.Student student) {
        StudentWrapper.Student studentInfo = JSON.parseObject(JSON.toJSONString(student), StudentWrapper.Student.class);
        TenantInfo tenantInfo = getTenantInfo();
        studentInfo.setTenantId(tenantInfo.getId());

        Long studentId = student.getId();

        if (studentId == null) {
            SysUser sysUser = sysUserFeignService.queryUserByMobile(student.getPhone());
            if (sysUser != null && sysUser.getUserType().contains(ClientEnum.STUDENT.getCode())) {
                studentId = sysUser.getId();
            }
        }

        if (studentId != null) {
            Student one = studentService.lambdaQuery()
                    .eq(Student::getUserId, studentId)
                    .eq(Student::getHideFlag, 0)
                    .last("limit 1").one();
            if (one != null) {
                if (one.getTenantId().equals(-1L)) {
                    throw new BizException("该手机号已经注册为平台学生");
                } else if (!one.getTenantId().equals(tenantInfo.getId())) {
                    throw new BizException("该手机号已经注册为其他平台学生");
                }
            }
        }

        studentService.save(studentInfo);
        return succeed();
    }

    @PostMapping("/importExcel")
    @ApiOperation(value = "导入", notes = "传入file")
    public HttpResponseResult<List<ErrMsg>> importExcel(@RequestParam("file") MultipartFile file) {
        if (null == file) {
            return HttpResponseResult.failed("请上传文件");
        }
        SysUser user = sysUserFeignService.queryUserInfo();
        if (user == null || null == user.getId()) {
            return failed(HttpStatus.FORBIDDEN, "请登录");
        }
        try {
            ExcelDataReader<StudentWrapper.StudentImport> reader =
                    ExcelUtils.getReader(StudentWrapper.StudentImport.class, file);
            studentService.importStudentExcel(reader.getDataList(), user.getTenantId(), user.getId());
            return HttpResponseResult.succeed();
        } catch (ExcelException e) {
            log.error("导入学生失败：" + JSON.toJSONString(e.getErrMsgList()));
            return HttpResponseResult.failed("文件解析失败");
        }
    }

    private TenantInfo getTenantInfo() {
        SysUser sysUser = sysUserFeignService.queryUserInfo();
        TenantInfo tenantInfo = tenantInfoService.getById(sysUser.getTenantId());
        if (tenantInfo == null) {
            throw new BizException("非法请求");
        }
        return tenantInfo;
    }
    @ApiOperation(value = "查询学员基本信息")
    @GetMapping("/queryUserInfo")
    public HttpResponseResult<StudentHomeVo> queryUserInfo(Long userId) throws Exception {
        SysUser user = sysUserFeignService.queryUserById(userId);
        if (user == null || null == user.getId()) {
            return failed(500, "参数错误");
        }
        return succeed(studentService.queryUserInfo(user));
    }

    @ApiOperation(value = "设置系统默认客服")
    @GetMapping("/updateUserCustomerService")
    public HttpResponseResult<String> updateUserCustomerService() {

        SysUser user = sysUserFeignService.queryUserInfo();
        if (user == null || null == user.getId()) {
            return failed(HttpStatus.FORBIDDEN, "请登录");
        }

        return succeed(studentService.updateUserCustomerService(user));
    }
}