using JobsMedical.Web.Models;
using Microsoft.EntityFrameworkCore;

namespace JobsMedical.Web.Data;

/// <summary>
/// Seeds a believable Tehran-focused board so the marketplace doesn't look empty on first run
/// (the cold-start problem). Idempotent: only seeds when the DB is empty.
/// </summary>
public static class SeedData
{
    public static async Task EnsureSeededAsync(AppDbContext db)
    {
        if (await db.Cities.AnyAsync()) return;

        var tehran = new City { Name = "تهران", Province = "تهران", IsActive = true };
        var cities = new[]
        {
            tehran,
            new City { Name = "کرج", Province = "البرز", IsActive = false },
            new City { Name = "مشهد", Province = "خراسان رضوی", IsActive = false },
            new City { Name = "اصفهان", Province = "اصفهان", IsActive = false },
            new City { Name = "شیراز", Province = "فارس", IsActive = false },
        };
        db.Cities.AddRange(cities);
        await db.SaveChangesAsync(); // need tehran.Id before districts reference it

        var roles = new[]
        {
            new Role { Name = "پزشک عمومی", Category = "پزشک", SortOrder = 1 },
            new Role { Name = "پزشک متخصص", Category = "پزشک", SortOrder = 2 },
            new Role { Name = "پرستار", Category = "پرستار", SortOrder = 3 },
            new Role { Name = "ماما", Category = "ماما", SortOrder = 4 },
            new Role { Name = "تکنسین اتاق عمل", Category = "تکنسین", SortOrder = 5 },
            new Role { Name = "تکنسین فوریت‌های پزشکی", Category = "تکنسین", SortOrder = 6 },
            new Role { Name = "کارشناس آزمایشگاه", Category = "تکنسین", SortOrder = 7 },
        };
        db.Roles.AddRange(roles);

        // Tehran neighborhoods (محله/منطقه) for the within-city filter.
        var saadatAbad  = new District { Name = "سعادت‌آباد", CityId = tehran.Id };
        var shahrakGharb = new District { Name = "شهرک غرب", CityId = tehran.Id };
        var valiasr     = new District { Name = "ولیعصر / پارک‌وی", CityId = tehran.Id };
        var narmak      = new District { Name = "نارمک", CityId = tehran.Id };
        var tehranpars  = new District { Name = "تهرانپارس", CityId = tehran.Id };
        var gisha       = new District { Name = "گیشا / برج میلاد", CityId = tehran.Id };
        db.Districts.AddRange(saadatAbad, shahrakGharb, valiasr, narmak, tehranpars, gisha,
            new District { Name = "ونک", CityId = tehran.Id },
            new District { Name = "تجریش", CityId = tehran.Id });
        await db.SaveChangesAsync();

        var facilities = new[]
        {
            new Facility { Name = "بیمارستان میلاد", Type = FacilityType.Hospital, CityId = tehran.Id,
                DistrictId = gisha.Id,
                Address = "تهران، بزرگراه همت، روبه‌روی برج میلاد", Phone = "021-82032000",
                Lat = 35.7448, Lng = 51.3753, IsVerified = true },
            new Facility { Name = "بیمارستان دی", Type = FacilityType.Hospital, CityId = tehran.Id,
                DistrictId = valiasr.Id,
                Address = "تهران، خیابان ولیعصر، بالاتر از پارک‌وی", Phone = "021-23601",
                Lat = 35.7986, Lng = 51.4087, IsVerified = true },
            new Facility { Name = "کلینیک تخصصی پارسیان", Type = FacilityType.Clinic, CityId = tehran.Id,
                DistrictId = saadatAbad.Id,
                Address = "تهران، سعادت‌آباد، میدان کاج", Phone = "021-22360000",
                Lat = 35.7872, Lng = 51.3760, IsVerified = false },
            new Facility { Name = "درمانگاه شبانه‌روزی البرز", Type = FacilityType.Polyclinic, CityId = tehran.Id,
                DistrictId = narmak.Id,
                Address = "تهران، نارمک، میدان هلال احمر", Phone = "021-77900000",
                Lat = 35.7448, Lng = 51.5085, IsVerified = true },
            new Facility { Name = "بیمارستان آتیه", Type = FacilityType.Hospital, CityId = tehran.Id,
                DistrictId = shahrakGharb.Id,
                Address = "تهران، شهرک غرب، بلوار فرحزادی", Phone = "021-82721",
                Lat = 35.7570, Lng = 51.3680, IsVerified = true },
            new Facility { Name = "کلینیک درمانی مهر", Type = FacilityType.Clinic, CityId = tehran.Id,
                DistrictId = tehranpars.Id,
                Address = "تهران، تهرانپارس، فلکه دوم", Phone = "021-77700000",
                Lat = 35.7350, Lng = 51.5400, IsVerified = false },
        };
        db.Facilities.AddRange(facilities);
        await db.SaveChangesAsync();

        // Build ~2 weeks of shifts starting today, a few per facility per day, across roles.
        var today = DateOnly.FromDateTime(DateTime.UtcNow);
        var rng = new Random(20260602); // deterministic seed for reproducible sample data
        var shifts = new List<Shift>();

        // Weighted role pool — GP and nurse most common, others sprinkled in.
        var rolePool = new[]
        {
            roles[0], roles[0], roles[0],   // پزشک عمومی (most common)
            roles[2], roles[2],             // پرستار
            roles[1],                       // پزشک متخصص
            roles[3],                       // ماما
            roles[4], roles[5], roles[6],   // تکنسین‌ها
        };

        var templates = new[]
        {
            (ShiftType.Day,     new TimeOnly(8, 0),  new TimeOnly(14, 0), "شیفت صبح", 1_500_000L),
            (ShiftType.Evening, new TimeOnly(14, 0), new TimeOnly(20, 0), "شیفت عصر", 1_800_000L),
            (ShiftType.Night,   new TimeOnly(20, 0), new TimeOnly(8, 0),  "شیفت شب", 2_500_000L),
            (ShiftType.OnCall,  new TimeOnly(8, 0),  new TimeOnly(8, 0),  "آنکال", 0L),
        };

        foreach (var f in facilities)
        {
            for (var d = 0; d < 14; d++)
            {
                var date = today.AddDays(d);
                var count = rng.Next(0, 3); // 0–2 shifts per facility per day
                for (var i = 0; i < count; i++)
                {
                    var t = templates[rng.Next(templates.Length)];
                    var role = rolePool[rng.Next(rolePool.Length)];

                    // Vary the compensation model: fixed, profit-share, both (choose), or negotiable.
                    var payType = PayType.PerShift;
                    long? amount = t.Item5;
                    int? share = null;
                    if (t.Item1 == ShiftType.OnCall) { payType = PayType.Negotiable; amount = null; }
                    else
                    {
                        switch (rng.Next(0, 5))
                        {
                            case 0: payType = PayType.Negotiable; amount = null; break;   // توافقی
                            case 1: payType = PayType.Percentage; amount = null;          // درصدی
                                    share = rng.Next(0, 2) == 0 ? 50 : 60; break;
                            case 2: share = rng.Next(0, 2) == 0 ? 40 : 50; break;         // مبلغ یا درصد (به انتخاب)
                            default: break;                                               // مبلغ مقطوع
                        }
                    }

                    shifts.Add(new Shift
                    {
                        FacilityId = f.Id,
                        RoleId = role.Id,
                        Date = date,
                        StartTime = t.Item2,
                        EndTime = t.Item3,
                        ShiftType = t.Item1,
                        SpecialtyRequired = role.Name,
                        Description = $"{t.Item4} - نیازمند {role.Name} مسلط به امور درمانگاه/اورژانس",
                        PayType = payType,
                        PayAmount = amount,
                        SharePercent = share,
                        Status = ShiftStatus.Open,
                        Source = ShiftSource.Admin,
                    });
                }
            }
        }
        db.Shifts.AddRange(shifts);

        // Permanent hiring openings (استخدام) — the hiring side of the marketplace.
        db.JobOpenings.AddRange(
            new JobOpening { FacilityId = facilities[0].Id, RoleId = roles[2].Id,
                Title = "استخدام پرستار بخش اورژانس", EmploymentType = EmploymentType.FullTime,
                SalaryMin = 18_000_000, SalaryMax = 25_000_000,
                Description = "استخدام تمام‌وقت پرستار جهت بخش اورژانس با سابقه کار.",
                Requirements = "حداقل ۲ سال سابقه، مسلط به ICU", Status = ShiftStatus.Open },
            new JobOpening { FacilityId = facilities[1].Id, RoleId = roles[0].Id,
                Title = "پزشک عمومی مقیم", EmploymentType = EmploymentType.Contract,
                SalaryMin = 40_000_000, SalaryMax = 55_000_000,
                Description = "پزشک عمومی مقیم جهت بیمارستان، شیفت‌های چرخشی.",
                Status = ShiftStatus.Open },
            new JobOpening { FacilityId = facilities[2].Id, RoleId = roles[3].Id,
                Title = "ماما جهت کلینیک زنان", EmploymentType = EmploymentType.PartTime,
                SalaryMin = null, SalaryMax = null,
                Description = "همکاری پاره‌وقت ماما در کلینیک تخصصی زنان و زایمان.",
                Status = ShiftStatus.Open },
            new JobOpening { FacilityId = facilities[4].Id, RoleId = roles[4].Id,
                Title = "تکنسین اتاق عمل", EmploymentType = EmploymentType.FullTime,
                SalaryMin = 16_000_000, SalaryMax = 22_000_000,
                Description = "تکنسین اتاق عمل جهت بیمارستان، تمام‌وقت با بیمه.",
                Requirements = "مدرک تکنسین اتاق عمل، آشنا به ابزار جراحی", Status = ShiftStatus.Open },
            new JobOpening { FacilityId = facilities[3].Id, RoleId = roles[0].Id,
                Title = "پزشک عمومی طرح", EmploymentType = EmploymentType.Plan,
                SalaryMin = 30_000_000, SalaryMax = 30_000_000,
                Description = "جذب پزشک عمومی جهت گذراندن طرح در درمانگاه شبانه‌روزی.",
                Status = ShiftStatus.Open });

        await db.SaveChangesAsync();

        // A couple of raw listings waiting in the admin normalization queue.
        db.RawListings.AddRange(
            new RawListing
            {
                SourceChannel = "کانال شیفت پزشکان تهران",
                RawText = "نیازمند پزشک عمومی جهت شیفت شب درمانگاه در منطقه غرب تهران، کارانه توافقی. تماس: ۰۹۱۲xxxxxxx",
                Status = RawListingStatus.New,
            },
            new RawListing
            {
                SourceChannel = "Divar - استخدام پزشک",
                RawText = "بیمارستان خصوصی جهت تکمیل کادر درمان به پزشک عمومی برای شیفت‌های روز نیازمند است.",
                Status = RawListingStatus.New,
            },
            new RawListing
            {
                SourceChannel = "کانال درمانگاه‌های تهران",
                RawText = "درمانگاه شبانه‌روزی نیازمند پزشک عمومی برای شیفت عصر، پرداخت ۵۰٪ سهم درآمد ویزیت. سعادت‌آباد.",
                Status = RawListingStatus.New,
            });
        await db.SaveChangesAsync();
    }
}
