package com.competition.modules.biz.homework.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.competition.common.enums.ErrorCode;
import com.competition.common.exception.BusinessException;
import com.competition.common.result.PageResult;
import com.competition.modules.biz.homework.dto.CreateHomeworkDto;
import com.competition.modules.biz.homework.entity.BizHomework;
import com.competition.modules.biz.homework.mapper.HomeworkMapper;
import com.competition.modules.biz.homework.service.IHomeworkService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class HomeworkServiceImpl extends ServiceImpl<HomeworkMapper, BizHomework> implements IHomeworkService {

    private final HomeworkMapper homeworkMapper;

    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @Override
    public BizHomework create(CreateHomeworkDto dto, Long tenantId) {
        log.info("创建作业，名称：{}，租户：{}", dto.getName(), tenantId);

        BizHomework entity = new BizHomework();
        entity.setTenantId(tenantId);
        entity.setName(dto.getName());
        entity.setContent(dto.getContent());
        entity.setSubmitStartTime(LocalDateTime.parse(dto.getSubmitStartTime(), DATE_TIME_FORMATTER));
        entity.setSubmitEndTime(LocalDateTime.parse(dto.getSubmitEndTime(), DATE_TIME_FORMATTER));
        entity.setAttachments(dto.getAttachments());
        entity.setPublishScope(dto.getPublishScope());
        entity.setReviewRuleId(dto.getReviewRuleId());
        entity.setStatus("unpublished");

        save(entity);
        log.info("作业创建成功，ID：{}", entity.getId());
        return entity;
    }

    @Override
    public PageResult<Map<String, Object>> findAll(Long page, Long pageSize, Long tenantId, String name, String status) {
        log.info("查询作业列表，页码：{}，每页：{}", page, pageSize);

        LambdaQueryWrapper<BizHomework> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BizHomework::getValidState, 1);

        if (tenantId != null) {
            wrapper.eq(BizHomework::getTenantId, tenantId);
        }
        if (StringUtils.hasText(name)) {
            wrapper.like(BizHomework::getName, name);
        }
        if (StringUtils.hasText(status)) {
            wrapper.eq(BizHomework::getStatus, status);
        }

        wrapper.orderByDesc(BizHomework::getCreateTime);

        Page<BizHomework> pageObj = new Page<>(page, pageSize);
        Page<BizHomework> result = homeworkMapper.selectPage(pageObj, wrapper);

        List<Map<String, Object>> voList = result.getRecords().stream()
                .map(this::entityToMap)
                .collect(Collectors.toList());

        return PageResult.from(result, voList);
    }

    @Override
    public PageResult<Map<String, Object>> findMyHomeworks(Long page, Long pageSize, Long userId, Long tenantId, String name) {
        log.info("查询我的作业列表，用户：{}，租户：{}", userId, tenantId);

        LambdaQueryWrapper<BizHomework> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BizHomework::getValidState, 1);
        wrapper.eq(BizHomework::getStatus, "published");

        if (tenantId != null) {
            wrapper.eq(BizHomework::getTenantId, tenantId);
        }
        if (StringUtils.hasText(name)) {
            wrapper.like(BizHomework::getName, name);
        }

        wrapper.orderByDesc(BizHomework::getPublishTime);

        Page<BizHomework> pageObj = new Page<>(page, pageSize);
        Page<BizHomework> result = homeworkMapper.selectPage(pageObj, wrapper);

        List<Map<String, Object>> voList = result.getRecords().stream()
                .map(this::entityToMap)
                .collect(Collectors.toList());

        return PageResult.from(result, voList);
    }

    @Override
    public Map<String, Object> findDetail(Long id) {
        log.info("查询作业详情，ID：{}", id);

        BizHomework entity = getById(id);
        if (entity == null) {
            throw BusinessException.of(ErrorCode.NOT_FOUND, "作业不存在");
        }
        return entityToMap(entity);
    }

    @Override
    public BizHomework update(Long id, CreateHomeworkDto dto) {
        log.info("更新作业，ID：{}", id);

        BizHomework entity = getById(id);
        if (entity == null) {
            throw BusinessException.of(ErrorCode.NOT_FOUND, "作业不存在");
        }

        if (StringUtils.hasText(dto.getName())) {
            entity.setName(dto.getName());
        }
        if (dto.getContent() != null) {
            entity.setContent(dto.getContent());
        }
        if (StringUtils.hasText(dto.getSubmitStartTime())) {
            entity.setSubmitStartTime(LocalDateTime.parse(dto.getSubmitStartTime(), DATE_TIME_FORMATTER));
        }
        if (StringUtils.hasText(dto.getSubmitEndTime())) {
            entity.setSubmitEndTime(LocalDateTime.parse(dto.getSubmitEndTime(), DATE_TIME_FORMATTER));
        }
        if (dto.getAttachments() != null) {
            entity.setAttachments(dto.getAttachments());
        }
        if (dto.getPublishScope() != null) {
            entity.setPublishScope(dto.getPublishScope());
        }
        if (dto.getReviewRuleId() != null) {
            entity.setReviewRuleId(dto.getReviewRuleId());
        }

        updateById(entity);
        log.info("作业更新成功，ID：{}", id);
        return entity;
    }

    @Override
    public void publish(Long id, List<Integer> publishScope) {
        log.info("发布作业，ID：{}", id);

        BizHomework entity = getById(id);
        if (entity == null) {
            throw BusinessException.of(ErrorCode.NOT_FOUND, "作业不存在");
        }

        entity.setStatus("published");
        entity.setPublishTime(LocalDateTime.now());
        if (publishScope != null) {
            entity.setPublishScope(publishScope);
        }

        updateById(entity);
        log.info("作业发布成功，ID：{}", id);
    }

    @Override
    public void unpublish(Long id) {
        log.info("取消发布作业，ID：{}", id);

        BizHomework entity = getById(id);
        if (entity == null) {
            throw BusinessException.of(ErrorCode.NOT_FOUND, "作业不存在");
        }

        entity.setStatus("unpublished");
        entity.setPublishTime(null);

        updateById(entity);
        log.info("作业取消发布成功，ID：{}", id);
    }

    @Override
    public void remove(Long id) {
        log.info("删除作业，ID：{}", id);
        removeById(id);
        log.info("作业删除成功，ID：{}", id);
    }

    // ====== 私有辅助方法 ======

    private Map<String, Object> entityToMap(BizHomework entity) {
        Map<String, Object> map = new LinkedHashMap<>();
        map.put("id", entity.getId());
        map.put("tenantId", entity.getTenantId());
        map.put("name", entity.getName());
        map.put("content", entity.getContent());
        map.put("submitStartTime", entity.getSubmitStartTime());
        map.put("submitEndTime", entity.getSubmitEndTime());
        map.put("attachments", entity.getAttachments());
        map.put("publishScope", entity.getPublishScope());
        map.put("reviewRuleId", entity.getReviewRuleId());
        map.put("status", entity.getStatus());
        map.put("publishTime", entity.getPublishTime());
        map.put("createTime", entity.getCreateTime());
        map.put("modifyTime", entity.getModifyTime());
        return map;
    }
}
