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 PostShiftModel : PageModel
{
    private readonly AppDbContext _db;
    private readonly CaptchaService _captcha;
    private readonly SubmissionGuard _guard;
    private readonly NotificationService _notify;

    public PostShiftModel(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 string? CaptchaToken { get; set; }
    [BindProperty] public string? CaptchaAnswer { get; set; }

    [BindProperty] public int FacilityId { get; set; }
    [BindProperty] public int RoleId { get; set; }
    [BindProperty] public DateOnly Date { get; set; }
    [BindProperty] public ShiftType ShiftType { get; set; }
    [BindProperty] public TimeOnly StartTime { get; set; }
    [BindProperty] public TimeOnly EndTime { get; set; }
    [BindProperty] public long? PayAmount { get; set; }
    [BindProperty] public int? SharePercent { get; set; }   // سهم درآمد (٪)
    [BindProperty] public bool Negotiable { get; set; }
    [BindProperty] public Gender GenderRequirement { get; set; }
    [BindProperty] public string? Description { get; set; }

    public async Task OnGetAsync()
    {
        await LoadListsAsync();
        Date = DateOnly.FromDateTime(DateTime.UtcNow).AddDays(1);
        StartTime = new TimeOnly(8, 0);
        EndTime = new TimeOnly(14, 0);
        NewCaptcha();
    }

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

        if (!_captcha.Verify(CaptchaToken, CaptchaAnswer))
        { Error = "پاسخ سؤال امنیتی نادرست است."; NewCaptcha(); return Page(); }

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

        if (SubmissionGuard.ContainsSpam(Description))
        { Error = "متن شیفت تبلیغاتی/نامعتبر به‌نظر می‌رسد."; NewCaptcha(); return Page(); }

        if (await _guard.DuplicateShiftAsync(FacilityId, RoleId, Date, StartTime, ShiftType))
        { Error = "این شیفت (همان مرکز، نقش، تاریخ و ساعت) قبلاً ثبت شده است."; NewCaptcha(); return Page(); }

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

        var role = await _db.Roles.FindAsync(RoleId);
        var shift = new Shift
        {
            FacilityId = FacilityId,
            RoleId = RoleId,
            Date = Date,
            StartTime = StartTime,
            EndTime = EndTime,
            ShiftType = ShiftType,
            SpecialtyRequired = role?.Name ?? "",
            Description = Description,
            PayType = Negotiable ? PayType.Negotiable
                : (PayAmount is null && SharePercent is not null ? PayType.Percentage : PayType.PerShift),
            PayAmount = Negotiable ? null : PayAmount,
            SharePercent = Negotiable ? null : SharePercent,
            GenderRequirement = GenderRequirement,
            Status = ShiftStatus.Open,
            Source = ShiftSource.Direct, // posted directly by the facility
        };
        _db.Shifts.Add(shift);
        await _db.SaveChangesAsync();
        await _notify.NotifyNewShiftAsync(shift.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;
    }
}
