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

public class SettlementGenerator
{
    private static readonly string[] townNames = {
        "Ashford", "Brookhaven", "Clearwater", "Drakemoor", "Emberfall",
        "Frostholm", "Goldmeadow", "Ironbridge", "Moonhaven", "Oakenford",
        "Ravenshollow", "Silverdale", "Thornwick", "Wolfsburg", "Brightwater"
    };

    private static readonly string[] villageNames = {
        "Millbrook", "Stonefield", "Greenhill", "Redrock", "Fairhaven",
        "Smallwood", "Riverside", "Hillcrest", "Meadowbrook", "Pinewood",
        "Sunset", "Morning", "Pleasant", "Quiet", "Little"
    };

    public void GenerateSettlements(MapData mapData)
    {
        GenerateTowns(mapData);
        GenerateVillages(mapData);
    }

    private void GenerateTowns(MapData mapData)
    {
        int townCount = Random.Range(2, 5);
        int attempts = 0;
        int maxAttempts = 100;

        while (mapData.GetTowns().Count < townCount && attempts < maxAttempts)
        {
            attempts++;

            int x = Random.Range(15, mapData.Width - 15);
            int y = Random.Range(15, mapData.Height - 15);

            if (CanPlaceSettlement(mapData, x, y, 9, 10))
            {
                CreateTown(mapData, x, y);
            }
        }
    }

    private void GenerateVillages(MapData mapData)
    {
        int villageCount = Random.Range(8, 15);
        int attempts = 0;
        int maxAttempts = 200;

        while (mapData.GetVillages().Count < villageCount && attempts < maxAttempts)
        {
            attempts++;

            int x = Random.Range(5, mapData.Width - 5);
            int y = Random.Range(5, mapData.Height - 5);

            if (CanPlaceSettlement(mapData, x, y, 1, 10))
            {
                CreateVillage(mapData, x, y);
            }
        }
    }

    private bool CanPlaceSettlement(MapData mapData, int x, int y, int size, int minDistance)
    {
        // Check if area is suitable (plains terrain)
        for (int dx = -size / 2; dx <= size / 2; dx++)
        {
            for (int dy = -size / 2; dy <= size / 2; dy++)
            {
                int checkX = x + dx;
                int checkY = y + dy;

                if (!mapData.IsValidPosition(checkX, checkY))
                    return false;

                MapTile tile = mapData.GetTile(checkX, checkY);
                if (tile.terrainType != TerrainType.Plains &&
                    tile.terrainType != TerrainType.Shore)
                    return false;
            }
        }

        // Check distance from other settlements
        var allSettlements = mapData.GetTowns();
        allSettlements.AddRange(mapData.GetVillages());

        foreach (var settlement in allSettlements)
        {
            float distance = Vector2.Distance(new Vector2(x, y),
                                            new Vector2(settlement.position.x, settlement.position.y));
            if (distance < minDistance)
                return false;
        }

        return true;
    }

    private void CreateTown(MapData mapData, int centerX, int centerY)
    {
        string name = GetRandomName(townNames);
        var settlement = new Settlement(name, SettlementType.Town, new Vector2Int(centerX, centerY));

        // Create 3x3 town area
        for (int dx = -1; dx <= 1; dx++)
        {
            for (int dy = -1; dy <= 1; dy++)
            {
                int x = centerX + dx;
                int y = centerY + dy;

                if (mapData.IsValidPosition(x, y))
                {
                    mapData.GetTile(x, y).featureType = FeatureType.Town;
                    mapData.GetTile(x, y).name = name;
                    settlement.tiles.Add(new Vector2Int(x, y));
                }
            }
        }

        mapData.AddSettlement(settlement);
    }

    private void CreateVillage(MapData mapData, int x, int y)
    {
        string name = GetRandomName(villageNames);
        var settlement = new Settlement(name, SettlementType.Village, new Vector2Int(x, y));

        mapData.GetTile(x, y).featureType = FeatureType.Village;
        mapData.GetTile(x, y).name = name;
        settlement.tiles.Add(new Vector2Int(x, y));

        mapData.AddSettlement(settlement);
    }

    private string GetRandomName(string[] nameArray)
    {
        return nameArray[Random.Range(0, nameArray.Length)];
    }
}