using Apollinare.Domain.Entities;
using Apollinare.Infrastructure.Data;
using Microsoft.EntityFrameworkCore;

namespace Apollinare.API.Services;

public class CustomFieldService
{
    private readonly AppollinareDbContext _context;
    private readonly ILogger<CustomFieldService> _logger;

    public CustomFieldService(AppollinareDbContext context, ILogger<CustomFieldService> logger)
    {
        _context = context;
        _logger = logger;
    }

    public async Task<List<CustomFieldDefinition>> GetAllDefinitionsAsync()
    {
        return await _context.CustomFieldDefinitions
            .OrderBy(x => x.EntityName)
            .ThenBy(x => x.SortOrder)
            .ToListAsync();
    }

    public async Task<List<CustomFieldDefinition>> GetDefinitionsByEntityAsync(string entityName)
    {
        return await _context.CustomFieldDefinitions
            .Where(x => x.EntityName == entityName && x.IsActive)
            .OrderBy(x => x.SortOrder)
            .ToListAsync();
    }

    public async Task<CustomFieldDefinition?> GetDefinitionAsync(int id)
    {
        return await _context.CustomFieldDefinitions.FindAsync(id);
    }

    public async Task<CustomFieldDefinition> CreateDefinitionAsync(CustomFieldDefinition definition)
    {
        // Check for duplicate field name in the same entity
        var exists = await _context.CustomFieldDefinitions
            .AnyAsync(x => x.EntityName == definition.EntityName && x.FieldName == definition.FieldName);
        
        if (exists)
        {
            throw new ArgumentException($"Field '{definition.FieldName}' already exists for entity '{definition.EntityName}'");
        }

        definition.CreatedAt = DateTime.UtcNow;
        _context.CustomFieldDefinitions.Add(definition);
        await _context.SaveChangesAsync();
        return definition;
    }

    public async Task<CustomFieldDefinition> UpdateDefinitionAsync(int id, CustomFieldDefinition updatedDef)
    {
        var existing = await _context.CustomFieldDefinitions.FindAsync(id);
        if (existing == null)
        {
            throw new KeyNotFoundException($"CustomFieldDefinition with ID {id} not found");
        }

        existing.Label = updatedDef.Label;
        existing.Type = updatedDef.Type;
        existing.IsRequired = updatedDef.IsRequired;
        existing.DefaultValue = updatedDef.DefaultValue;
        existing.OptionsJson = updatedDef.OptionsJson;
        existing.SortOrder = updatedDef.SortOrder;
        existing.Description = updatedDef.Description;
        existing.IsActive = updatedDef.IsActive;
        existing.ValidationRegex = updatedDef.ValidationRegex;
        existing.Placeholder = updatedDef.Placeholder;
        existing.UpdatedAt = DateTime.UtcNow;

        await _context.SaveChangesAsync();
        return existing;
    }

    public async Task DeleteDefinitionAsync(int id)
    {
        var existing = await _context.CustomFieldDefinitions.FindAsync(id);
        if (existing == null)
        {
            throw new KeyNotFoundException($"CustomFieldDefinition with ID {id} not found");
        }

        _context.CustomFieldDefinitions.Remove(existing);
        await _context.SaveChangesAsync();
    }
}
