using Godot;
using System;
using System.Collections.Generic;
using Cirno.Scripts.Controllers;
using Cirno.Scripts.Enums;

public partial class Minimap : CanvasLayer
{
    [Export] public RogueliteRoomManager RoomManager { get; private set; }

    private Rid _canvasItemRid;
    private Rid _parentCanvas;
    private Godot.Collections.Dictionary<Vector2I, RogueliteRoom> RoomGrid => RoomManager.RoomGrid;

    private List<RogueliteRoom> SpawnedRooms => RoomManager.SpawnedRooms;

    private List<RoomConnection> Connections => RoomManager.Connections;

    [Export] public int CellSize { get; private set; } = 16;
    [Export] public Vector2 Padding { get; private set; } = new Vector2(20, 20);

    [Export] public float Separation = 2f;

    private Vector2 _viewportSize;

    public override void _Ready()
    {
        RoomManager.MapCreated += RoomManagerOnMapCreated;

        _canvasItemRid = RenderingServer.CanvasItemCreate();
        _parentCanvas = this.GetCanvas(); //GetCanvasItem(); // Gets the RID of this Node2D's canvas
        RenderingServer.CanvasItemSetParent(_canvasItemRid, _parentCanvas);
        RenderingServer.CanvasItemSetVisible(_canvasItemRid, true);
    }

    public override void _EnterTree()
    {
        // Get current window size to position minimap in top-right
        _viewportSize = GetViewport().GetVisibleRect().Size;
    }


    private void RoomManagerOnMapCreated()
    {
        RedrawMinimap();
    }
    
    // public override void _Process(double delta)
    // {
    //     //RedrawMinimap();
    // }

    // public void SetRoomGrid(Dictionary<Vector2I, RogueliteRoom> roomGrid)
    // {
    //     _roomGrid = roomGrid;
    //     RedrawMinimap();
    // }

    private void RedrawMinimap()
    {
        // Clear previous draw commands
        RenderingServer.CanvasItemClear(_canvasItemRid);

        if (SpawnedRooms == null)
            return;

        // Find bounds
        Vector2I min = new(int.MaxValue, int.MaxValue);
        Vector2I max = new(int.MinValue, int.MinValue);

        foreach (var room in SpawnedRooms)
        {
            min = new Vector2I(Math.Min(min.X, room.GridPosition.X), Math.Min(min.Y, room.GridPosition.Y));
            max = new Vector2I(Math.Max(max.X, room.GridPosition.X + room.RoomResource.Size.X),
                Math.Max(max.Y, room.GridPosition.Y + room.RoomResource.Size.Y));
        }

        Vector2 mapSize = (max - min) * CellSize;
        Vector2 offset = new Vector2(
            _viewportSize.X - mapSize.X - Padding.X, // padding from right
            Padding.Y // Top padding
        );

        //Vector2 offset = Padding; // Padding

        foreach (var room in SpawnedRooms)
        {
            Vector2I pos = room.GridPosition;
            Vector2I size = room.RoomResource.Size;
            Vector2 drawPos = offset + (new Vector2((pos.X - min.X), (pos.Y - min.Y))) * (CellSize + Separation);
            Vector2 drawSize = new Vector2(size.X, size.Y) * CellSize +
                               new Vector2((size.X - 1), (size.Y - 1)) * Separation;
            //Vector2 drawSize = new Vector2(size.X, size.Y) * CellSize;

            Color color = GetColorForRoomType(room.RoomResource.Type);

            RenderingServer.CanvasItemAddRect(_canvasItemRid, new Rect2(drawPos, drawSize), color);
        }

        DrawRoomConnections(Connections, min, offset);
        
        //DrawDebugGrid();
    }

    private void DrawPlayer(Vector2I minGrid, Vector2 baseOffset)
    {
        var playerPosition = GameManager.Instance.PlayerPosition;
        
        //var scaledPos = playerPosition  
        
    }
    
    private void DrawDebugGrid()
    {
        foreach (var room in SpawnedRooms)
        {
            var rect = new Rect2(room.GridPosition * RoomManager.TileSize * RoomManager.RoomSizeInTiles, RoomManager.TileSize * RoomManager.RoomSizeInTiles);
            
            RenderingServer.CanvasItemAddRect(_canvasItemRid, rect, new Color(0, 120,0, 125));
        }
    }

    private void DrawRoomConnections(List<RoomConnection> connections, Vector2I minGrid, Vector2 baseOffset)
    {
        int spacing = (int)Separation;

        foreach (var connection in connections)
        {
            // Skip if either room is missing
            if (!RoomGrid.ContainsKey(connection.From) || !RoomGrid.ContainsKey(connection.To))
                continue;

            // Convert grid coordinates to local minimap grid (relative to min)
            Vector2I fromGrid = connection.From - minGrid;
            Vector2I toGrid = connection.To - minGrid;

            // Center of the From cell in pixels
            Vector2 fromCenter = baseOffset
                                 + fromGrid * (CellSize + spacing)
                                 + new Vector2(CellSize / 2f, CellSize / 2f);

            // Center of the To cell in pixels
            Vector2 toCenter = baseOffset
                               + toGrid * (CellSize + spacing)
                               + new Vector2(CellSize / 2f, CellSize / 2f);

            // The gap center between rooms
            Vector2 gapCenter = (fromCenter + toCenter) * 0.5f;

            // Short line inside the separation gap
            Vector2 delta = (toCenter - fromCenter).Normalized();
            Vector2 halfGap = delta * (spacing / 2f);

            Vector2 lineStart = gapCenter - halfGap;
            Vector2 lineEnd = gapCenter + halfGap;

            // Pick color based on type
            Color color = Colors.White;
            if (connection.IsSecret)
                color = Colors.Purple;
            else if (connection.IsLocked)
                color = Colors.Orange;

            float thickness = 1f;

            // Draw the line
            RenderingServer.CanvasItemAddLine(_canvasItemRid, lineStart, lineEnd, color, thickness);
        }
    }

    private Color GetColorForRoomType(RoomType type)
    {
        return type switch
        {
            RoomType.Boss => Colors.Red,
            RoomType.Shop => Colors.DarkKhaki,
            RoomType.Regular => Colors.Blue,
            RoomType.Key => Colors.Purple,
            RoomType.Secret => Colors.Bisque,
            RoomType.Treasure => Colors.Gold,
            RoomType.Starter => Colors.Green,
            _ => Colors.DimGray
        };
    }
}