package cn.nianxx.thhotel.workflows.reservation.repository;

import cn.nianxx.thhotel.workflows.reservation.common.dto.ReservationInvoiceGenerationDraft;
import cn.nianxx.thhotel.workflows.reservation.common.enums.ReservationInvoiceGenerationStatus;
import cn.nianxx.thhotel.workflows.reservation.domain.ReservationInvoiceGenerationEntity;
import cn.nianxx.thhotel.workflows.reservation.mapper.ReservationInvoiceGenerationMapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import java.time.LocalDateTime;
import org.springframework.stereotype.Repository;

/**
 * Reservation Invoice 生成记录 MyBatis 持久化实现。
 */
@Repository
public class MybatisReservationInvoiceGenerationRepository implements ReservationInvoiceGenerationRepository {

    private final ReservationInvoiceGenerationMapper mapper;

    /**
     * 注入生成记录 Mapper。
     */
    public MybatisReservationInvoiceGenerationRepository(ReservationInvoiceGenerationMapper mapper) {
        this.mapper = mapper;
    }

    /**
     * 新增生成记录，初始状态由调用方决定，便于后续支持异步 outbox。
     */
    @Override
    public Long insertGeneration(ReservationInvoiceGenerationDraft draft) {
        ReservationInvoiceGenerationEntity entity = new ReservationInvoiceGenerationEntity();
        entity.setHotelId(draft.hotelId());
        entity.setSourceType(draft.sourceType());
        entity.setOrderId(draft.orderId());
        entity.setTaskId(draft.taskId());
        entity.setSourceMessageId(draft.sourceMessageId());
        entity.setTemplateCode(draft.templateCode());
        entity.setTemplateVersion(draft.templateVersion());
        entity.setInvoicePayloadJson(draft.invoicePayloadJson());
        entity.setGenerationStatus(draft.generationStatus());
        entity.setCreatedBy(draft.createdBy());
        entity.setCreatedAt(draft.now());
        entity.setUpdatedAt(draft.now());
        mapper.insert(entity);
        return entity.getId();
    }

    /**
     * 将生成记录标记为成功，并保存生成物 OSS 定位信息。
     */
    @Override
    public void markSucceeded(
            Long generationId,
            String calculatedTotalsJson,
            String generatedExcelObjectKey,
            String pdfObjectKey,
            String pdfUrl,
            LocalDateTime now) {
        mapper.update(null, Wrappers.<ReservationInvoiceGenerationEntity>lambdaUpdate()
                .set(ReservationInvoiceGenerationEntity::getCalculatedTotalsJson, calculatedTotalsJson)
                .set(ReservationInvoiceGenerationEntity::getGeneratedExcelObjectKey, generatedExcelObjectKey)
                .set(ReservationInvoiceGenerationEntity::getPdfObjectKey, pdfObjectKey)
                .set(ReservationInvoiceGenerationEntity::getPdfUrl, pdfUrl)
                .set(ReservationInvoiceGenerationEntity::getGenerationStatus,
                        ReservationInvoiceGenerationStatus.SUCCEEDED.name())
                .set(ReservationInvoiceGenerationEntity::getSafeErrorCode, null)
                .set(ReservationInvoiceGenerationEntity::getSafeErrorSummary, null)
                .set(ReservationInvoiceGenerationEntity::getUpdatedAt, now)
                .eq(ReservationInvoiceGenerationEntity::getId, generationId));
    }

    /**
     * 记录 Excel 生成物对象路径，不改变当前生成状态。
     */
    @Override
    public void recordGeneratedExcel(Long generationId, String generatedExcelObjectKey, LocalDateTime now) {
        mapper.update(null, Wrappers.<ReservationInvoiceGenerationEntity>lambdaUpdate()
                .set(ReservationInvoiceGenerationEntity::getGeneratedExcelObjectKey, generatedExcelObjectKey)
                .set(ReservationInvoiceGenerationEntity::getUpdatedAt, now)
                .eq(ReservationInvoiceGenerationEntity::getId, generationId));
    }

    /**
     * 记录 PDF 生成物对象路径，不改变当前生成状态。
     */
    @Override
    public void recordGeneratedPdf(Long generationId, String pdfObjectKey, String pdfUrl, LocalDateTime now) {
        mapper.update(null, Wrappers.<ReservationInvoiceGenerationEntity>lambdaUpdate()
                .set(ReservationInvoiceGenerationEntity::getPdfObjectKey, pdfObjectKey)
                .set(ReservationInvoiceGenerationEntity::getPdfUrl, pdfUrl)
                .set(ReservationInvoiceGenerationEntity::getUpdatedAt, now)
                .eq(ReservationInvoiceGenerationEntity::getId, generationId));
    }

    /**
     * 将生成记录标记为失败，不保存原始异常堆栈或用户输入明细。
     */
    @Override
    public void markFailed(Long generationId, String safeErrorCode, String safeErrorSummary, LocalDateTime now) {
        mapper.update(null, Wrappers.<ReservationInvoiceGenerationEntity>lambdaUpdate()
                .set(ReservationInvoiceGenerationEntity::getGenerationStatus,
                        ReservationInvoiceGenerationStatus.FAILED.name())
                .set(ReservationInvoiceGenerationEntity::getSafeErrorCode, safeErrorCode)
                .set(ReservationInvoiceGenerationEntity::getSafeErrorSummary, safeErrorSummary)
                .set(ReservationInvoiceGenerationEntity::getUpdatedAt, now)
                .eq(ReservationInvoiceGenerationEntity::getId, generationId));
    }
}
