using CashLineERP.Domain.Common;

namespace CashLineERP.Domain.Parties;

public sealed class OnboardingLead : Entity
{
    public long Id { get; private set; }
    public string LeadCode { get; private set; } = string.Empty;
    public string ProspectTypeCode { get; private set; } = string.Empty;
    public string? CompanyName { get; private set; }
    public string? ContactName { get; private set; }
    public string? Email { get; private set; }
    public string? MobileNumber { get; private set; }
    public string SourceChannelCode { get; private set; } = string.Empty;
    public string StatusCode { get; private set; } = string.Empty;
    public string? Notes { get; private set; }
    public long? BusinessPartyId { get; private set; }
    public long? SubjectProfileId { get; private set; }
    public DateTime? SubmittedAtUtc { get; private set; }

    public OnboardingLead(
        string leadCode,
        string prospectTypeCode,
        string? companyName,
        string? contactName,
        string? email,
        string? mobileNumber,
        string sourceChannelCode,
        string? notes)
    {
        LeadCode = NormalizeRequired(leadCode, "lead code");
        ProspectTypeCode = NormalizeRequired(prospectTypeCode, "prospect type code");
        CompanyName = NormalizeOptional(companyName);
        ContactName = NormalizeOptional(contactName);
        Email = NormalizeOptional(email);
        MobileNumber = NormalizeOptional(mobileNumber);
        SourceChannelCode = NormalizeRequired(sourceChannelCode, "source channel code");
        StatusCode = "LEAD_CAPTURED";
        Notes = NormalizeOptional(notes);

        if (Email is null && MobileNumber is null)
        {
            throw new InvalidOperationException("Onboarding lead requires at least one communication destination.");
        }
    }

    private OnboardingLead()
    {
    }

    public void MarkSelfServiceStarted(string? notes = null)
    {
        StatusCode = "SELF_SERVICE_IN_PROGRESS";
        Notes = NormalizeOptional(notes) ?? Notes;
        Touch(null);
    }

    public void MarkSubmitted(long businessPartyId, long subjectProfileId, string? notes = null)
    {
        if (businessPartyId <= 0 || subjectProfileId <= 0)
        {
            throw new InvalidOperationException("Onboarding lead submission requires valid party and profile identifiers.");
        }

        BusinessPartyId = businessPartyId;
        SubjectProfileId = subjectProfileId;
        StatusCode = "SELF_SERVICE_SUBMITTED";
        SubmittedAtUtc = DateTime.UtcNow;
        Notes = NormalizeOptional(notes) ?? Notes;
        Touch(null);
    }

    private static string NormalizeRequired(string value, string fieldName)
    {
        var normalizedValue = NormalizeOptional(value);
        if (string.IsNullOrWhiteSpace(normalizedValue))
        {
            throw new InvalidOperationException($"Onboarding lead {fieldName} is required.");
        }

        return normalizedValue;
    }

    private static string? NormalizeOptional(string? value) =>
        string.IsNullOrWhiteSpace(value) ? null : value.Trim();
}
