using CashLineERP.Application.Parties;
using CashLineERP.Domain.Parties;
using Microsoft.EntityFrameworkCore;

namespace CashLineERP.Infrastructure.Persistence.Repositories;

public sealed class OnboardingLeadRepository : IOnboardingLeadRepository
{
    private readonly CashLineErpDbContext _dbContext;

    public OnboardingLeadRepository(CashLineErpDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public OnboardingLead Create(OnboardingLead lead)
    {
        _dbContext.OnboardingLeads.Add(lead);
        _dbContext.SaveChanges();
        return lead;
    }

    public OnboardingLead? GetByLeadCode(string leadCode)
    {
        var normalizedCode = NormalizeCode(leadCode);
        var tracked = _dbContext.OnboardingLeads.Local
            .SingleOrDefault(entry => entry.LeadCode == normalizedCode);
        if (tracked is not null)
        {
            return tracked;
        }

        return _dbContext.OnboardingLeads
            .SingleOrDefault(entry => entry.LeadCode == normalizedCode);
    }

    public IReadOnlyCollection<OnboardingLead> GetLeads(string? prospectTypeCode = null, string? statusCode = null)
    {
        var query = _dbContext.OnboardingLeads.AsNoTracking().AsQueryable();

        if (!string.IsNullOrWhiteSpace(prospectTypeCode))
        {
            var normalizedProspectType = prospectTypeCode.Trim().ToUpperInvariant();
            query = query.Where(entry => entry.ProspectTypeCode == normalizedProspectType);
        }

        if (!string.IsNullOrWhiteSpace(statusCode))
        {
            var normalizedStatusCode = statusCode.Trim().ToUpperInvariant();
            query = query.Where(entry => entry.StatusCode == normalizedStatusCode);
        }

        return query
            .OrderByDescending(entry => entry.CreatedAtUtc)
            .ToArray();
    }

    public OnboardingLead Update(OnboardingLead lead)
    {
        _dbContext.OnboardingLeads.Update(lead);
        _dbContext.SaveChanges();
        return lead;
    }

    private static string NormalizeCode(string leadCode)
    {
        var normalizedCode = leadCode?.Trim().ToUpperInvariant();
        if (string.IsNullOrWhiteSpace(normalizedCode))
        {
            throw new InvalidOperationException("Onboarding lead code is required.");
        }

        return normalizedCode;
    }
}
