using System;
using System.IO;
using System.Linq;
using Interfaces;
using Nancy;
using Nancy.Extensions;
using Nancy.ModelBinding;

namespace RaceLapTimer.ApiControllers
{
    public class PilotApiModule : NancyModule
    {
        private readonly IDbProvider _provider;
        private readonly IRootPathProvider _rootPathProvider;

        public PilotApiModule(IDbProvider provider, IRootPathProvider pathProvider) : base("/api/pilot")
        {
            _provider = provider;
            _rootPathProvider = pathProvider;

            Get["/{id}"] = args => GetPilot(args);
            Post["/edit"] = args => EditCreatePilot();
            Post["/create"] = args => EditCreatePilot();
            Get["/delete/{id}"] = args => DeletePilot(args);
            Post["/upload/{id}"] = args => UploadPicture(args);
            Delete["/transponder/{id}"] = args => RemoveTransponderToken(args);
        }

        private dynamic RemoveTransponderToken(dynamic args)
        {
            var pilotId = (int)args.Id;
            var resp = _provider.RemoveTransponderAssociation(pilotId);
            return Context.GetRedirect("/pilots");
        }

        private dynamic UploadPicture(dynamic args)
        {
            var pilotId = args.Id;
            var pilot = (Pilot)_provider.GetPilot(pilotId);
            var oldImageName = Path.GetFileName(pilot.ImageUrl??string.Empty);

            var uploadDirectory = Path.Combine(_rootPathProvider.GetRootPath(), "images");

            if (!Directory.Exists(uploadDirectory))
            {
                Directory.CreateDirectory(uploadDirectory);
            }

            if (Request.Files.Any())
            {
                var file = Request.Files.First();

                var newFileName = Guid.NewGuid();
                var generatedFileName = string.Format("{0}{1}", newFileName, Path.GetExtension(file.Name)); //0000-0000.....ext

                var filename = Path.Combine(uploadDirectory, generatedFileName);

                using (var fileStream = new FileStream(filename, FileMode.Create))
                {
                    file.Value.CopyTo(fileStream);
                    fileStream.Flush();
                    fileStream.Close();
                }

                pilot.ImageUrl = "/images/" + generatedFileName;
                _provider.UpdatePilot(pilot);

                if(!string.IsNullOrEmpty(oldImageName))
                    File.Delete(Path.Combine(uploadDirectory, oldImageName));
            }

            string returnurl = "/pilot/edit/" + pilotId;
            return Context.GetRedirect(returnurl); 
        }

        private dynamic DeletePilot(dynamic args)
        {
            var res = _provider.DeletePilot(args.Id);
            return Context.GetRedirect("/pilots");
        }

        private dynamic GetPilot(dynamic args)
        {
            int pilotId = args.Id;
            return Response.AsJson(_provider.GetPilot(pilotId));
        }

        private dynamic EditCreatePilot()
        {
            var pilotObject = this.Bind<Pilot>();
            var resp = _provider.CreatePilot(pilotObject);
            return Context.GetRedirect("/pilots");
        }
    }
}
