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.Security.Claims;

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

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

        //Get api/rfcase/list       
        [HttpGet("list")]
        public JsonResult GetList(long? Project, bool? Open, int? Priority, string Search)
        {
            //NOTE: Unlike FogBugz, does not open a case directly from the search
            //uses a separate route (simple get), so this route doesn't need to worry about it.


            //FILTERS
            var cases = _context.RfCase.AsQueryable();


            //TODO: this is case sensitive currently
            //need to figure out a way to make it insensitive
            if (!string.IsNullOrWhiteSpace(Search))
            {
                cases = _context.RfCase.Where(s => s.Notes.Contains(Search)
                                           || s.ReleaseNotes.Contains(Search)
                                           || s.ReleaseVersion.Contains(Search)
                                           || s.Title.Contains(Search)
                                           );
            }

            //project
            if (Project != null && Project != 0)
            {
                cases = cases.Where(s => s.RfCaseProjectId == Project);
            }

            //open
            if (Open != null)
            {
                if (Open == true)
                {
                    cases = cases.Where(s => s.DtClosed == null);
                }
                else
                {
                    cases = cases.Where(s => s.DtClosed != null);
                }
            }

            //priority
            if (Priority != null && Priority > 0 && Priority < 6)
            {
                cases = cases.Where(s => s.Priority == Priority);

            }

            cases = cases.OrderBy(s => s.Priority).ThenByDescending(s => s.Id);
            return new JsonResult(cases);
        }



        // //Get api/rfcase/77/attachments
        // [HttpGet("{id}/attachments")]
        // public IEnumerable<dtoNameIdItem> GetAttachmentList([FromRoute] long id)
        // {
        //     var res = from c in _context.RfCaseBlob
        //     .Where(c => c.RfCaseId.Equals(id)).OrderBy(c => c.Id)//order by entry order
        //               select new dtoNameIdItem
        //               {
        //                   id = c.Id,
        //                   name = c.Name
        //               };
        //     return res.ToList();
        // }


        //Get api/rfcase/77/attachments
        [HttpGet("{id}/attachments")]
        public ActionResult GetAttachmentList([FromRoute] long id)
        {
            var res = from c in _context.RfCaseBlob
            .Where(c => c.RfCaseId.Equals(id)).OrderBy(c => c.Id)//order by entry order
                      select new dtoNameIdItem
                      {
                          id = c.Id,
                          name = c.Name
                      };

            //Took forever to find this out
            //How to get user id from jwt token in controller
            //http://www.jerriepelser.com/blog/aspnetcore-jwt-saving-bearer-token-as-claim/
            var userId = User.FindFirst("id")?.Value;
            long luserId=long.Parse(userId);


            var user = _context.User.SingleOrDefault(m => m.Id == luserId);
            if (user == null)
            {
                return NotFound();
            }

            return new JsonResult(new { dlkey = user.DlKey, attach = res.ToList() });
        }




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


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

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

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

            return Ok(RfCase);
        }

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

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

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

            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!RfCaseExists(id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }

            return NoContent();
        }

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

            _context.RfCase.Add(RfCase);
            await _context.SaveChangesAsync();

            return CreatedAtAction("GetRfCase", new { id = RfCase.Id }, RfCase);
        }

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

            var RfCase = await _context.RfCase.SingleOrDefaultAsync(m => m.Id == id);
            if (RfCase == null)
            {
                return NotFound();
            }

            _context.RfCase.Remove(RfCase);
            await _context.SaveChangesAsync();

            return Ok(RfCase);
        }

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