using System;

namespace GestionaDenuncias.Shared.Models;

public sealed class ThirdPartyIdentityData
{
    public bool IsAnonymous { get; set; }
    public bool IsLegalEntity { get; set; }
    public string DocumentId { get; set; } = string.Empty;
    public string FirstName { get; set; } = string.Empty;
    public string LastName { get; set; } = string.Empty;
    public string BusinessName { get; set; } = string.Empty;
    public string Email { get; set; } = string.Empty;
    public string CountryCode { get; set; } = string.Empty;
    public string NotificationPreference { get; set; } = string.Empty;
    public string ElectronicNotification { get; set; } = string.Empty;
    public string PostalNotificationPreference { get; set; } = string.Empty;
    public ThirdPartyAddressData? Address { get; set; }

    public string DisplayName =>
        IsLegalEntity
            ? BusinessName
            : string.Join(
                ' ',
                new[] { FirstName, LastName }
                    .Where(value => !string.IsNullOrWhiteSpace(value)));

    public static ThirdPartyIdentityData FromComplaint(DenunciasGestiona denuncia)
    {
        ArgumentNullException.ThrowIfNull(denuncia);

        var documentId = (denuncia.DocumentoResuelto ?? string.Empty).Trim().ToUpperInvariant();
        var firstName = denuncia.NombreResuelto.Trim();
        var lastName = BuildLastName(denuncia);
        var businessName = denuncia.RazonSocialResuelta.Trim();
        var isAnonymous = denuncia.EsAnonima ||
                          string.Equals(
                              documentId,
                              "00000000T",
                              StringComparison.OrdinalIgnoreCase);
        var isLegalEntity = !isAnonymous &&
                            (denuncia.EsPersonaJuridica ||
                             LooksLikeLegalEntityDocument(documentId) ||
                             (!string.IsNullOrWhiteSpace(businessName) &&
                              string.IsNullOrWhiteSpace(firstName)));

        return new ThirdPartyIdentityData
        {
            IsAnonymous = isAnonymous,
            IsLegalEntity = isLegalEntity,
            DocumentId = isAnonymous
                ? "00000000T"
                : documentId,
            FirstName = isAnonymous ? "Anonimo" : isLegalEntity ? string.Empty : firstName,
            LastName = isAnonymous ? "-" : isLegalEntity ? string.Empty : lastName,
            BusinessName = isAnonymous ? string.Empty : businessName,
            Email = (denuncia.Correo_Electronico ?? string.Empty).Trim(),
            CountryCode = string.IsNullOrWhiteSpace(denuncia.Pais) ? denuncia.PaisOrigen : denuncia.Pais,
            NotificationPreference = denuncia.Notificacion_Preferencia ?? string.Empty,
            ElectronicNotification = denuncia.Notificacion_Electronica ?? string.Empty,
            PostalNotificationPreference = denuncia.NotificacionPostal ?? string.Empty,
            Address = isAnonymous ? null : ThirdPartyAddressData.FromComplaint(denuncia)
        };
    }

    private static string BuildLastName(DenunciasGestiona denuncia)
    {
        var separated = string.Join(
            ' ',
            new[] { denuncia.PrimerApellidoResuelto, denuncia.SegundoApellidoResuelto }
                .Where(value => !string.IsNullOrWhiteSpace(value))
                .Select(value => value.Trim()));

        return string.IsNullOrWhiteSpace(separated)
            ? denuncia.ApellidosResueltos.Trim()
            : separated;
    }

    private static bool LooksLikeLegalEntityDocument(string documentId)
    {
        var value = (documentId ?? string.Empty).Trim().ToUpperInvariant();
        if (value.Length != 9)
        {
            return false;
        }

        const string legalEntityPrefixes = "ABCDEFGHJKLMNPQRSUVW";
        return legalEntityPrefixes.Contains(value[0]) &&
               value.Skip(1).Take(7).All(char.IsDigit);
    }
}
