using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using Microsoft.EntityFrameworkCore;
using rockfishCore.Models;
using rockfishCore.Util;
using System.ComponentModel.DataAnnotations;

namespace rockfishCore.Controllers
{
    //### OUR ROUTE CALLED FROM ROCKFISH CLIENT ####
    [Produces("application/json")]
    [Route("api/rvl")]
    [Authorize]
    public class RvlController : Controller
    {
        private readonly rockfishContext ct;


        public RvlController(rockfishContext context)
        {
            ct = context;
        }

        public class dtoRavLicense
        {
            [Required]
            public string RegisteredTo { get; set; }
            [Required]
            public string DbId { get; set; }
            [Required]
            public bool Perpetual { get; set; }
            [Required]
            public bool LicenseExpires { get; set; }
            [Required]
            public long LicenseExpirationDate { get; set; }
            [Required]
            public long MaintenanceExpirationDate { get; set; }
            [Required]
            public List<dtoLicenseFeature> Features { get; set; }
            [Required]
            public long SiteId { get; set; }
        }
        public class dtoLicenseFeature
        {
            dtoLicenseFeature()
            {
                Count = 0;
            }
            //name of feature / product
            public string Feature { get; set; }
            //Optional count for items that require it
            public long Count { get; set; }
        }


        // #if (DEBUG)
        //         private const string LICENSE_SERVER_URL = "http://localhost:3001/";
        //         public const string SUPPORT_EMAIL = "cardjohn@ayanova.com";
        // #else
        //         private const string LICENSE_SERVER_URL = "https://rockfish.ayanova.com/";
        //         public const string SUPPORT_EMAIL="support@ayanova.com";
        // #endif

        [HttpPost]
        public async Task<IActionResult> Post([FromBody] dtoRavLicense l)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }


            //Get customer from site id
            var CustomerId = await ct.Site.AsNoTracking().Where(z => z.Id == l.SiteId).Select(z => z.CustomerId).FirstOrDefaultAsync();

            if (CustomerId == 0)
            {
                return BadRequest($"Customer could not be found for site id {l.SiteId}");
            }

            var Customer = await ct.Customer.AsNoTracking().Where(z => z.Id == CustomerId).FirstOrDefaultAsync();
            if (Customer == null)
            {
                return BadRequest($"Customer could not be found for customer id {CustomerId}");
            }

            if (string.IsNullOrWhiteSpace(Customer.AdminEmail))
            {
                return BadRequest($"Customer does not have an Admin / License email address, no where to send key");
            }

            if (!Customer.Active)
            {
                return BadRequest($"Customer {Customer.Name} is not Active, set to active and try again");
            }

            if (Customer.DoNotContact)
            {
                return BadRequest($"Customer {Customer.Name} is set to DO NOT CONTACT, unable to process and send key");
            }

            try
            {
                var newLicense = new RavenKeyFactory.AyaNovaLicenseKey();

                newLicense.RegisteredTo = l.RegisteredTo;
                newLicense.DbId = l.DbId;
                if (l.LicenseExpires)
                    newLicense.LicenseExpiration = DateUtil.EpochToDate(l.LicenseExpirationDate);
                else
                    newLicense.LicenseExpiration = DateUtil.EmptyDateValue;
                newLicense.MaintenanceExpiration = DateUtil.EpochToDate(l.MaintenanceExpirationDate);
                foreach (dtoLicenseFeature f in l.Features)
                {
                    newLicense.Features.Add(new RavenKeyFactory.LicenseFeature() { Feature = f.Feature, Count = f.Count });
                }

                //Everything seems to be in order generate the license, save it and send it

                var Key = RavenKeyFactory.GenerateRavenKey(newLicense);

                //save it to the database
                var DBLicense = new License();
                DBLicense.CustomerId = CustomerId;
                DBLicense.SiteId = l.SiteId;
                DBLicense.Email = Customer.AdminEmail;
                DBLicense.DbId = l.DbId;
                DBLicense.Perpetual = l.Perpetual;
                DBLicense.Code = "na";
                DBLicense.Key = Key;
                DBLicense.RegTo = l.RegisteredTo;
                DBLicense.DtLicenseExpiration = l.LicenseExpirationDate;
                DBLicense.DtMaintenanceExpiration = l.MaintenanceExpirationDate;
                await ct.License.AddAsync(DBLicense);
                await ct.SaveChangesAsync();

                //Key generated, record saved successfully
                //If key is not revoked (don't warn them in that case) send notification to customer
                if (l.RegisteredTo != RavenKeyFactory.REVOKED_TOKEN)
                {

                    var body = $"Thank you for your purchase!\nYour AyaNova license key is ready to be installed.\nAyaNova will fetch it automatically within 24 hours or you can force it to fetch immediately from the License page in AyaNova now.\n---\n{newLicense}";
                    //send license email
#if (DEBUG)
                    RfMail.SendMessage("support@ayanova.com", "cardjohn@ayanova.com", "AyaNova license key", body, false);
#else
//throw new System.Exception("UNCOMMENT THIS FOR PRODUCTION");
                RfMail.SendMessage("support@ayanova.com", Customer.AdminEmail, "AyaNova license key", body, false);
#endif

                }
                return Ok("ok");
            }
            catch (Exception ex)
            {
                return StatusCode(500, $"Exception processing request: {ex.Message}");
            }
        }


        [HttpGet("list/{siteId}")]
        public async Task<IActionResult> GetList([FromRoute] long siteId)
        {
            return Ok(await ct.License.AsNoTracking().Where(z => z.SiteId == siteId).OrderByDescending(z => z.Id).ToListAsync());
        }




    }//eoc
}//eons