package com.ruoyi.generator.service.front;

import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.generator.domain.front.FrontProject;
import com.ruoyi.generator.domain.front.FrontProjectColumn;
import com.ruoyi.generator.domain.front.FrontProjectTable;
import com.ruoyi.generator.domain.front.dto.DatabaseColumnDesign;
import com.ruoyi.generator.domain.front.dto.DatabaseDesignResponse;
import com.ruoyi.generator.domain.front.dto.DatabaseTableDesign;
import com.ruoyi.generator.domain.front.dto.FrontProjectCreateRequest;
import com.ruoyi.generator.domain.front.dto.FrontProjectUpdateRequest;
import com.ruoyi.generator.mapper.front.FrontProjectColumnMapper;
import com.ruoyi.generator.mapper.front.FrontProjectMapper;
import com.ruoyi.generator.mapper.front.FrontProjectTableMapper;

@Service
public class FrontProjectServiceImpl implements IFrontProjectService
{
    @Autowired
    private FrontProjectMapper frontProjectMapper;
    @Autowired
    private FrontProjectTableMapper frontProjectTableMapper;
    @Autowired
    private FrontProjectColumnMapper frontProjectColumnMapper;

    @Override
    public FrontProject createProject(Long userId, FrontProjectCreateRequest request)
    {
        if (userId == null || request == null || StringUtils.isEmpty(request.getProjectName()))
        {
            throw new ServiceException("项目名称不能为空");
        }
        FrontProject project = new FrontProject();
        project.setUserId(userId);
        project.setProjectName(request.getProjectName());
        project.setProjectDesc(request.getProjectDesc());
        project.setIndustryTemplate(request.getIndustryTemplate());
        project.setPackageName(StringUtils.defaultIfEmpty(request.getPackageName(), "com.easycode.generated"));
        project.setVersion(StringUtils.defaultIfEmpty(request.getVersion(), "1.0.0"));
        project.setProjectFileName(toProjectFileName(request.getProjectName()));
        project.setFrontFramework("Vue3 + Element Plus");
        project.setBackFramework("Spring Boot + MyBatis");
        project.setGenerateStatus("0");
        project.setPreviewStatus("0");
        project.setStatus("0");
        frontProjectMapper.insertFrontProject(project);
        return project;
    }

    @Override
    public List<FrontProject> listProjects(Long userId)
    {
        FrontProject query = new FrontProject();
        query.setUserId(userId);
        return frontProjectMapper.selectFrontProjectList(query);
    }

    @Override
    public FrontProject getProject(Long userId, Long projectId)
    {
        FrontProject project = frontProjectMapper.selectFrontProjectByUserAndId(userId, projectId);
        if (project == null)
        {
            throw new ServiceException("项目不存在");
        }
        return project;
    }

    @Override
    public int updateProject(Long userId, Long projectId, FrontProjectUpdateRequest request)
    {
        if (request == null)
        {
            throw new ServiceException("项目参数不能为空");
        }
        getProject(userId, projectId);
        FrontProject project = new FrontProject();
        project.setProjectId(projectId);
        project.setUserId(userId);
        project.setProjectName(request.getProjectName());
        project.setProjectDesc(request.getProjectDesc());
        project.setIndustryTemplate(request.getIndustryTemplate());
        project.setPackageName(request.getPackageName());
        project.setVersion(request.getVersion());
        return frontProjectMapper.updateFrontProject(project);
    }

    @Override
    @Transactional
    public int deleteProject(Long userId, Long projectId)
    {
        getProject(userId, projectId);
        frontProjectColumnMapper.deleteColumnsByProjectId(projectId);
        frontProjectTableMapper.deleteTablesByProjectId(projectId);
        return frontProjectMapper.deleteFrontProjectByUserAndId(userId, projectId);
    }

    @Override
    public DatabaseDesignResponse getDatabase(Long userId, Long projectId)
    {
        getProject(userId, projectId);
        DatabaseDesignResponse response = new DatabaseDesignResponse();
        response.setProjectId(projectId);
        List<DatabaseTableDesign> tables = new ArrayList<DatabaseTableDesign>();
        List<FrontProjectTable> projectTables = frontProjectTableMapper.selectTablesByProjectId(projectId);
        if (projectTables == null)
        {
            projectTables = new ArrayList<FrontProjectTable>();
        }
        for (FrontProjectTable table : projectTables)
        {
            List<FrontProjectColumn> columns = frontProjectColumnMapper.selectColumnsByTableId(table.getTableId());
            table.setColumns(columns);
            tables.add(toTableDesign(table));
        }
        response.setTables(tables);
        return response;
    }

    @Override
    @Transactional
    public DatabaseDesignResponse saveDatabase(Long userId, Long projectId, DatabaseDesignResponse request)
    {
        getProject(userId, projectId);
        frontProjectColumnMapper.deleteColumnsByProjectId(projectId);
        frontProjectTableMapper.deleteTablesByProjectId(projectId);
        if (request != null && request.getTables() != null)
        {
            for (DatabaseTableDesign tableDesign : request.getTables())
            {
                if (tableDesign == null)
                {
                    continue;
                }
                FrontProjectTable table = toFrontProjectTable(projectId, userId, tableDesign);
                frontProjectTableMapper.insertFrontProjectTable(table);
                if (tableDesign.getColumns() != null)
                {
                    for (DatabaseColumnDesign columnDesign : tableDesign.getColumns())
                    {
                        FrontProjectColumn column = toFrontProjectColumn(projectId, table.getTableId(), columnDesign);
                        frontProjectColumnMapper.insertFrontProjectColumn(column);
                    }
                }
            }
        }
        return getDatabase(userId, projectId);
    }

    private String toProjectFileName(String projectName)
    {
        return StringUtils.defaultString(projectName).trim().replaceAll("\\s+", "-").toLowerCase();
    }

    private FrontProjectTable toFrontProjectTable(Long projectId, Long userId, DatabaseTableDesign source)
    {
        FrontProjectTable table = new FrontProjectTable();
        table.setProjectId(projectId);
        table.setUserId(userId);
        table.setTableName(source.getTableName());
        table.setTableComment(source.getTableComment());
        table.setClassName(source.getClassName());
        table.setModuleName(source.getModuleName());
        table.setBusinessName(source.getBusinessName());
        table.setFunctionName(source.getFunctionName());
        table.setTplCategory(StringUtils.defaultIfEmpty(source.getTplCategory(), "crud"));
        table.setTplWebType(StringUtils.defaultIfEmpty(source.getTplWebType(), "element-plus"));
        table.setOptions(source.getOptions());
        table.setCreateTableSql(source.getCreateTableSql());
        table.setSort(source.getSort());
        table.setStatus("0");
        return table;
    }

    private FrontProjectColumn toFrontProjectColumn(Long projectId, Long tableId, DatabaseColumnDesign source)
    {
        FrontProjectColumn column = new FrontProjectColumn();
        column.setProjectId(projectId);
        column.setTableId(tableId);
        column.setColumnName(source.getColumnName());
        column.setColumnComment(source.getColumnComment());
        column.setColumnType(source.getColumnType());
        column.setJavaType(source.getJavaType());
        column.setJavaField(source.getJavaField());
        column.setIsPk(source.getIsPk());
        column.setIsIncrement(source.getIsIncrement());
        column.setIsRequired(source.getIsRequired());
        column.setIsInsert(source.getIsInsert());
        column.setIsEdit(source.getIsEdit());
        column.setIsList(source.getIsList());
        column.setIsQuery(source.getIsQuery());
        column.setQueryType(source.getQueryType());
        column.setHtmlType(source.getHtmlType());
        column.setDictType(source.getDictType());
        column.setDefaultValue(source.getDefaultValue());
        column.setSort(source.getSort());
        return column;
    }

    private DatabaseTableDesign toTableDesign(FrontProjectTable source)
    {
        DatabaseTableDesign table = new DatabaseTableDesign();
        table.setTableId(source.getTableId());
        table.setTableName(source.getTableName());
        table.setTableComment(source.getTableComment());
        table.setClassName(source.getClassName());
        table.setModuleName(source.getModuleName());
        table.setBusinessName(source.getBusinessName());
        table.setFunctionName(source.getFunctionName());
        table.setTplCategory(source.getTplCategory());
        table.setTplWebType(source.getTplWebType());
        table.setOptions(source.getOptions());
        table.setCreateTableSql(source.getCreateTableSql());
        table.setSort(source.getSort());
        List<DatabaseColumnDesign> columns = new ArrayList<DatabaseColumnDesign>();
        if (source.getColumns() != null)
        {
            for (FrontProjectColumn column : source.getColumns())
            {
                columns.add(toColumnDesign(column));
            }
        }
        table.setColumns(columns);
        return table;
    }

    private DatabaseColumnDesign toColumnDesign(FrontProjectColumn source)
    {
        DatabaseColumnDesign column = new DatabaseColumnDesign();
        column.setColumnId(source.getColumnId());
        column.setTableId(source.getTableId());
        column.setColumnName(source.getColumnName());
        column.setColumnComment(source.getColumnComment());
        column.setColumnType(source.getColumnType());
        column.setJavaType(source.getJavaType());
        column.setJavaField(source.getJavaField());
        column.setIsPk(source.getIsPk());
        column.setIsIncrement(source.getIsIncrement());
        column.setIsRequired(source.getIsRequired());
        column.setIsInsert(source.getIsInsert());
        column.setIsEdit(source.getIsEdit());
        column.setIsList(source.getIsList());
        column.setIsQuery(source.getIsQuery());
        column.setQueryType(source.getQueryType());
        column.setHtmlType(source.getHtmlType());
        column.setDictType(source.getDictType());
        column.setDefaultValue(source.getDefaultValue());
        column.setSort(source.getSort());
        return column;
    }
}
