using System.Security.Claims;
using JobsMedical.Web.Data;
using JobsMedical.Web.Models;
using JobsMedical.Web.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;

namespace JobsMedical.Web.Pages.Employer;

[Authorize]
public class PostJobModel : PageModel
{
    private readonly AppDbContext _db;
    private readonly CaptchaService _captcha;
    private readonly SubmissionGuard _guard;
    private readonly NotificationService _notify;

    public PostJobModel(AppDbContext db, CaptchaService captcha, SubmissionGuard guard, NotificationService notify)
    {
        _db = db;
        _captcha = captcha;
        _guard = guard;
        _notify = notify;
    }

    public List<Facility> MyFacilities { get; private set; } = new();
    public List<Role> Roles { get; private set; } = new();
    public string? Error { get; private set; }
    public string CaptchaQuestion { get; private set; } = "";

    [BindProperty] public int FacilityId { get; set; }
    [BindProperty] public int RoleId { get; set; }
    [BindProperty] public string Title { get; set; } = "";
    [BindProperty] public EmploymentType EmploymentType { get; set; }
    [BindProperty] public long? SalaryMin { get; set; }
    [BindProperty] public long? SalaryMax { get; set; }
    [BindProperty] public bool Negotiable { get; set; }
    [BindProperty] public Gender GenderRequirement { get; set; }
    [BindProperty] public string? Description { get; set; }
    [BindProperty] public string? Requirements { get; set; }
    [BindProperty] public string? CaptchaToken { get; set; }
    [BindProperty] public string? CaptchaAnswer { get; set; }

    public async Task OnGetAsync() { await LoadListsAsync(); NewCaptcha(); }

    public async Task<IActionResult> OnPostAsync()
    {
        await LoadListsAsync();

        // 1. Bot gate — built-in captcha.
        if (!_captcha.Verify(CaptchaToken, CaptchaAnswer))
        { Error = "پاسخ سؤال امنیتی نادرست است."; NewCaptcha(); return Page(); }

        if (!MyFacilities.Any(f => f.Id == FacilityId))
        { Error = "این مرکز متعلق به شما نیست."; NewCaptcha(); return Page(); }
        if (string.IsNullOrWhiteSpace(Title)) { Error = "عنوان موقعیت الزامی است."; NewCaptcha(); return Page(); }

        // 2. Garbage screen.
        if (SubmissionGuard.LooksLikeGarbage(Title, Description))
        { Error = "متن آگهی نامعتبر یا تبلیغاتی به‌نظر می‌رسد."; NewCaptcha(); return Page(); }

        // 3. Duplicate position.
        if (await _guard.DuplicateJobAsync(FacilityId, RoleId, Title))
        { Error = "این موقعیت استخدامی قبلاً برای این مرکز ثبت شده است."; NewCaptcha(); return Page(); }

        // 4. Flood protection — hourly posting cap.
        var uid = int.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)!);
        if (await _guard.PostingRateExceededAsync(uid))
        { Error = $"در یک ساعت اخیر بیش از حد مجاز ({SubmissionGuard.MaxListingsPerHour}) آگهی ثبت کرده‌اید. بعداً تلاش کنید."; NewCaptcha(); return Page(); }

        var job = new JobOpening
        {
            FacilityId = FacilityId,
            RoleId = RoleId,
            Title = Title.Trim(),
            EmploymentType = EmploymentType,
            SalaryMin = Negotiable ? null : SalaryMin,
            SalaryMax = Negotiable ? null : SalaryMax,
            GenderRequirement = GenderRequirement,
            Description = Description,
            Requirements = Requirements,
            Status = ShiftStatus.Open,
            Source = ShiftSource.Direct,
        };
        _db.JobOpenings.Add(job);
        await _db.SaveChangesAsync();
        await _notify.NotifyNewJobAsync(job.Id);   // notify matching staff
        return RedirectToPage("/Employer/Index");
    }

    private async Task LoadListsAsync()
    {
        var userId = int.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)!);
        MyFacilities = await _db.Facilities.Include(f => f.City)
            .Where(f => f.OwnerUserId == userId).OrderBy(f => f.Name).ToListAsync();
        Roles = await _db.Roles.Where(r => r.IsActive).OrderBy(r => r.SortOrder).ToListAsync();
    }

    private void NewCaptcha()
    {
        var (q, token) = _captcha.Create();
        CaptchaQuestion = q;
        CaptchaToken = token;
    }
}
