using System.Text.Json;
using ColaFlow.Modules.Mcp.Contracts.Resources;
using ColaFlow.Modules.Mcp.Domain.Exceptions;
using ColaFlow.Modules.ProjectManagement.Application.Common.Interfaces;
using ColaFlow.Modules.ProjectManagement.Domain.Repositories;
using ColaFlow.Modules.ProjectManagement.Domain.ValueObjects;
using Microsoft.Extensions.Logging;

namespace ColaFlow.Modules.Mcp.Application.Resources;

/// <summary>
/// Resource: colaflow://issues.get/{id}
/// Gets detailed information about a specific issue (Epic, Story, or Task)
/// </summary>
public class IssuesGetResource(
    IProjectRepository projectRepository,
    ITenantContext tenantContext,
    ILogger<IssuesGetResource> logger)
    : IMcpResource
{
    public string Uri => "colaflow://issues.get/{id}";
    public string Name => "Issue Details";
    public string Description => "Get detailed information about an issue (Epic/Story/Task)";
    public string MimeType => "application/json";
    public string Category => "Issues";
    public string Version => "1.0";

    public async Task<McpResourceContent> GetContentAsync(
        McpResourceRequest request,
        CancellationToken cancellationToken)
    {
        var tenantId = tenantContext.GetCurrentTenantId();

        // Extract {id} from URI parameters
        if (!request.UriParams.TryGetValue("id", out var idString))
        {
            throw new McpInvalidParamsException("Missing required parameter: id");
        }

        if (!Guid.TryParse(idString, out var issueIdGuid))
        {
            throw new McpInvalidParamsException($"Invalid issue ID format: {idString}");
        }

        logger.LogDebug("Fetching issue {IssueId} for tenant {TenantId}", issueIdGuid, tenantId);

        // Try to find as Epic
        var epic = await projectRepository.GetEpicByIdReadOnlyAsync(EpicId.From(issueIdGuid), cancellationToken);
        if (epic != null)
        {
            var epicDto = new
            {
                id = epic.Id.Value,
                type = "Epic",
                name = epic.Name,
                description = epic.Description,
                status = epic.Status.ToString(),
                priority = epic.Priority.ToString(),
                createdAt = epic.CreatedAt,
                updatedAt = epic.UpdatedAt,
                stories = epic.Stories?.Select(s => new
                {
                    id = s.Id.Value,
                    title = s.Title,
                    status = s.Status.ToString(),
                    priority = s.Priority.ToString(),
                    assigneeId = s.AssigneeId?.Value
                }).ToList()
            };

            var json = JsonSerializer.Serialize(epicDto, new JsonSerializerOptions { WriteIndented = true });

            return new McpResourceContent
            {
                Uri = request.Uri,
                MimeType = MimeType,
                Text = json
            };
        }

        // Try to find as Story
        var story = await projectRepository.GetStoryByIdReadOnlyAsync(StoryId.From(issueIdGuid), cancellationToken);
        if (story != null)
        {
            var storyDto = new
            {
                id = story.Id.Value,
                type = "Story",
                title = story.Title,
                description = story.Description,
                status = story.Status.ToString(),
                priority = story.Priority.ToString(),
                assigneeId = story.AssigneeId?.Value,
                createdAt = story.CreatedAt,
                updatedAt = story.UpdatedAt,
                tasks = story.Tasks?.Select(t => new
                {
                    id = t.Id.Value,
                    title = t.Title,
                    status = t.Status.ToString(),
                    priority = t.Priority.ToString(),
                    assigneeId = t.AssigneeId?.Value
                }).ToList()
            };

            var json = JsonSerializer.Serialize(storyDto, new JsonSerializerOptions { WriteIndented = true });

            return new McpResourceContent
            {
                Uri = request.Uri,
                MimeType = MimeType,
                Text = json
            };
        }

        // Try to find as Task
        var task = await projectRepository.GetTaskByIdReadOnlyAsync(TaskId.From(issueIdGuid), cancellationToken);
        if (task != null)
        {
            var taskDto = new
            {
                id = task.Id.Value,
                type = "Task",
                title = task.Title,
                description = task.Description,
                status = task.Status.ToString(),
                priority = task.Priority.ToString(),
                assigneeId = task.AssigneeId?.Value,
                createdAt = task.CreatedAt,
                updatedAt = task.UpdatedAt
            };

            var json = JsonSerializer.Serialize(taskDto, new JsonSerializerOptions { WriteIndented = true });

            return new McpResourceContent
            {
                Uri = request.Uri,
                MimeType = MimeType,
                Text = json
            };
        }

        // Not found
        throw new McpNotFoundException($"Issue not found: {issueIdGuid}");
    }
}
