using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using YTManager;
using YTManager.Models;

namespace YTManager.Controllers.Private
{
    [Produces("application/json")]
    [Route("api_raw/Channels")]
    public class Private_Channel : Controller
    {
        private readonly MediaDB db;

        public Private_Channel(MediaDB context)
        {
            db = context;
        }

        [HttpGet]
        public IEnumerable<Channel> GetChannels()
        {
            return db.Channels;
        }

        [HttpGet("{id}")]
        public async Task<IActionResult> GetChannel([FromRoute] long id)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            var channel = await db
                .Channels
                .Include(c => c.Videos)
                .SingleOrDefaultAsync(m => m.PrimaryKey == id);

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

            return Ok(channel);
        }

        [HttpPut("{id}")]
        public async Task<IActionResult> PutChannel([FromRoute] long id, [FromBody] Channel channel)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            if (id != channel.PrimaryKey)
            {
                return BadRequest();
            }

            db.Entry(channel).State = EntityState.Modified;

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

            return NoContent();
        }

        [HttpPost("{channelid}")]
        public async Task<IActionResult> PostChannel([FromRoute] string channelid) {
            // Only add it to the databse if it's not in there already.
            if (db.Channels.Any(c => c.YoutubeID == channelid))
                return BadRequest();

            // Get the channel contents from youtube.
            var channel = await Tasks.FetchVideos.Get_YTChannel(channelid);

            // Add it to the databse.
            await db.Channels.AddAsync(channel);
            await db.SaveChangesAsync();

            // Say all went ok.
            return Ok(channel);
        }

        [HttpPost]
        public async Task<IActionResult> PostChannel([FromBody] Channel channel)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            db.Channels.Add(channel);
            await db.SaveChangesAsync();

            return CreatedAtAction("GetChannel", new { id = channel.PrimaryKey }, channel);
        }

        [HttpDelete("{id}")]
        public async Task<IActionResult> DeleteChannel([FromRoute] long id)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            var channel = await db.Channels.SingleOrDefaultAsync(m => m.PrimaryKey == id);
            if (channel == null)
            {
                return NotFound();
            }

            db.Channels.Remove(channel);
            await db.SaveChangesAsync();

            return Ok(channel);
        }

        private bool ChannelExists(long id)
        {
            return db.Channels.Any(e => e.PrimaryKey == id);
        }
    }
}