using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using PhoneToolMX.Data;
using PhoneToolMX.Models;
using System.Net.NetworkInformation;
using System.Text.RegularExpressions;

namespace PolyProv.Controllers
{
    public class ConfigController : Controller
    {
        private PTMXContext _ctx;
        private static Regex userConf = new Regex("^([0-9a-fA-F]{12})-user$");
        private static Regex initConf = new Regex("^([0-9a-fA-F]{12})$");
        private static Regex sipConf = new Regex("^([0-9a-fA-F]{12})-sip$");
        
        /// <summary>
        /// Gets a <see cref="Phone" /> by its MAC Address.
        /// </summary>
        /// <param name="addr">The MAC address of the phone</param>
        /// <returns>The <see cref="Phone"/> with the given MAC, or null if none was found</returns>
        private Phone? GetByMacStr(string addr)
        {
            if (!PhysicalAddress.TryParse(addr, out var parsed)) return null;
            return _ctx.Phones
                .Include(m => m.Extensions)
                .Include(m => m.Model)
                .FirstOrDefault(p => p.MacAddress.Equals(parsed));
        }

        public ConfigController(PTMXContext context)
        {
            _ctx = context;
        }

        [HttpGet("{param}.cfg")]
        public IActionResult GetConfig(string param)
        {
            return param switch
            {
                _ when initConf.Match(param) is { Success: true } match => InitSettings(match.Groups[1].Value),
                _ when userConf.Match(param) is { Success: true } match => PhoneSettings(match.Groups[1].Value),
                _ when sipConf.Match(param) is { Success: true } match => SipSettings(match.Groups[1].Value),
                _ => NotFound(),
            };
        }
        
        public IActionResult InitSettings(string addr)
        {
            var phone = GetByMacStr(addr);
            return phone != null ? View("Init", phone) : NotFound();
        }
        
        public IActionResult PhoneSettings(string addr)
        {
            var phone = GetByMacStr(addr);
            
            // ReSharper disable once InvertIf
            if (phone?.PrimaryExtension is {} primary && phone.Extensions.FirstOrDefault() != primary) {
                // primary extension exists and is not first, reorder so it's first
                phone.Extensions.Remove(primary);
                phone.Extensions = phone.Extensions.Prepend(primary).ToList();
            }
            
            return phone != null ? View("Phone", phone) : NotFound();
        }
        
        public IActionResult SipSettings(string addr)
        {
            var phone = GetByMacStr(addr);
            return phone != null ? View("Sip", phone) : NotFound();
        }

        [HttpGet("000000000000-directory.xml")]
        public IActionResult ExtDirectory()
        {
            var extensions = _ctx.Extensions.Where(x => x.Listed == true);
            return View("Directory", extensions.ToList());
        }
    }
}