using Indotalent.ConfigBackEnd.Exceptions;
using Indotalent.ConfigBackEnd.Extensions;
using Indotalent.Infrastructure.Database;
using MediatR;
using Microsoft.EntityFrameworkCore;

namespace Indotalent.Features.Setting.Company.Cqrs;

public class CreateCompanyRequest
{
    public string? Name { get; set; }
    public string? Description { get; set; }
    public bool IsDefault { get; set; }
    public string? CurrencyId { get; set; }
    public string? TaxIdentification { get; set; }
    public string? BusinessLicense { get; set; }
    public string? CompanyLogo { get; set; }
    public string? StreetAddress { get; set; }
    public string? City { get; set; }
    public string? StateProvince { get; set; }
    public string? ZipCode { get; set; }
    public string? Phone { get; set; }
    public string? Email { get; set; }
    public string? SocialMediaLinkedIn { get; set; }
    public string? SocialMediaX { get; set; }
    public string? SocialMediaFacebook { get; set; }
    public string? SocialMediaInstagram { get; set; }
    public string? SocialMediaTikTok { get; set; }
    public string? OtherInformation1 { get; set; }
    public string? OtherInformation2 { get; set; }
    public string? OtherInformation3 { get; set; }
}

public class CreateCompanyResponse
{
    public string? Id { get; set; }
    public string? Name { get; set; }
}

public record CreateCompanyCommand(CreateCompanyRequest Data) : IRequest<CreateCompanyResponse>;

public class CreateCompanyHandler : IRequestHandler<CreateCompanyCommand, CreateCompanyResponse>
{
    private readonly AppDbContext _context;

    public CreateCompanyHandler(AppDbContext context) => _context = context;

    public async Task<CreateCompanyResponse> Handle(CreateCompanyCommand request, CancellationToken cancellationToken)
    {
        var isExists = await _context.Company
            .AnyAsync(x => x.Name == request.Data.Name, cancellationToken);

        if (isExists)
        {
            throw new AlreadyExistsException("Company", request.Data.Name ?? string.Empty);
        }

        if (request.Data.IsDefault)
        {
            var existingDefaults = await _context.Company
                .Where(x => x.IsDefault)
                .ToListAsync(cancellationToken);

            foreach (var comp in existingDefaults)
            {
                comp.IsDefault = false;
            }
        }

        var entityName = nameof(Data.Entities.Company);
        var autoNo = await _context.GenerateAutoNumberAsync(
            entityName: entityName,
            prefixTemplate: $"{entityName.ToShortNameConsonant(3)}/{{Year}}/",
            ct: cancellationToken
        );

        var entity = new Data.Entities.Company
        {
            AutoNumber = autoNo,
            Name = request.Data.Name ?? string.Empty,
            Description = request.Data.Description ?? string.Empty,
            IsDefault = request.Data.IsDefault,
            CurrencyId = request.Data.CurrencyId ?? string.Empty,
            TaxIdentification = request.Data.TaxIdentification ?? string.Empty,
            BusinessLicense = request.Data.BusinessLicense ?? string.Empty,
            StreetAddress = request.Data.StreetAddress ?? string.Empty,
            City = request.Data.City ?? string.Empty,
            StateProvince = request.Data.StateProvince ?? string.Empty,
            ZipCode = request.Data.ZipCode ?? string.Empty,
            Phone = request.Data.Phone ?? string.Empty,
            Email = request.Data.Email ?? string.Empty,
            SocialMediaLinkedIn = request.Data.SocialMediaLinkedIn ?? string.Empty,
            SocialMediaX = request.Data.SocialMediaX ?? string.Empty,
            SocialMediaFacebook = request.Data.SocialMediaFacebook ?? string.Empty,
            SocialMediaInstagram = request.Data.SocialMediaInstagram ?? string.Empty,
            SocialMediaTikTok = request.Data.SocialMediaTikTok ?? string.Empty,
            OtherInformation1 = request.Data.OtherInformation1 ?? string.Empty,
            OtherInformation2 = request.Data.OtherInformation2 ?? string.Empty,
            OtherInformation3 = request.Data.OtherInformation3 ?? string.Empty
        };

        _context.Company.Add(entity);
        await _context.SaveChangesAsync(cancellationToken);

        return new CreateCompanyResponse { Id = entity.Id, Name = entity.Name };
    }
}