using System.Data;
using Microsoft.EntityFrameworkCore;
using SolutionErp.Application.Common.Interfaces;
using SolutionErp.Application.ContractSigningPlans.Services;
using SolutionErp.Domain.Office;

namespace SolutionErp.Infrastructure.Services;

// [W1 Mig 69 — S161 2026-07-29] Mã phiếu KHKK — format KHKK/{YYYY}/{Seq:D3} (anh OK @S161).
// Mirror PurchaseEvaluationCodeGenerator (SERIALIZABLE + LastSeq += 1), khác 1 điểm:
// sequence sống trong bảng WorkflowAppCodeSequences DÙNG CHUNG 4 module Office
// (per-prefix row "KHKK/{YYYY}" — KHÔNG bảng sequence riêng, spec W1 §②-9).
public class ContractSigningPlanCodeGenerator(IApplicationDbContext db, IDateTime dateTime)
    : IContractSigningPlanCodeGenerator
{
    public async Task<string> GenerateAsync(CancellationToken ct = default)
    {
        var year = dateTime.UtcNow.Year;
        var prefix = $"KHKK/{year}";

        // Transaction SERIALIZABLE chống race 2 người Submit cùng lúc (mirror PE codegen).
        var context = (DbContext)db;
        await using var tx = await context.Database
            .BeginTransactionAsync(IsolationLevel.Serializable, ct);
        try
        {
            var seq = await db.WorkflowAppCodeSequences
                .FirstOrDefaultAsync(s => s.Prefix == prefix, ct);
            if (seq is null)
            {
                seq = new WorkflowAppCodeSequence
                {
                    Prefix = prefix, LastSeq = 1, UpdatedAt = dateTime.UtcNow,
                };
                db.WorkflowAppCodeSequences.Add(seq);
            }
            else
            {
                seq.LastSeq += 1;
                seq.UpdatedAt = dateTime.UtcNow;
            }
            await db.SaveChangesAsync(ct);
            await tx.CommitAsync(ct);
            return $"{prefix}/{seq.LastSeq:D3}";
        }
        catch
        {
            await tx.RollbackAsync(ct);
            throw;
        }
    }
}
