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 System.IO;

namespace rockfishCore.Controllers
{
    [Produces("application/json")]
    [Route("api/Purchase")]
    [Authorize]
    public class PurchaseController : Controller
    {
        private readonly rockfishContext _context;

        public PurchaseController(rockfishContext context)
        {
            _context = context;
        }

        //Get unique product code / name combinations
        [HttpGet("productcodes")]
        public JsonResult GetUniqueProductCodes()
        {
            //Note: will return dupes as comparer sees misspellings as unique in name, but I'm keeping it that way 
            //so the name misspellings are apparent and can be fixed up
            var l = _context.Purchase.Select(p => new { p.ProductCode, p.Name }).Distinct().OrderBy(p => p.ProductCode);
            return Json(l);
        }

        // GET: api/Purchase
        [HttpGet]
        public IEnumerable<Purchase> GetPurchase()
        {
            return _context.Purchase;
        }

        // GET: api/Purchase/5
        [HttpGet("{id}")]
        public async Task<IActionResult> GetPurchase([FromRoute] long id)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            var purchase = await _context.Purchase.SingleOrDefaultAsync(m => m.Id == id);

            if (purchase == null)
            {
                return NotFound();
            }

            return Ok(purchase);
        }

        // PUT: api/Purchase/5
        [HttpPut("{id}")]
        public async Task<IActionResult> PutPurchase([FromRoute] long id, [FromBody] Purchase purchase)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            if (id != purchase.Id)
            {
                return BadRequest();
            }

            _context.Entry(purchase).State = EntityState.Modified;

            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!PurchaseExists(id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }
           // updateCustomerActive(purchase.CustomerId);
             ParseOrderAndUpdateEmail(purchase);
            return NoContent();
        }

        // POST: api/Purchase
        [HttpPost]
        public async Task<IActionResult> PostPurchase([FromBody] Purchase purchase)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            _context.Purchase.Add(purchase);
            await _context.SaveChangesAsync();

           // updateCustomerActive(purchase.CustomerId);
            ParseOrderAndUpdateEmail(purchase);

            return CreatedAtAction("GetPurchase", new { id = purchase.Id }, purchase);
        }

        // DELETE: api/Purchase/5
        [HttpDelete("{id}")]
        public async Task<IActionResult> DeletePurchase([FromRoute] long id)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            var purchase = await _context.Purchase.SingleOrDefaultAsync(m => m.Id == id);
            if (purchase == null)
            {
                return NotFound();
            }
            var customerId = purchase.CustomerId;

            _context.Purchase.Remove(purchase);
            await _context.SaveChangesAsync();

            //removed, now have the concept of lapsed so active should be in manual control
            //
           // updateCustomerActive(customerId);
            return Ok(purchase);
        }

        private bool PurchaseExists(long id)
        {
            return _context.Purchase.Any(e => e.Id == id);
        }

        // //check if customer has any active subs and flag accordingly
        // private void updateCustomerActive(long customerId)
        // {
        //     var cust = _context.Customer.First(m => m.Id == customerId);
        //     bool active = hasActiveSubs(customerId);
        //     if (cust.Active != active)
        //     {
        //         cust.Active = active;
        //         _context.Customer.Update(cust);
        //         _context.SaveChanges();
        //     }
        // }

        // //check if a customer has active subscriptions
        // private bool hasActiveSubs(long customerId)
        // {
        //     return _context.Purchase.Where(m => m.CustomerId == customerId && m.CancelDate == null).Count() > 0;
        // }



        private void ParseOrderAndUpdateEmail(Purchase purchase)
        {
            Dictionary<string, string> d = ParseShareItOrderData(purchase.Notes);
            if (d.Count < 1)
                return;

            if (d.ContainsKey("E-Mail"))
            {
                string email = d["E-Mail"];
                if (!string.IsNullOrWhiteSpace(email))
                {
                    //append or set it to the customer adminAddress if it isn't already present there
                    //in this way the last address listed is the most recent purchase address there
                    var cust = _context.Customer.First(m => m.Id == purchase.CustomerId);
                    Util.CustomerUtils.AddAdminEmailIfNotPresent(cust, email);
                    _context.SaveChanges();
                }
            }
        }


        /// <summary>
        /// parse out the x=y values in a ShareIt order document
        /// </summary>
        /// <param name="order"></param>
        /// <returns></returns>
        Dictionary<string, string> ParseShareItOrderData(string order)
        {
            Dictionary<string, string> ret = new Dictionary<string, string>();

            if (!string.IsNullOrWhiteSpace(order))
            {
                //parse the email address out of the order
                StringReader sr = new StringReader(order);
                string aLine = string.Empty;
                while (true)
                {
                    aLine = sr.ReadLine();
                    if (aLine != null)
                    {
                        if (aLine.Contains("="))
                        {
                            string[] item = aLine.Split("=");
                            ret.Add(item[0].Trim(), item[1].Trim());
                        }

                    }
                    else
                    {
                        break;
                    }
                }
            }
            return ret;
        }
        /*
                    Original JS code for this from client end of things:
                     // Loop through all lines
            for (var j = 0; j < lines.length; j++) {
              var thisLine = lines[j];
              if (thisLine.includes("=")) {
                var thisElement = thisLine.split("=");
                purchaseData[thisElement[0].trim()] = thisElement[1].trim();
              }
            }

            //Now have an object with the value pairs in it
            if (purchaseData["ShareIt Ref #"]) {
              $("#salesOrderNumber").val(purchaseData["ShareIt Ref #"]);
            }

            // if (purchaseData["E-Mail"]) {
            //   $("#email").val(purchaseData["E-Mail"]);
            // }


                     */





    }//eoc
}//eons