using System.ComponentModel;
using System.Text.Json;
using ColaFlow.Modules.ProjectManagement.Application.Common.Interfaces;
using ColaFlow.Modules.ProjectManagement.Domain.Repositories;
using Microsoft.Extensions.Logging;
using ModelContextProtocol.Server;

namespace ColaFlow.Modules.Mcp.Application.SdkResources;

/// <summary>
/// MCP Resource: Projects (SDK-based implementation)
/// Provides access to project data in the current tenant
/// </summary>
[McpServerResourceType]
public class ProjectsSdkResource
{
    private readonly IProjectRepository _projectRepository;
    private readonly ITenantContext _tenantContext;
    private readonly ILogger<ProjectsSdkResource> _logger;

    public ProjectsSdkResource(
        IProjectRepository projectRepository,
        ITenantContext tenantContext,
        ILogger<ProjectsSdkResource> logger)
    {
        _projectRepository = projectRepository ?? throw new ArgumentNullException(nameof(projectRepository));
        _tenantContext = tenantContext ?? throw new ArgumentNullException(nameof(tenantContext));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    [McpServerResource]
    [Description("List all projects in current tenant")]
    public async Task<string> ListProjectsAsync(CancellationToken cancellationToken = default)
    {
        var tenantId = _tenantContext.GetCurrentTenantId();

        _logger.LogDebug("Fetching projects list for tenant {TenantId} (SDK)", tenantId);

        // Get all projects (read-only)
        var projects = await _projectRepository.GetAllProjectsReadOnlyAsync(cancellationToken);

        // Map to DTOs
        var projectDtos = projects.Select(p => new
        {
            id = p.Id.Value,
            name = p.Name,
            key = p.Key.ToString(),
            description = p.Description,
            status = p.Status.ToString(),
            createdAt = p.CreatedAt,
            updatedAt = p.UpdatedAt,
            epicCount = p.Epics?.Count ?? 0
        }).ToList();

        var result = JsonSerializer.Serialize(new
        {
            projects = projectDtos,
            total = projectDtos.Count
        }, new JsonSerializerOptions { WriteIndented = true });

        _logger.LogInformation("Retrieved {Count} projects for tenant {TenantId} (SDK)", projectDtos.Count, tenantId);

        return result;
    }

    [McpServerResource]
    [Description("Get detailed information about a specific project")]
    public async Task<string> GetProjectAsync(
        [Description("The project ID")] Guid projectId,
        CancellationToken cancellationToken = default)
    {
        var tenantId = _tenantContext.GetCurrentTenantId();

        _logger.LogDebug("Fetching project {ProjectId} for tenant {TenantId} (SDK)", projectId, tenantId);

        var project = await _projectRepository.GetByIdAsync(
            ProjectManagement.Domain.ValueObjects.ProjectId.From(projectId),
            cancellationToken);

        if (project == null)
        {
            throw new InvalidOperationException($"Project with ID {projectId} not found");
        }

        var result = JsonSerializer.Serialize(new
        {
            id = project.Id.Value,
            name = project.Name,
            key = project.Key.ToString(),
            description = project.Description,
            status = project.Status.ToString(),
            createdAt = project.CreatedAt,
            updatedAt = project.UpdatedAt,
            epics = project.Epics?.Select(e => new
            {
                id = e.Id.Value,
                title = e.Name, // Epic uses Name instead of Title
                status = e.Status.ToString()
            }).ToList() ?? (object)new List<object>()
        }, new JsonSerializerOptions { WriteIndented = true });

        _logger.LogInformation("Retrieved project {ProjectId} for tenant {TenantId} (SDK)", projectId, tenantId);

        return result;
    }
}
