using Azure.Core;
using LSFE.Domain.Contracts;
using LSFE.Infrastructure.Dto;
using LSFE.Infrastructure.Entities;
using LSFE.Infrastructure.Entities.Auth;
using LSFE.Infrastructure.Model.Admin;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace LSFE.API.Controllers.Admin
{
    public class AdminController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        public readonly UserManager<AppsUsers> _userManager;
        public readonly SignInManager<AppsUsers> _signInManager;
        public readonly IAccountService _accountService;
        public AdminController(IUnitOfWork unitOfWork, IWebHostEnvironment env,
            IAccountService accountService, UserManager<AppsUsers> userManager, 
            SignInManager<AppsUsers> signInManager) 
            : base(unitOfWork, env)
        {
            _unitOfWork = unitOfWork;
            _accountService = accountService;
            _userManager = userManager;
            _signInManager = signInManager;
        }
        [HttpPost("VerifyAdmin")]
        public async Task<IActionResult> VerifyAdmin([FromBody] AdminVerificationRequest request)
        {
            if (request == null || string.IsNullOrWhiteSpace(request.AdminUserName))
            {
                return Ok(new AdminVerificationResponse
                {
                    Success = false,
                    Message = "Invalid request.",
                    MessCode = 0
                });
            }

            try
            {
                var userName = request.AdminUserName.Trim().ToLowerInvariant();
                var user = await _userManager.FindByNameAsync(userName);

                if (user == null)
                {
                    return Ok(new AdminVerificationResponse
                    {
                        Success = false,
                        Message = "Invalid username.",
                        MessCode = 0
                    });
                }

                var signInResult = await _signInManager
                    .CheckPasswordSignInAsync(user, request.AdminPassword, lockoutOnFailure: false);

                if (!signInResult.Succeeded)
                {
                    return Ok(new AdminVerificationResponse
                    {
                        Success = false,
                        Message = "Invalid admin password or you have no permission!",
                        MessCode = 0
                    });
                }

                // Direct role check (no need to query all roles)
                var isAdmin = await _userManager.IsInRoleAsync(user, "Admin");

                if (!isAdmin)
                {
                    return Ok(new AdminVerificationResponse
                    {
                        Success = false,
                        Message = "Invalid admin password or you have no permission!",
                        MessCode = 0
                    });
                }

                return Ok(new AdminVerificationResponse
                {
                    Success = true,
                    Message = "AdminRole",
                    MessCode = 1
                });
            }
            catch (Exception ex)
            {
                return Ok(new AdminVerificationResponse
                {
                    Success = false,
                    Message = ex.Message,
                    MessCode = 0
                });
            }
        }

        [HttpPost("RegisterDevice")]
        public async Task<IActionResult> RegisterDevice([FromBody] DeviceRegistrationRequest request)
        {
            if (request == null || string.IsNullOrWhiteSpace(request.MedRepUsername))
            {
                return Ok(new AdminVerificationResponse
                {
                    Success = false,
                    Message = "Invalid request.",
                    MessCode = 0
                });
            }

            try
            {
                var userName = request.MedRepUsername.Trim().ToLowerInvariant();
                var user = await _userManager.FindByNameAsync(userName);

                if (user == null)
                {
                    return Ok(new AdminVerificationResponse
                    {
                        Success = false,
                        Message = "Invalid username.",
                        MessCode = 0
                    });
                }

                var signInResult = await _signInManager
                    .CheckPasswordSignInAsync(user, request.MedRepPassword, lockoutOnFailure: false);

                if (!signInResult.Succeeded)
                {
                    return Unauthorized("Invalid username or password.");
                }

                // 1. Check if device is already registered to another active user
                var deviceInUse = await _unitOfWork.UserDevices.AnyAsync(d =>
                    d.DeviceId == request.DeviceId &&
                    d.IsActive &&
                    d.UserId != user.Id);

                if (deviceInUse)
                {
                    return Ok(new AdminVerificationResponse
                    {
                        Success = false,
                        Message = "This device is already registered to another user.",
                        MessCode = 0
                    });
                }

                // 2. Deactivate existing active devices for this user
                var activeDevices = await _unitOfWork.UserDevices
                    .FindAllAsync(d => d.UserId == user.Id && d.IsActive);

                foreach (var device in activeDevices)
                {
                    device.IsActive = false;
                    device.IsAuthorized = false;
                    device.DeactivatedDate = DateTime.UtcNow;
                    device.DeactivatedBy = "Admin Registration";
                    device.DeactivationReason = "New device registered by admin";
                }

                // 3. Register new device
                var newDevice = new Infrastructure.Entities.Admin.UserDevice
                {
                    UserId = user.Id,
                    DeviceId = request.DeviceId,
                    DeviceModel = request.DeviceModel,
                    DevicePlatform = request.DevicePlatform,
                    DeviceVersion = request.DeviceVersion,
                    DeviceManufacturer = request.DeviceManufacturer,
                    AppVersion = request.AppVersion,
                    IsAuthorized = true,
                    IsActive = true,
                    RegisteredDate = DateTime.UtcNow,
                    RegisteredBy = "Admin",
                    Notes = $"Registered by admin for {request.MedRepUsername}"
                };

                var result = await _unitOfWork.UserDevices.AddOrUpdateAsync(newDevice);

                if (!result.Success)
                {
                    return Ok(new AdminVerificationResponse
                    {
                        Success = false,
                        Message = result.Message ?? "Failed to register device.",
                        MessCode = 0
                    });
                }

                await _unitOfWork.SaveChangesAsync();

                return Ok(new DeviceRegistrationResponse
                {
                    Success = true,
                    Message = "Device registered successfully.",
                    UserId = user.Id,
                    DeviceId = request.DeviceId,
                    RegisteredDate = newDevice.RegisteredDate
                });
            }
            catch (Exception ex)
            {
                return Ok(new AdminVerificationResponse
                {
                    Success = false,
                    Message = ex.Message,
                    MessCode = 0
                });
            }
        }

        [HttpPost("CheckDevice")]
        public async Task<IActionResult> CheckDevice([FromBody] DeviceInfo deviceInfo)
        {
            try
            {
                var user = await _userManager.Users
                    .FirstOrDefaultAsync(u => u.UserName == deviceInfo.UserName);

                if (user == null)
                {
                    return NotFound(new { message = "User not found" });
                }

                var devices = await _unitOfWork.UserDevices.
                    AnyAsync(d => d.UserId == user.Id && d.DeviceId == deviceInfo.DeviceId);
                if (!devices)
                {
                    return Ok(new DeviceRegistrationResponse
                    {
                        Success = false,
                        Message = "No record yet for this device.",
                        UserId = user.Id
                    });
                }
                else
                return Ok(new DeviceRegistrationResponse
                {
                    Success = true,
                    Message = "Device is registered.",
                    UserId = user.Id,
                    RegisteredDate = DateTime.UtcNow
                });
            }
            catch (Exception ex)
            {
                return StatusCode(500, new { message = "An error occurred" });
            }
        }

        #region Helper Methods
        private async Task SendDeviceRegistrationEmailAsync(string email, string deviceModel)
        {
            // Implement email notification
            // Example:
            // await _emailService.SendAsync(
            //     to: email,
            //     subject: "Device Registered - LSFE MobApp",
            //     body: $"Your device ({deviceModel}) has been registered successfully."
            // );

            await Task.CompletedTask;
        }

        #endregion
    }
}