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

namespace JobsMedical.Web.Pages.Account;

[Authorize]
public class ProfileModel : PageModel
{
    private readonly AppDbContext _db;
    public ProfileModel(AppDbContext db) => _db = db;

    public User? CurrentUser { get; private set; }
    public List<Shift> SavedShifts { get; private set; } = new();
    public List<JobOpening> AppliedJobs { get; private set; } = new();
    public List<Shift> AppliedShifts { get; private set; } = new();

    public async Task OnGetAsync()
    {
        var userId = int.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)!);
        CurrentUser = await _db.Users.FindAsync(userId);

        // All visitor ids this account has been linked to (across devices).
        var visitorIds = await _db.Visitors.Where(v => v.UserId == userId).Select(v => v.Id).ToListAsync();

        var events = await _db.InterestEvents
            .Where(e => visitorIds.Contains(e.VisitorId))
            .OrderByDescending(e => e.CreatedAt)
            .ToListAsync();

        var savedShiftIds = events.Where(e => e.EventType == InterestEventType.Save && e.ShiftId != null)
            .Select(e => e.ShiftId!.Value).Distinct().ToList();
        var appliedShiftIds = events.Where(e => e.EventType == InterestEventType.Apply && e.ShiftId != null)
            .Select(e => e.ShiftId!.Value).Distinct().ToList();
        var appliedJobIds = events.Where(e => e.EventType == InterestEventType.Apply && e.JobOpeningId != null)
            .Select(e => e.JobOpeningId!.Value).Distinct().ToList();

        SavedShifts = await ShiftsByIds(savedShiftIds);
        AppliedShifts = await ShiftsByIds(appliedShiftIds);
        AppliedJobs = await _db.JobOpenings
            .Include(j => j.Facility).ThenInclude(f => f.City).Include(j => j.Role)
            .Where(j => appliedJobIds.Contains(j.Id)).ToListAsync();
    }

    private Task<List<Shift>> ShiftsByIds(List<int> ids) => _db.Shifts
        .Include(s => s.Facility).ThenInclude(f => f.City)
        .Include(s => s.Facility).ThenInclude(f => f.District)
        .Include(s => s.Role)
        .Where(s => ids.Contains(s.Id)).ToListAsync();
}
