using FluentValidation;
using MediatR;
using Microsoft.EntityFrameworkCore;
using SolutionErp.Application.Common.Exceptions;
using SolutionErp.Application.Common.Interfaces;
using SolutionErp.Domain.Master;

namespace SolutionErp.Application.Master.Suppliers.Commands.CreateSupplier;

public record CreateSupplierCommand(
    string Code,
    string Name,
    SupplierType Type,
    string? TaxCode,
    string? Phone,
    string? Email,
    string? Address,
    string? ContactPerson,
    string? Note) : IRequest<Guid>;

public class CreateSupplierCommandValidator : AbstractValidator<CreateSupplierCommand>
{
    public CreateSupplierCommandValidator()
    {
        RuleFor(x => x.Code).NotEmpty().MaximumLength(50);
        RuleFor(x => x.Name).NotEmpty().MaximumLength(200);
        RuleFor(x => x.Type).IsInEnum();
        RuleFor(x => x.TaxCode).MaximumLength(20);
        RuleFor(x => x.Phone).MaximumLength(30);
        RuleFor(x => x.Email).MaximumLength(100).EmailAddress().When(x => !string.IsNullOrWhiteSpace(x.Email));
        RuleFor(x => x.Address).MaximumLength(500);
        RuleFor(x => x.ContactPerson).MaximumLength(200);
        RuleFor(x => x.Note).MaximumLength(1000);
    }
}

public class CreateSupplierCommandHandler : IRequestHandler<CreateSupplierCommand, Guid>
{
    private readonly IApplicationDbContext _db;

    public CreateSupplierCommandHandler(IApplicationDbContext db) => _db = db;

    public async Task<Guid> Handle(CreateSupplierCommand request, CancellationToken ct)
    {
        if (await _db.Suppliers.AnyAsync(x => x.Code == request.Code, ct))
            throw new ConflictException($"Mã NCC '{request.Code}' đã tồn tại.");

        var entity = new Supplier
        {
            Code = request.Code,
            Name = request.Name,
            Type = request.Type,
            TaxCode = request.TaxCode,
            Phone = request.Phone,
            Email = request.Email,
            Address = request.Address,
            ContactPerson = request.ContactPerson,
            Note = request.Note,
        };
        _db.Suppliers.Add(entity);
        await _db.SaveChangesAsync(ct);
        return entity.Id;
    }
}
