package com.lesingle.edu.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.lesingle.edu.common.enums.ErrorCode;
import com.lesingle.edu.common.exception.BusinessException;
import com.lesingle.edu.dto.request.GrowthRecordCreateRequest;
import com.lesingle.edu.dto.request.GrowthRecordUpdateRequest;
import com.lesingle.edu.entity.GrowthRecord;
import com.lesingle.edu.mapper.GrowthRecordMapper;
import com.lesingle.edu.service.GrowthRecordService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

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

@Slf4j
@Service
@RequiredArgsConstructor
public class GrowthRecordServiceImpl extends ServiceImpl<GrowthRecordMapper, GrowthRecord>
    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());
        if (request.getImages() != null) {
            try {
                record.setImages(objectMapper.writeValueAsString(request.getImages()));
            } catch (JsonProcessingException e) {
                record.setImages("[]");
            }
        }
        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);
        log.info("成长记录创建成功：id={}, studentId={}, title={}", record.getId(), record.getStudentId(), record.getTitle());
        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) {
            try {
                record.setImages(objectMapper.writeValueAsString(request.getImages()));
            } catch (JsonProcessingException e) {
                record.setImages("[]");
            }
        }
        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);
        log.info("成长记录更新成功：id={}", id);
        return record;
    }

    @Override
    public GrowthRecord getGrowthRecordById(Long id) {
        GrowthRecord record = growthRecordMapper.selectById(id);
        if (record == null) {
            throw new BusinessException(ErrorCode.DATA_NOT_FOUND, "成长记录不存在");
        }
        return record;
    }

    @Override
    public GrowthRecord getGrowthRecordByIdWithTenantCheck(Long id, Long tenantId) {
        GrowthRecord record = getGrowthRecordById(id);
        if (!record.getTenantId().equals(tenantId)) {
            throw new BusinessException(ErrorCode.FORBIDDEN, "无权访问该成长记录");
        }
        return record;
    }

    @Override
    public GrowthRecord updateGrowthRecordWithTenantCheck(Long id, Long tenantId, GrowthRecordUpdateRequest request) {
        getGrowthRecordByIdWithTenantCheck(id, tenantId);
        return updateGrowthRecord(id, request);
    }

    @Override
    public Page<GrowthRecord> getGrowthRecordPage(Long tenantId, Integer pageNum, Integer pageSize, Long studentId, String type) {
        Page<GrowthRecord> page = new Page<>(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::getUpdatedAt).orderByDesc(GrowthRecord::getCreatedAt);

        return growthRecordMapper.selectPage(page, wrapper);
    }

    @Override
    public Page<GrowthRecord> getGrowthRecordsByStudentId(Long studentId, Integer pageNum, Integer pageSize, String type) {
        Page<GrowthRecord> page = new Page<>(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);
        log.info("成长记录删除成功：id={}", id);
    }

    @Override
    @Transactional
    public void deleteGrowthRecordWithTenantCheck(Long id, Long tenantId) {
        getGrowthRecordByIdWithTenantCheck(id, tenantId);
        deleteGrowthRecord(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)
        );
    }

}
