using JobsMedical.Web.Data;
using JobsMedical.Web.Models;
using JobsMedical.Web.Services;
using JobsMedical.Web.Services.Scraping;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace JobsMedical.Web.Pages.Admin;

[Authorize(Roles = "Admin")]
public class SettingsModel : PageModel
{
    private readonly SettingsService _settings;
    private readonly ISmsSender _sms;
    private readonly AppDbContext _db;
    private readonly ScrapeHttpClients _clients;
    private readonly IAiAuditor _ai;
    public SettingsModel(SettingsService settings, ISmsSender sms, AppDbContext db,
        ScrapeHttpClients clients, IAiAuditor ai)
    {
        _settings = settings;
        _sms = sms;
        _db = db;
        _clients = clients;
        _ai = ai;
    }

    [BindProperty] public IngestionMode Mode { get; set; }
    [BindProperty] public int AutoPublishMinConfidence { get; set; }
    [BindProperty] public bool AiEnabled { get; set; }
    [BindProperty] public string? AiEndpoint { get; set; }
    [BindProperty] public string? AiApiKey { get; set; }
    [BindProperty] public string? AiModel { get; set; }
    // AiSystemPrompt is hardcoded (AppSetting.DefaultPrompt) and shown read-only — not bound/editable.
    [BindProperty] public bool AiAutoApprove { get; set; }
    [BindProperty] public bool AiUseProxy { get; set; }
    // Channel scraping sources
    [BindProperty] public bool AutoIngestEnabled { get; set; }
    [BindProperty] public int IngestIntervalMinutes { get; set; } = 30;
    [BindProperty] public bool TelegramEnabled { get; set; }
    [BindProperty] public string? TelegramChannels { get; set; }
    [BindProperty] public bool BaleEnabled { get; set; }
    [BindProperty] public string? BaleBotToken { get; set; }
    [BindProperty] public bool DivarEnabled { get; set; }
    [BindProperty] public string? DivarCity { get; set; }
    [BindProperty] public string? DivarQueries { get; set; }
    [BindProperty] public bool MedjobsEnabled { get; set; }
    [BindProperty] public int MedjobsMaxAds { get; set; } = 40;
    [BindProperty] public bool IranEstekhdamEnabled { get; set; }
    [BindProperty] public int IranEstekhdamMaxAds { get; set; } = 40;
    [BindProperty] public bool IranEstekhdamUseProxy { get; set; }
    [BindProperty] public bool MedboomEnabled { get; set; }
    [BindProperty] public int MedboomMaxAds { get; set; } = 40;
    [BindProperty] public bool MedboomUseProxy { get; set; }
    [BindProperty] public bool SmsEnabled { get; set; }
    [BindProperty] public string? SmsApiKey { get; set; }
    [BindProperty] public string? SmsTemplate { get; set; }
    [BindProperty] public string? SmsSender { get; set; }
    [BindProperty] public string? NeshanMapKey { get; set; }
    [BindProperty] public bool WebNotificationsEnabled { get; set; }
    [BindProperty] public bool PushEnabled { get; set; }
    [BindProperty] public string? VapidPublicKey { get; set; }
    [BindProperty] public string? VapidPrivateKey { get; set; }
    [BindProperty] public string? VapidSubject { get; set; }
    [BindProperty] public string? TestPhone { get; set; }
    [BindProperty] public bool DemoMode { get; set; }
    [BindProperty] public bool WebsitesEnabled { get; set; }
    [BindProperty] public string? WebsiteUrls { get; set; }
    [BindProperty] public string? IngestProxyUrl { get; set; }
    [BindProperty] public bool TelegramUseProxy { get; set; }
    [BindProperty] public bool BaleUseProxy { get; set; }
    [BindProperty] public bool DivarUseProxy { get; set; }
    [BindProperty] public bool MedjobsUseProxy { get; set; }
    [BindProperty] public bool WebsitesUseProxy { get; set; }
    [TempData] public string? Saved { get; set; }
    [TempData] public string? SmsTest { get; set; }
    [TempData] public string? DemoMsg { get; set; }
    [TempData] public string? ProxyTest { get; set; }
    [TempData] public string? AiTest { get; set; }

    public async Task OnGetAsync()
    {
        var s = await _settings.GetAsync();
        Mode = s.Mode;
        AutoPublishMinConfidence = s.AutoPublishMinConfidence;
        AiEnabled = s.AiEnabled;
        AiEndpoint = s.AiEndpoint;
        AiApiKey = s.AiApiKey;
        AiModel = s.AiModel;
        AiAutoApprove = s.AiAutoApprove;
        AiUseProxy = s.AiUseProxy;
        AutoIngestEnabled = s.AutoIngestEnabled;
        IngestIntervalMinutes = s.IngestIntervalMinutes;
        TelegramEnabled = s.TelegramEnabled;
        TelegramChannels = s.TelegramChannels;
        BaleEnabled = s.BaleEnabled;
        BaleBotToken = s.BaleBotToken;
        DivarEnabled = s.DivarEnabled;
        DivarCity = s.DivarCity;
        DivarQueries = s.DivarQueries;
        MedjobsEnabled = s.MedjobsEnabled;
        MedjobsMaxAds = s.MedjobsMaxAds;
        IranEstekhdamEnabled = s.IranEstekhdamEnabled;
        IranEstekhdamMaxAds = s.IranEstekhdamMaxAds;
        IranEstekhdamUseProxy = s.IranEstekhdamUseProxy;
        MedboomEnabled = s.MedboomEnabled;
        MedboomMaxAds = s.MedboomMaxAds;
        MedboomUseProxy = s.MedboomUseProxy;
        SmsEnabled = s.SmsEnabled;
        SmsApiKey = s.SmsApiKey;
        SmsTemplate = s.SmsTemplate;
        SmsSender = s.SmsSender;
        NeshanMapKey = s.NeshanMapKey;
        DemoMode = s.DemoMode;
        WebsitesEnabled = s.WebsitesEnabled;
        WebsiteUrls = s.WebsiteUrls;
        IngestProxyUrl = s.IngestProxyUrl;
        TelegramUseProxy = s.TelegramUseProxy;
        BaleUseProxy = s.BaleUseProxy;
        DivarUseProxy = s.DivarUseProxy;
        MedjobsUseProxy = s.MedjobsUseProxy;
        WebsitesUseProxy = s.WebsitesUseProxy;
        WebNotificationsEnabled = s.WebNotificationsEnabled;
        PushEnabled = s.PushEnabled;
        VapidPublicKey = s.VapidPublicKey;
        VapidPrivateKey = s.VapidPrivateKey;
        VapidSubject = s.VapidSubject;
    }

    public async Task<IActionResult> OnPostAsync()
    {
        await _settings.SaveAsync(new AppSetting
        {
            Mode = Mode,
            AutoPublishMinConfidence = AutoPublishMinConfidence,
            AiEnabled = AiEnabled,
            AiEndpoint = AiEndpoint,
            AiApiKey = AiApiKey,
            AiModel = AiModel,
            // AiSystemPrompt intentionally omitted — AppSetting defaults it to DefaultPrompt (hardcoded).
            AiAutoApprove = AiAutoApprove,
            AiUseProxy = AiUseProxy,
            AutoIngestEnabled = AutoIngestEnabled,
            IngestIntervalMinutes = IngestIntervalMinutes,
            TelegramEnabled = TelegramEnabled,
            TelegramChannels = TelegramChannels,
            BaleEnabled = BaleEnabled,
            BaleBotToken = BaleBotToken,
            DivarEnabled = DivarEnabled,
            DivarCity = DivarCity,
            DivarQueries = DivarQueries,
            MedjobsEnabled = MedjobsEnabled,
            MedjobsMaxAds = MedjobsMaxAds,
            IranEstekhdamEnabled = IranEstekhdamEnabled,
            IranEstekhdamMaxAds = IranEstekhdamMaxAds,
            IranEstekhdamUseProxy = IranEstekhdamUseProxy,
            MedboomEnabled = MedboomEnabled,
            MedboomMaxAds = MedboomMaxAds,
            MedboomUseProxy = MedboomUseProxy,
            SmsEnabled = SmsEnabled,
            SmsApiKey = SmsApiKey,
            SmsTemplate = SmsTemplate,
            SmsSender = SmsSender,
            NeshanMapKey = NeshanMapKey,
            DemoMode = DemoMode,
            WebsitesEnabled = WebsitesEnabled,
            WebsiteUrls = WebsiteUrls,
            IngestProxyUrl = IngestProxyUrl,
            TelegramUseProxy = TelegramUseProxy,
            BaleUseProxy = BaleUseProxy,
            DivarUseProxy = DivarUseProxy,
            MedjobsUseProxy = MedjobsUseProxy,
            WebsitesUseProxy = WebsitesUseProxy,
            WebNotificationsEnabled = WebNotificationsEnabled,
            PushEnabled = PushEnabled,
            VapidPublicKey = VapidPublicKey,
            VapidPrivateKey = VapidPrivateKey,
            VapidSubject = VapidSubject,
        });
        Saved = "تنظیمات ذخیره شد.";
        return RedirectToPage();
    }

    public async Task<IActionResult> OnPostSeedDemoAsync()
    {
        var n = await SeedData.SeedDemoAsync(_db);
        DemoMsg = n > 0 ? $"داده‌های نمونه ثبت شد ({n} مرکز + شیفت/استخدام)." : "داده‌های نمونه از قبل موجود است.";
        return RedirectToPage();
    }

    public async Task<IActionResult> OnPostClearDemoAsync()
    {
        var n = await SeedData.ClearDemoAsync(_db);
        DemoMsg = $"داده‌های نمونه حذف شد ({n} مرکز و آگهی‌های وابسته).";
        return RedirectToPage();
    }

    /// <summary>Check the VPN/proxy is connected by reaching a normally-blocked site through it.</summary>
    public async Task<IActionResult> OnPostTestProxyAsync()
    {
        var s = await _settings.GetAsync();
        if (string.IsNullOrWhiteSpace(s.IngestProxyUrl))
        { ProxyTest = "ابتدا آدرس پروکسی را وارد و ذخیره کن."; return RedirectToPage(); }

        var client = _clients.For(s, useProxy: true);
        var sw = System.Diagnostics.Stopwatch.StartNew();
        try
        {
            // api.telegram.org is filtered in Iran — a reply means the tunnel reaches the open internet.
            using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(15));
            using var resp = await client.GetAsync("https://api.telegram.org",
                HttpCompletionOption.ResponseHeadersRead, cts.Token);
            sw.Stop();
            ProxyTest = $"✅ پروکسی وصل است — به اینترنت آزاد دسترسی دارد (HTTP {(int)resp.StatusCode}، {sw.ElapsedMilliseconds} میلی‌ثانیه).";
        }
        catch (Exception ex)
        {
            ProxyTest = "❌ اتصال از طریق پروکسی ناموفق بود. مطمئن شو سرویس Xray اجراست و کانفیگ معتبر است. خطا: " + ex.Message;
        }
        return RedirectToPage();
    }

    /// <summary>Send a sample post to the AI endpoint and show the verdict (validates key/endpoint/proxy).</summary>
    public async Task<IActionResult> OnPostTestAiAsync()
    {
        var s = await _settings.GetAsync();
        if (!s.AiEnabled || string.IsNullOrWhiteSpace(s.AiEndpoint))
        { AiTest = "ابتدا «فعال‌سازی هوش مصنوعی» را بزن و آدرس/کلید را ذخیره کن."; return RedirectToPage(); }

        const string sample = "استخدام پرستار خانم برای بخش اورژانس بیمارستان میلاد تهران، شیفت شب، حقوق توافقی، تماس ۰۹۱۲۱۲۳۴۵۶۷";
        // TestAsync runs the real call and returns the exact reason on failure (HTTP status,
        // response body, network/proxy error) — unlike AuditAsync, which swallows errors to null.
        AiTest = await _ai.TestAsync(sample, s);
        return RedirectToPage();
    }

    public async Task<IActionResult> OnPostTestSmsAsync()
    {
        var s = await _settings.GetAsync();
        var phone = OtpService.Normalize(TestPhone ?? "");
        if (phone.Length < 10) { SmsTest = "شماره معتبر وارد کنید."; return RedirectToPage(); }
        if (!s.SmsEnabled) { SmsTest = "ابتدا SMS را فعال و ذخیره کنید."; return RedirectToPage(); }
        try
        {
            var ok = await _sms.SendOtpAsync(phone, Random.Shared.Next(10000, 100000).ToString(), s);
            SmsTest = ok ? $"پیامک آزمایشی به {phone} ارسال شد." : "ارسال ناموفق بود (پاسخ منفی از سرویس).";
        }
        catch (Exception ex) { SmsTest = "خطا در ارسال: " + ex.Message; }
        return RedirectToPage();
    }
}
