using System.Collections.Generic;
using UnityEngine;
using System.Linq;

public class MapData
{
    public int Width { get; private set; }
    public int Height { get; private set; }

    private MapTile[,] tiles;
    private List<Settlement> settlements;

    public MapData(int width, int height)
    {
        Width = width;
        Height = height;
        tiles = new MapTile[width, height];
        settlements = new List<Settlement>();

        InitializeTiles();
    }

    private void InitializeTiles()
    {
        for (int x = 0; x < Width; x++)
        {
            for (int y = 0; y < Height; y++)
            {
                tiles[x, y] = new MapTile(x, y);
            }
        }
    }

    public MapTile GetTile(int x, int y)
    {
        if (IsValidPosition(x, y))
            return tiles[x, y];
        return null;
    }

    public void SetTile(int x, int y, MapTile tile)
    {
        if (IsValidPosition(x, y))
            tiles[x, y] = tile;
    }

    public bool IsValidPosition(int x, int y)
    {
        return x >= 0 && x < Width && y >= 0 && y < Height;
    }

    public void ExpandMap(int newWidth, int newHeight)
    {
        MapTile[,] newTiles = new MapTile[newWidth, newHeight];

        // Copy existing tiles
        for (int x = 0; x < Width; x++)
        {
            for (int y = 0; y < Height; y++)
            {
                newTiles[x, y] = tiles[x, y];
            }
        }

        // Initialize new tiles
        for (int x = 0; x < newWidth; x++)
        {
            for (int y = 0; y < newHeight; y++)
            {
                if (newTiles[x, y] == null)
                {
                    newTiles[x, y] = new MapTile(x, y);
                }
            }
        }

        tiles = newTiles;
        Width = newWidth;
        Height = newHeight;
    }

    public void ExpandMapWithOffset(int newWidth, int newHeight, int offsetX, int offsetY)
    {
        MapTile[,] newTiles = new MapTile[newWidth, newHeight];

        // Copy existing tiles with offset
        for (int x = 0; x < Width; x++)
        {
            for (int y = 0; y < Height; y++)
            {
                int newX = x + offsetX;
                int newY = y + offsetY;
                if (newX >= 0 && newX < newWidth && newY >= 0 && newY < newHeight)
                {
                    newTiles[newX, newY] = tiles[x, y];
                    // Update tile coordinates
                    newTiles[newX, newY].x = newX;
                    newTiles[newX, newY].y = newY;
                }
            }
        }

        // Initialize new tiles
        for (int x = 0; x < newWidth; x++)
        {
            for (int y = 0; y < newHeight; y++)
            {
                if (newTiles[x, y] == null)
                {
                    newTiles[x, y] = new MapTile(x, y);
                }
            }
        }

        // Update settlements positions
        foreach (var settlement in settlements)
        {
            settlement.position.x += offsetX;
            settlement.position.y += offsetY;
        }

        tiles = newTiles;
        Width = newWidth;
        Height = newHeight;
    }

    public void AddSettlement(Settlement settlement)
    {
        settlements.Add(settlement);
    }

    public List<Settlement> GetTowns()
    {
        return settlements.Where(s => s.Type == SettlementType.Town).ToList();
    }

    public List<Settlement> GetVillages()
    {
        return settlements.Where(s => s.Type == SettlementType.Village).ToList();
    }

    public List<Vector2Int> GetNeighbors(int x, int y, bool includeDiagonals = false)
    {
        List<Vector2Int> neighbors = new List<Vector2Int>();

        for (int dx = -1; dx <= 1; dx++)
        {
            for (int dy = -1; dy <= 1; dy++)
            {
                if (dx == 0 && dy == 0) continue;
                if (!includeDiagonals && dx != 0 && dy != 0) continue;

                int nx = x + dx;
                int ny = y + dy;

                if (IsValidPosition(nx, ny))
                {
                    neighbors.Add(new Vector2Int(nx, ny));
                }
            }
        }

        return neighbors;
    }
}

[System.Serializable]
public class Settlement
{
    public string name;
    public SettlementType Type;
    public Vector2Int position;
    public List<Vector2Int> tiles;

    public Settlement(string name, SettlementType type, Vector2Int position)
    {
        this.name = name;
        this.Type = type;
        this.position = position;
        this.tiles = new List<Vector2Int>();
    }
}

public enum SettlementType
{
    Town,
    Village
}