package com.qqchen.deploy.backend.workflow.service.impl;

import com.qqchen.deploy.backend.framework.exception.BusinessException;
import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl;
import com.qqchen.deploy.backend.workflow.dto.FormDefinitionDTO;
import com.qqchen.deploy.backend.workflow.dto.query.FormDefinitionQuery;
import com.qqchen.deploy.backend.workflow.entity.FormDefinition;
import com.qqchen.deploy.backend.workflow.enums.FormDefinitionStatusEnums;
import com.qqchen.deploy.backend.workflow.repository.IFormDefinitionRepository;
import com.qqchen.deploy.backend.workflow.service.IFormDefinitionService;
import com.qqchen.deploy.backend.workflow.converter.FormDefinitionConverter;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 表单定义服务实现
 *
 * @author qqchen
 * @date 2025-10-24
 */
@Slf4j
@Service
public class FormDefinitionServiceImpl extends BaseServiceImpl<FormDefinition, FormDefinitionDTO, FormDefinitionQuery, Long> implements IFormDefinitionService {

    @Resource
    private IFormDefinitionRepository formDefinitionRepository;

    @Resource
    private FormDefinitionConverter formDefinitionConverter;

    @Override
    @Transactional
    public FormDefinitionDTO create(FormDefinitionDTO dto) {
        log.info("创建表单定义: name={}, key={}", dto.getName(), dto.getKey());

        // 1. 转换为实体
        FormDefinition formDefinition = formDefinitionConverter.toEntity(dto);

        // 2. 后端控制版本号和状态（前端传递的值会被覆盖）
        formDefinition.setFormVersion(1); // 新建表单，版本号固定为 1
        formDefinition.setStatus(FormDefinitionStatusEnums.DRAFT); // 新建表单，状态固定为草稿

        // 3. 保存
        FormDefinition savedForm = formDefinitionRepository.save(formDefinition);
        log.info("表单定义创建成功: id={}, key={}, version={}", savedForm.getId(), savedForm.getKey(), savedForm.getFormVersion());

        return formDefinitionConverter.toDto(savedForm);
    }

    @Override
    @Transactional
    public FormDefinitionDTO update(Long id, FormDefinitionDTO dto) {
        log.info("更新表单定义: id={}, name={}", id, dto.getName());

        // 1. 查询原始表单定义
        FormDefinition existingForm = formDefinitionRepository.findById(id)
                .orElseThrow(() -> new BusinessException(com.qqchen.deploy.backend.framework.enums.ResponseCode.FORM_DEFINITION_NOT_FOUND));

        // 2. 保留后端控制的字段（版本号和状态由后端控制，不允许前端修改）
        Integer originalFormVersion = existingForm.getFormVersion();
        FormDefinitionStatusEnums originalStatus = existingForm.getStatus();

        // 3. 转换并更新允许修改的字段
        FormDefinition formDefinition = formDefinitionConverter.toEntity(dto);
        formDefinition.setId(id); // 使用路径参数的ID
        formDefinition.setFormVersion(originalFormVersion); // 保留原始版本号
        formDefinition.setStatus(originalStatus); // 保留原始状态

        // 4. 保存
        FormDefinition savedForm = formDefinitionRepository.save(formDefinition);
        log.info("表单定义更新成功: id={}, version={}, status={}", savedForm.getId(), savedForm.getFormVersion(), savedForm.getStatus());

        return formDefinitionConverter.toDto(savedForm);
    }

    @Override
    @Transactional
    public FormDefinitionDTO publish(Long id) {
        log.info("发布表单定义，ID: {}", id);

        // 1. 查询当前表单定义
        FormDefinition currentForm = formDefinitionRepository.findById(id)
                .orElseThrow(() -> new BusinessException(com.qqchen.deploy.backend.framework.enums.ResponseCode.FORM_DEFINITION_NOT_FOUND));

        // 2. 检查是否已发布
        if (FormDefinitionStatusEnums.PUBLISHED.equals(currentForm.getStatus())) {
            log.info("表单已发布，创建新版本: key={}, currentVersion={}", currentForm.getKey(), currentForm.getFormVersion());

            // 创建新版本
            FormDefinition newVersion = new FormDefinition();
            newVersion.setName(currentForm.getName());
            newVersion.setKey(currentForm.getKey());
            newVersion.setFormVersion(currentForm.getFormVersion() + 1);
            newVersion.setCategoryId(currentForm.getCategoryId());
            newVersion.setDescription(currentForm.getDescription());
            newVersion.setSchema(currentForm.getSchema());
            newVersion.setTags(currentForm.getTags());
            newVersion.setStatus(FormDefinitionStatusEnums.PUBLISHED);
            newVersion.setIsTemplate(currentForm.getIsTemplate());

            FormDefinition savedNewVersion = formDefinitionRepository.save(newVersion);
            log.info("新版本创建成功: id={}, version={}", savedNewVersion.getId(), savedNewVersion.getFormVersion());

            return formDefinitionConverter.toDto(savedNewVersion);
        } else {
            // 3. 首次发布，直接更新状态
            log.info("首次发布表单: key={}, version={}", currentForm.getKey(), currentForm.getFormVersion());
            currentForm.setStatus(FormDefinitionStatusEnums.PUBLISHED);
            if (currentForm.getFormVersion() == null) {
                currentForm.setFormVersion(1);
            }

            FormDefinition savedForm = formDefinitionRepository.save(currentForm);
            log.info("表单发布成功: id={}, version={}", savedForm.getId(), savedForm.getFormVersion());

            return formDefinitionConverter.toDto(savedForm);
        }
    }

    @Override
    public FormDefinitionDTO getLatestByKey(String key) {
        log.info("根据key获取最新版本表单: key={}", key);

        FormDefinition formDefinition = formDefinitionRepository
                .findFirstByKeyAndDeletedFalseOrderByFormVersionDesc(key)
                .orElseThrow(() -> new BusinessException(com.qqchen.deploy.backend.framework.enums.ResponseCode.FORM_DEFINITION_NOT_FOUND));

        return formDefinitionConverter.toDto(formDefinition);
    }
}

