package com.reading.platform.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.reading.platform.common.enums.ErrorCode;
import com.reading.platform.common.exception.BusinessException;
import com.reading.platform.common.util.PageUtils;
import com.reading.platform.dto.request.GrowthRecordCreateRequest;
import com.reading.platform.dto.request.GrowthRecordUpdateRequest;
import com.reading.platform.entity.GrowthRecord;
import com.reading.platform.mapper.GrowthRecordMapper;
import com.reading.platform.service.GrowthRecordService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.util.List;

@Service
@RequiredArgsConstructor
public class GrowthRecordServiceImpl implements GrowthRecordService {

    private final GrowthRecordMapper growthRecordMapper;
    private final ObjectMapper objectMapper;

    @Override
    @Transactional
    public GrowthRecord createGrowthRecord(Long tenantId, Long recorderId, String recorderRole, GrowthRecordCreateRequest request) {
        GrowthRecord record = new GrowthRecord();
        record.setTenantId(tenantId);
        record.setStudentId(request.getStudentId());
        record.setType(request.getType());
        record.setTitle(request.getTitle());
        record.setContent(request.getContent());
        record.setImages(request.getImages());
        record.setRecordedBy(recorderId);
        record.setRecorderRole(recorderRole);
        record.setRecordDate(request.getRecordDate() != null ? request.getRecordDate() : LocalDate.now());

        if (request.getTags() != null && !request.getTags().isEmpty()) {
            try {
                record.setTags(objectMapper.writeValueAsString(request.getTags()));
            } catch (JsonProcessingException e) {
                record.setTags("[]");
            }
        }

        growthRecordMapper.insert(record);
        return record;
    }

    @Override
    @Transactional
    public GrowthRecord updateGrowthRecord(Long id, GrowthRecordUpdateRequest request) {
        GrowthRecord record = getGrowthRecordById(id);

        if (StringUtils.hasText(request.getType())) {
            record.setType(request.getType());
        }
        if (StringUtils.hasText(request.getTitle())) {
            record.setTitle(request.getTitle());
        }
        if (request.getContent() != null) {
            record.setContent(request.getContent());
        }
        if (request.getImages() != null) {
            record.setImages(request.getImages());
        }
        if (request.getRecordDate() != null) {
            record.setRecordDate(request.getRecordDate());
        }
        if (request.getTags() != null) {
            try {
                record.setTags(objectMapper.writeValueAsString(request.getTags()));
            } catch (JsonProcessingException e) {
                record.setTags("[]");
            }
        }

        growthRecordMapper.updateById(record);
        return record;
    }

    @Override
    public GrowthRecord getGrowthRecordById(Long id) {
        GrowthRecord record = growthRecordMapper.selectById(id);
        if (record == null) {
            throw new BusinessException(ErrorCode.DATA_NOT_FOUND, "Growth record not found");
        }
        return record;
    }

    @Override
    public Page<GrowthRecord> getGrowthRecordPage(Long tenantId, Integer pageNum, Integer pageSize, Long studentId, String type) {
        Page<GrowthRecord> page = PageUtils.of(pageNum, pageSize);
        LambdaQueryWrapper<GrowthRecord> wrapper = new LambdaQueryWrapper<>();

        wrapper.eq(GrowthRecord::getTenantId, tenantId);

        if (studentId != null) {
            wrapper.eq(GrowthRecord::getStudentId, studentId);
        }
        if (StringUtils.hasText(type)) {
            wrapper.eq(GrowthRecord::getType, type);
        }
        wrapper.orderByDesc(GrowthRecord::getRecordDate);

        return growthRecordMapper.selectPage(page, wrapper);
    }

    @Override
    public Page<GrowthRecord> getGrowthRecordsByStudentId(Long studentId, Integer pageNum, Integer pageSize, String type) {
        Page<GrowthRecord> page = PageUtils.of(pageNum, pageSize);
        LambdaQueryWrapper<GrowthRecord> wrapper = new LambdaQueryWrapper<>();

        wrapper.eq(GrowthRecord::getStudentId, studentId);

        if (StringUtils.hasText(type)) {
            wrapper.eq(GrowthRecord::getType, type);
        }
        wrapper.orderByDesc(GrowthRecord::getRecordDate);

        return growthRecordMapper.selectPage(page, wrapper);
    }

    @Override
    @Transactional
    public void deleteGrowthRecord(Long id) {
        getGrowthRecordById(id);
        growthRecordMapper.deleteById(id);
    }

    @Override
    public List<GrowthRecord> getRecentGrowthRecords(Long studentId, Integer limit) {
        int size = limit != null && limit > 0 ? limit : 10;
        return growthRecordMapper.selectList(
                new LambdaQueryWrapper<GrowthRecord>()
                        .eq(GrowthRecord::getStudentId, studentId)
                        .orderByDesc(GrowthRecord::getRecordDate)
                        .last("LIMIT " + size)
        );
    }

}
