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

namespace JobsMedical.Web.Pages.Account;

public class LoginModel : PageModel
{
    private readonly AppDbContext _db;
    private readonly OtpService _otp;
    private readonly VisitorContext _visitor;
    private readonly IConfiguration _config;

    public LoginModel(AppDbContext db, OtpService otp, VisitorContext visitor, IConfiguration config)
    {
        _db = db;
        _otp = otp;
        _visitor = visitor;
        _config = config;
    }

    [BindProperty] public string Phone { get; set; } = "";
    [BindProperty] public string? Code { get; set; }
    /// <summary>"employee" (کادر درمان) or "employer" (کارفرما/مرکز) — only used when creating a new account.</summary>
    [BindProperty] public string AccountType { get; set; } = "employee";

    public bool CodeSent { get; private set; }
    public string? DevCode { get; private set; }   // shown only in dev (no SMS gateway yet)
    public string? Error { get; private set; }

    public void OnGet() { }

    public async Task<IActionResult> OnPostRequestCodeAsync()
    {
        var phone = OtpService.Normalize(Phone);
        if (phone.Length < 10)
        {
            Error = "شماره موبایل معتبر وارد کنید.";
            return Page();
        }
        Phone = phone;
        DevCode = await _otp.IssueAsync(phone);   // null when SMS is enabled (sent via gateway)
        CodeSent = true;
        return Page();
    }

    public async Task<IActionResult> OnPostVerifyAsync(string? returnUrl)
    {
        var phone = OtpService.Normalize(Phone);
        if (!_otp.Verify(phone, Code ?? ""))
        {
            Error = "کد واردشده نادرست یا منقضی شده است.";
            CodeSent = true;
            return Page();
        }

        // Find or create the user. The configured admin phone is granted the Admin role.
        var user = await _db.Users.FirstOrDefaultAsync(u => u.Phone == phone);
        if (user is { IsBanned: true })
        {
            Error = "حساب شما مسدود شده است." + (string.IsNullOrWhiteSpace(user.BanReason) ? "" : $" ({user.BanReason})");
            return Page();
        }
        var isAdmin = phone == OtpService.Normalize(_config["Auth:AdminPhone"] ?? "");
        var isEmployer = string.Equals(AccountType, "employer", StringComparison.OrdinalIgnoreCase);
        if (user is null)
        {
            // New account: the chosen type decides the role (employer → facility panel).
            user = new User
            {
                Phone = phone,
                IsPhoneVerified = true,
                Role = isAdmin ? UserRole.Admin
                     : isEmployer ? UserRole.FacilityAdmin
                     : UserRole.Doctor,
            };
            _db.Users.Add(user);
        }
        else
        {
            user.IsPhoneVerified = true;
            if (isAdmin) user.Role = UserRole.Admin;
        }
        await _db.SaveChangesAsync();

        // Link the anonymous visitor (and its interest history) to this account.
        var vid = _visitor.VisitorId;
        if (!string.IsNullOrEmpty(vid))
        {
            var visitor = await _db.Visitors.FirstOrDefaultAsync(v => v.Id == vid);
            if (visitor is null) { visitor = new Visitor { Id = vid }; _db.Visitors.Add(visitor); }
            visitor.UserId = user.Id;
            await _db.SaveChangesAsync();
        }

        await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
            AuthHelper.BuildPrincipal(user));

        if (!string.IsNullOrEmpty(returnUrl)) return LocalRedirect(returnUrl);
        // Route to the right panel for the account type.
        return user.Role switch
        {
            UserRole.Admin => RedirectToPage("/Admin/Overview"),
            UserRole.FacilityAdmin => RedirectToPage("/Employer/Index"),
            _ => RedirectToPage("/Me/Index"),
        };
    }
}
