namespace Baya.Infrastructure.Persistence.Configuration.GeographyConfig;

/// <summary>
/// The one-time province/city/district seed, loaded via <c>HasData</c> so the rows land with the
/// migration on a fresh DB (the b1 seeding path). Ids are fixed and deterministic — city id is
/// <c>100 + provinceId</c>, Tehran's districts are <c>1001…1022</c> — so re-running is idempotent and the
/// model snapshot stays stable. All 31 provinces get their capital city (which covers the product's
/// white-space targets — Tehran, Karaj, Mashhad, Isfahan, Shiraz, Tabriz, Ahvaz, Qom, all provincial
/// capitals); only Tehran gets districts at seed time. Adding neighborhoods elsewhere is a later admin
/// insert, never a deploy.
/// </summary>
internal static class GeographySeed
{
    public const long TehranProvinceId = 1;
    public const long TehranCityId = 101;

    // (id, name_fa, name_en, capital_fa, capital_en). Tehran first, then by convention; sort_order = id.
    private static readonly (long Id, string NameFa, string NameEn, string CapitalFa, string CapitalEn)[] ProvinceRows =
    [
        (1, "تهران", "Tehran", "تهران", "Tehran"),
        (2, "البرز", "Alborz", "کرج", "Karaj"),
        (3, "اصفهان", "Isfahan", "اصفهان", "Isfahan"),
        (4, "فارس", "Fars", "شیراز", "Shiraz"),
        (5, "خراسان رضوی", "Razavi Khorasan", "مشهد", "Mashhad"),
        (6, "آذربایجان شرقی", "East Azerbaijan", "تبریز", "Tabriz"),
        (7, "آذربایجان غربی", "West Azerbaijan", "ارومیه", "Urmia"),
        (8, "خوزستان", "Khuzestan", "اهواز", "Ahvaz"),
        (9, "قم", "Qom", "قم", "Qom"),
        (10, "کرمان", "Kerman", "کرمان", "Kerman"),
        (11, "گیلان", "Gilan", "رشت", "Rasht"),
        (12, "مازندران", "Mazandaran", "ساری", "Sari"),
        (13, "مرکزی", "Markazi", "اراک", "Arak"),
        (14, "اردبیل", "Ardabil", "اردبیل", "Ardabil"),
        (15, "قزوین", "Qazvin", "قزوین", "Qazvin"),
        (16, "کرمانشاه", "Kermanshah", "کرمانشاه", "Kermanshah"),
        (17, "خراسان شمالی", "North Khorasan", "بجنورد", "Bojnord"),
        (18, "خراسان جنوبی", "South Khorasan", "بیرجند", "Birjand"),
        (19, "همدان", "Hamadan", "همدان", "Hamadan"),
        (20, "کردستان", "Kurdistan", "سنندج", "Sanandaj"),
        (21, "لرستان", "Lorestan", "خرم‌آباد", "Khorramabad"),
        (22, "گلستان", "Golestan", "گرگان", "Gorgan"),
        (23, "هرمزگان", "Hormozgan", "بندرعباس", "Bandar Abbas"),
        (24, "بوشهر", "Bushehr", "بوشهر", "Bushehr"),
        (25, "زنجان", "Zanjan", "زنجان", "Zanjan"),
        (26, "سمنان", "Semnan", "سمنان", "Semnan"),
        (27, "یزد", "Yazd", "یزد", "Yazd"),
        (28, "سیستان و بلوچستان", "Sistan and Baluchestan", "زاهدان", "Zahedan"),
        (29, "چهارمحال و بختیاری", "Chaharmahal and Bakhtiari", "شهرکرد", "Shahrekord"),
        (30, "کهگیلویه و بویراحمد", "Kohgiluyeh and Boyer-Ahmad", "یاسوج", "Yasuj"),
        (31, "ایلام", "Ilam", "ایلام", "Ilam"),
    ];

    // Tehran's 22 municipal مناطق, as Persian ordinals ("منطقه ۱" … "منطقه ۲۲").
    private static readonly string[] PersianDigits = ["۰", "۱", "۲", "۳", "۴", "۵", "۶", "۷", "۸", "۹"];

    public static object[] Provinces()
    {
        var ts = SeedConstants.Timestamp;
        return ProvinceRows
            .Select(p => (object)new
            {
                p.Id,
                p.NameFa,
                p.NameEn,
                SortOrder = (int)p.Id,
                IsActive = true,
                CreatedAt = ts
            })
            .ToArray();
    }

    public static object[] Cities()
    {
        var ts = SeedConstants.Timestamp;
        return ProvinceRows
            .Select(p => (object)new
            {
                Id = 100 + p.Id,
                ProvinceId = p.Id,
                NameFa = p.CapitalFa,
                NameEn = p.CapitalEn,
                SortOrder = 1,
                IsActive = true,
                CreatedAt = ts
            })
            .ToArray();
    }

    public static object[] Districts()
    {
        var ts = SeedConstants.Timestamp;
        return Enumerable.Range(1, 22)
            .Select(n => (object)new
            {
                Id = 1000L + n,
                CityId = TehranCityId,
                NameFa = $"منطقه {ToPersianNumber(n)}",
                NameEn = $"District {n}",
                SortOrder = n,
                IsActive = true,
                CreatedAt = ts
            })
            .ToArray();
    }

    private static string ToPersianNumber(int value) =>
        string.Concat(value.ToString(System.Globalization.CultureInfo.InvariantCulture)
            .Select(c => PersianDigits[c - '0']));
}
