package com.ga.api.service.upload;

import com.ga.common.exception.BizException;
import com.ga.common.exception.ErrorCode;
import com.ga.common.model.PageResponse;
import com.ga.common.util.SecurityUtil;
import com.ga.core.mapper.upload.UploadColumnMapper;
import com.ga.core.mapper.upload.UploadHistoryMapper;
import com.ga.core.mapper.upload.UploadTemplateMapper;
import com.ga.core.vo.upload.*;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@RequiredArgsConstructor
public class UploadTemplateService {

    private final UploadTemplateMapper templateMapper;
    private final UploadColumnMapper columnMapper;
    private final UploadHistoryMapper historyMapper;

    @Transactional(readOnly = true)
    public PageResponse<UploadTemplateResp> list(UploadTemplateSearchParam param) {
        param.startPage();
        return PageResponse.of(templateMapper.selectList(param));
    }

    @Transactional(readOnly = true)
    public UploadTemplateResp detail(Long templateId) {
        UploadTemplateResp resp = templateMapper.selectById(templateId);
        if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
        resp.setColumns(columnMapper.selectByTemplateId(templateId));
        return resp;
    }

    @Transactional
    public Long create(UploadTemplateSaveReq req) {
        if (templateMapper.existsByCode(req.getTemplateCode()) > 0) {
            throw new BizException(ErrorCode.DUPLICATE_DATA, "이미 존재하는 템플릿 코드입니다: " + req.getTemplateCode());
        }
        UploadTemplateVO vo = req.toVO();
        vo.setCreatedBy(SecurityUtil.getCurrentUserId());
        templateMapper.insert(vo);
        if (req.getColumns() != null && !req.getColumns().isEmpty()) {
            columnMapper.insertBatch(vo.getTemplateId(), req.getColumns());
        }
        return vo.getTemplateId();
    }

    @Transactional
    public void update(Long templateId, UploadTemplateSaveReq req) {
        if (templateMapper.selectById(templateId) == null) {
            throw new BizException(ErrorCode.NOT_FOUND);
        }
        UploadTemplateVO vo = req.toVO();
        vo.setTemplateId(templateId);
        vo.setUpdatedBy(SecurityUtil.getCurrentUserId());
        templateMapper.update(vo);
        if (req.getColumns() != null) {
            columnMapper.deleteByTemplateId(templateId);
            if (!req.getColumns().isEmpty()) {
                columnMapper.insertBatch(templateId, req.getColumns());
            }
        }
    }

    @Transactional
    public void delete(Long templateId) {
        if (templateMapper.selectById(templateId) == null) {
            throw new BizException(ErrorCode.NOT_FOUND);
        }
        columnMapper.deleteByTemplateId(templateId);
        templateMapper.delete(templateId);
    }

    @Transactional(readOnly = true)
    public List<UploadTemplateColumnVO> columns(Long templateId) {
        return columnMapper.selectByTemplateId(templateId);
    }

    @Transactional
    public void updateColumns(Long templateId, List<UploadTemplateColumnVO> columns) {
        if (templateMapper.selectById(templateId) == null) {
            throw new BizException(ErrorCode.NOT_FOUND);
        }
        columnMapper.deleteByTemplateId(templateId);
        if (columns != null && !columns.isEmpty()) {
            columnMapper.insertBatch(templateId, columns);
        }
    }

    @Transactional(readOnly = true)
    public PageResponse<UploadHistoryResp> history(Long templateId, UploadTemplateSearchParam param) {
        param.startPage();
        return PageResponse.of(historyMapper.selectByTemplate(templateId, param));
    }
}
