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,
    // S? go-live expansion — 18 field bổ sung, tất cả TRAILING OPTIONAL (= null)
    // để payload tối thiểu cũ + call-site positional 9-arg vẫn hợp lệ (mọi field optional).
    string? PackageCategory = null,
    string? OfficeAddress = null,
    string? MailingAddress = null,
    string? Fax = null,
    string? BankAccount = null,
    string? SecondaryBankAccount = null,
    string? LegalRepresentative = null,
    string? LegalRepTitle = null,
    string? AuthorizationNote = null,
    string? LinkGuq = null,
    string? LinkGpkd = null,
    string? LinkHsnl = null,
    string? ContactTitle = null,
    string? ContactPhone = null,
    string? MailRecipient = null,
    string? ReferralSource = null,
    string? OwnerPmh = null,
    SupplierStatus? Status = null) : 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);
        // S? — new fields OPTIONAL: MaximumLength ONLY, KHÔNG NotEmpty (Create open-auth, minimal payload phải hợp lệ).
        RuleFor(x => x.PackageCategory).MaximumLength(300);
        RuleFor(x => x.OfficeAddress).MaximumLength(500);
        RuleFor(x => x.MailingAddress).MaximumLength(500);
        RuleFor(x => x.Fax).MaximumLength(50);
        RuleFor(x => x.BankAccount).MaximumLength(500);
        RuleFor(x => x.SecondaryBankAccount).MaximumLength(500);
        RuleFor(x => x.LegalRepresentative).MaximumLength(200);
        RuleFor(x => x.LegalRepTitle).MaximumLength(150);
        RuleFor(x => x.AuthorizationNote).MaximumLength(1000);
        RuleFor(x => x.LinkGuq).MaximumLength(1000);
        RuleFor(x => x.LinkGpkd).MaximumLength(1000);
        RuleFor(x => x.LinkHsnl).MaximumLength(1000);
        RuleFor(x => x.ContactTitle).MaximumLength(150);
        RuleFor(x => x.ContactPhone).MaximumLength(50);
        RuleFor(x => x.MailRecipient).MaximumLength(200);
        RuleFor(x => x.ReferralSource).MaximumLength(300);
        RuleFor(x => x.OwnerPmh).MaximumLength(150);
    }
}

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,
            PackageCategory = request.PackageCategory,
            OfficeAddress = request.OfficeAddress,
            MailingAddress = request.MailingAddress,
            Fax = request.Fax,
            BankAccount = request.BankAccount,
            SecondaryBankAccount = request.SecondaryBankAccount,
            LegalRepresentative = request.LegalRepresentative,
            LegalRepTitle = request.LegalRepTitle,
            AuthorizationNote = request.AuthorizationNote,
            LinkGuq = request.LinkGuq,
            LinkGpkd = request.LinkGpkd,
            LinkHsnl = request.LinkHsnl,
            ContactTitle = request.ContactTitle,
            ContactPhone = request.ContactPhone,
            MailRecipient = request.MailRecipient,
            ReferralSource = request.ReferralSource,
            OwnerPmh = request.OwnerPmh,
            Status = request.Status,
            IsPublic = true, // S113: "Thêm NCC" tay luôn có Code (validator NotEmpty) → công bố ngay (R7 badge đúng + hiện trong picker); CHỈ import mới landing nháp
        };
        _db.Suppliers.Add(entity);
        await _db.SaveChangesAsync(ct);
        return entity.Id;
    }
}
