package com.agileboot.codegen.service.impl;

import com.agileboot.codegen.dto.UserTemplateDTO;
import com.agileboot.codegen.entity.UserTemplate;
import com.agileboot.codegen.mapper.UserTemplateMapper;
import com.agileboot.codegen.service.IUserTemplateService;
import com.agileboot.codegen.vo.UserTemplateVO;
import cn.hutool.core.bean.BeanUtil;
import com.agileboot.common.satoken.utils.LoginHelper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import java.util.Arrays;
import com.agileboot.codegen.mapper.UserTemplateRepositoryMapper;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.StringReader;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户模板 Service实现类
 *
 * @author system
 * @date 2025-09-26
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserTemplateServiceImpl implements IUserTemplateService {

    private final UserTemplateMapper userTemplateMapper;
    private final UserTemplateRepositoryMapper repositoryMapper;

    @Override
    public Page<UserTemplateVO> selectUserTemplateList(Page<UserTemplate> page, Long userId, String templateGroup, Integer isPublic) {
        LambdaQueryWrapper<UserTemplate> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(userId != null, UserTemplate::getUserId, userId)
               .eq(StringUtils.isNotBlank(templateGroup), UserTemplate::getTemplateGroup, templateGroup)
               .eq(isPublic != null, UserTemplate::getIsPublic, isPublic)
               .orderByDesc(UserTemplate::getCreateTime);

        Page<UserTemplate> templatePage = userTemplateMapper.selectPage(page, wrapper);

        // 转换为VO
        Page<UserTemplateVO> voPage = new Page<>(templatePage.getCurrent(), templatePage.getSize(), templatePage.getTotal());
        List<UserTemplateVO> voList = templatePage.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
        voPage.setRecords(voList);

        return voPage;
    }

    @Override
    public List<UserTemplateVO> selectPublicTemplates(String templateGroup, Long currentUserId) {
        List<UserTemplate> templates = userTemplateMapper.selectPublicTemplates(templateGroup);
        return templates.stream()
                .map(template -> {
                    UserTemplateVO vo = convertToVO(template);
                    vo.setIsOwner(currentUserId != null && currentUserId.equals(template.getUserId()));
                    return vo;
                })
                .collect(Collectors.toList());
    }

    @Override
    public UserTemplateVO selectUserTemplateById(Long id) {
        UserTemplate template = userTemplateMapper.selectById(id);
        return template != null ? convertToVO(template) : null;
    }

    @Override
    @Transactional
    public boolean insertUserTemplate(UserTemplateDTO dto) {
        Long currentUserId = LoginHelper.getUserId();

        // 检查模板名称是否存在
        if (checkTemplateNameExists(currentUserId, dto.getTemplateName(), null)) {
            throw new RuntimeException("模板名称已存在");
        }

        UserTemplate template = new UserTemplate();
        BeanUtil.copyProperties(dto, template);
        template.setUserId(currentUserId);
        template.setUseCount(0);
        template.setStatus(dto.getStatus() != null ? dto.getStatus() : 1);
        template.setVersion(StringUtils.isNotBlank(dto.getVersion()) ? dto.getVersion() : "1.0.0");
        template.setIsEnabled(dto.getIsEnabled() != null ? dto.getIsEnabled() : 1); // 默认显示
        template.setIsContentPublic(dto.getIsContentPublic() != null ? dto.getIsContentPublic() : 0); // 默认不公开内容

        return userTemplateMapper.insert(template) > 0;
    }

    @Override
    @Transactional
    public boolean updateUserTemplate(UserTemplateDTO dto) {
        if (dto.getId() == null) {
            throw new RuntimeException("模板ID不能为空");
        }

        UserTemplate existTemplate = userTemplateMapper.selectById(dto.getId());
        if (existTemplate == null) {
            throw new RuntimeException("模板不存在");
        }

        Long currentUserId = LoginHelper.getUserId();
        // 只能修改自己的模板
        if (!currentUserId.equals(existTemplate.getUserId())) {
            throw new RuntimeException("无权限修改此模板");
        }

        // 检查模板名称是否存在（只在名称发生变化时才检查）
        if (!existTemplate.getTemplateName().equals(dto.getTemplateName()) &&
            checkTemplateNameExists(currentUserId, dto.getTemplateName(), dto.getId())) {
            throw new RuntimeException("模板名称已存在");
        }

        UserTemplate template = new UserTemplate();
        BeanUtil.copyProperties(dto, template);
        template.setUserId(currentUserId);

        return userTemplateMapper.updateById(template) > 0;
    }

    @Override
    @Transactional
    public boolean deleteUserTemplateById(Long id) {
        if (id == null) {
            throw new RuntimeException("模板ID不能为空");
        }

        UserTemplate template = userTemplateMapper.selectById(id);
        if (template == null) {
            throw new RuntimeException("模板不存在或已被删除");
        }

        Long currentUserId = LoginHelper.getUserId();
        // 只能删除自己的模板
        if (!currentUserId.equals(template.getUserId())) {
            throw new RuntimeException("无权限删除此模板");
        }

        int result = userTemplateMapper.deleteById(id);
        if (result <= 0) {
            throw new RuntimeException("删除操作失败");
        }

        // 清理模板仓库中的相关记录
        repositoryMapper.deleteByTemplate(currentUserId, "user", id.toString());

        return true;
    }

    @Override
    @Transactional
    public boolean deleteUserTemplateByIds(Long[] ids) {
        if (ids == null || ids.length == 0) {
            return false;
        }

        Long currentUserId = LoginHelper.getUserId();

        // 检查所有模板是否属于当前用户
        for (Long id : ids) {
            UserTemplate template = userTemplateMapper.selectById(id);
            if (template == null || !currentUserId.equals(template.getUserId())) {
                throw new RuntimeException("无权限删除模板ID: " + id);
            }
        }

        boolean deleteResult = userTemplateMapper.deleteByIds(Arrays.asList(ids)) > 0;
        
        // 清理模板仓库中的相关记录
        for (Long id : ids) {
            repositoryMapper.deleteByTemplate(currentUserId, "user", id.toString());
        }
        
        return deleteResult;
    }

    @Override
    @Transactional
    public boolean copyTemplate(Long templateId, String newName) {
        UserTemplate sourceTemplate = userTemplateMapper.selectById(templateId);
        if (sourceTemplate == null) {
            throw new RuntimeException("源模板不存在");
        }

        Long currentUserId = LoginHelper.getUserId();

        // 权限检查：只能复制自己的模板或公开模板
        if (sourceTemplate.getIsPublic() != 1 && !currentUserId.equals(sourceTemplate.getUserId())) {
            throw new RuntimeException("无权限复制此模板");
        }

        // 检查新模板名称是否存在
        if (checkTemplateNameExists(currentUserId, newName, null)) {
            throw new RuntimeException("模板名称已存在");
        }

        UserTemplate newTemplate = new UserTemplate();
        BeanUtil.copyProperties(sourceTemplate, newTemplate);
        newTemplate.setId(null);
        newTemplate.setUserId(currentUserId);
        newTemplate.setTemplateName(newName);
        newTemplate.setIsPublic(0); // 复制的模板默认为私有
        newTemplate.setUseCount(0);
        // 清除时间字段，让自动填充功能设置当前时间
        newTemplate.setCreateTime(null);
        newTemplate.setUpdateTime(null);
        newTemplate.setCreateBy(null);
        newTemplate.setUpdateBy(null);

        return userTemplateMapper.insert(newTemplate) > 0;
    }

    @Override
    public String validateTemplate(String templateContent) {
        try {
            Configuration cfg = new Configuration(Configuration.VERSION_2_3_31);
            cfg.setDefaultEncoding("UTF-8");

            // 创建模板对象
            Template template = new Template("validate", new StringReader(templateContent), cfg);

            // 使用测试数据验证模板
            StringWriter writer = new StringWriter();
            HashMap<String, Object> testData = new HashMap<>();
            testData.put("className", "TestClass");
            testData.put("tableName", "test_table");

            template.process(testData, writer);

            return "模板语法验证通过";
        } catch (Exception e) {
            return "模板语法错误: " + e.getMessage();
        }
    }

    @Override
    public boolean checkTemplateNameExists(Long userId, String templateName, Long excludeId) {
        return userTemplateMapper.checkTemplateNameExists(userId, templateName, excludeId) > 0;
    }

    @Override
    @Transactional
    public void increaseUseCount(Long id) {
        userTemplateMapper.increaseUseCount(id);
    }

    @Override
    @Transactional
    public boolean toggleTemplateVisibility(Long id, Integer isEnabled) {
        UserTemplate template = userTemplateMapper.selectById(id);
        if (template == null) {
            throw new RuntimeException("模板不存在");
        }
        Long currentUserId = LoginHelper.getUserId();
        // 只能修改自己的模板
        if (!currentUserId.equals(template.getUserId())) {
            throw new RuntimeException("无权限修改此模板");
        }

        // 更新模板的显示状态
        template.setIsEnabled(isEnabled);
        boolean updateResult = userTemplateMapper.updateById(template) > 0;

        // 如果是公开模板，同时更新模板仓库中的状态（如果存在的话）
        if (template.getIsPublic() == 1) {
            try {
                repositoryMapper.toggleTemplateStatus(currentUserId, "user", id.toString(), isEnabled);
            } catch (Exception e) {
                // 如果模板仓库中不存在该记录，忽略错误
                log.debug("更新模板仓库状态时出错，可能记录不存在: {}", e.getMessage());
            }
        }

        return updateResult;
    }

    @Override
    public String getTemplateContent(Long id) {
        UserTemplate template = userTemplateMapper.selectById(id);
        if (template == null) {
            throw new RuntimeException("模板不存在或已被删除");
        }

        Long currentUserId = LoginHelper.getUserId();
        
        // 权限检查：只能查看自己的模板或内容公开的模板
        if (!currentUserId.equals(template.getUserId())) {
            // 检查内容是否公开，如果字段不存在则默认为不公开
            Integer isContentPublic = template.getIsContentPublic();
            if (isContentPublic == null || isContentPublic != 1) {
                return "// 模板内容未公开，无法预览";
            }
        }

        return template.getTemplateContent();
    }

    /**
     * 转换实体为VO
     */
    private UserTemplateVO convertToVO(UserTemplate template) {
        UserTemplateVO vo = new UserTemplateVO();
        BeanUtil.copyProperties(template, vo);

        // 设置文本描述
        vo.setIsPublicText(template.getIsPublic() == 1 ? "公开" : "私有");

        String statusText;
        switch (template.getStatus()) {
            case 0:
                statusText = "草稿";
                break;
            case 1:
                statusText = "发布";
                break;
            case 2:
                statusText = "禁用";
                break;
            default:
                statusText = "未知";
        }
        vo.setStatusText(statusText);

        // 判断是否为当前用户创建
        Long currentUserId = LoginHelper.getUserId();
        vo.setIsOwner(currentUserId != null && currentUserId.equals(template.getUserId()));

        return vo;
    }
}

