using System;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using LFSLapper;

namespace LapperThreads
{
    public class LFSRestAPI
    {
        /*Code by xspeedasx https://www.lfs.net/forum/post/1970141#post1970141 */
        //Get list of mods
        public static async Task<List<ModCarEntry>> GetListOfModdedCars(string RestclientID, string RestclientSecret)
        {
            var client = new HttpClient();
            var content = new FormUrlEncodedContent(new Dictionary<string, string>
                {
                    {"client_secret",  RestclientSecret },
                    {"client_id", RestclientID },
                    {"grant_type", "client_credentials"}
                });
            var tokenResponse = await client.PostAsync("https://id.lfs.net/oauth2/access_token", content);
            var tokenText = await tokenResponse.Content.ReadAsStringAsync();
            var tokenStatus = tokenResponse.StatusCode;

            if (tokenStatus == System.Net.HttpStatusCode.OK)
            {
                try
                {
                    var tokenObject = JsonConvert.DeserializeObject<TokenResponse>(tokenText);
                    var accessToken = tokenObject.access_token;

                    client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);

                    var carEntriesResponse = await client.GetAsync("https://api.lfs.net/vehiclemod/");
                    var dataStatus = carEntriesResponse.StatusCode;
                    var dataText = await carEntriesResponse.Content.ReadAsStringAsync();
                    return JsonConvert.DeserializeObject<ModCarEntriesResponse>(dataText).Data;
                }
                catch
                {
                    throw new GLScript.GLApp.GLScriptException("Error on receiving moddata from LFS, check connection.");
                }
            }
            else
            {
                throw new GLScript.GLApp.GLScriptException("Error on authorisation: Unauthorized or check connection.");
            }
        }

        //Request info of 1 mod
        public static async Task<GetCarInfo> GetVehicleInfo(string RestclientID, string RestclientSecret, string car)
        {
            var client = new HttpClient();
            var content = new FormUrlEncodedContent(new Dictionary<string, string>
            {
                {"client_secret",  RestclientSecret },
                {"client_id", RestclientID },
                {"grant_type", "client_credentials"}
            });

            var tokenResponse = await client.PostAsync("https://id.lfs.net/oauth2/access_token", content);
            var tokenText = await tokenResponse.Content.ReadAsStringAsync();
            var tokenStatus = tokenResponse.StatusCode;

            if (tokenStatus == System.Net.HttpStatusCode.OK)
            {
                try
                {
                    var tokenObject = JsonConvert.DeserializeObject<TokenResponse>(tokenText);
                    var accessToken = tokenObject.access_token;

                    client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);

                    var carEntriesResponse = await client.GetAsync("https://api.lfs.net/vehiclemod/" + car);
                    var dataStatus = carEntriesResponse.StatusCode;
                    var dataText = await carEntriesResponse.Content.ReadAsStringAsync();
                    return JsonConvert.DeserializeObject<GetCarInfo>(dataText);
                }
                catch
                {
                    throw new GLScript.GLApp.GLScriptException("Error on receiving moddata from LFS, check connection.");
                }
            }
            else
            {
                throw new GLScript.GLApp.GLScriptException("Error on authorisation: Unauthorized or check connection.");
            }
        }

        public class TokenResponse
        {
            public string token_type { get; set; }
            public int expires_in { get; set; }
            public string access_token { get; set; }
        }

        public class ModCarEntriesResponse
        {
            public List<ModCarEntry> Data { get; set; }
            public int Id { get; set; }
            public object Exception { get; set; }
            public int Status { get; set; }
            public bool IsCanceled { get; set; }
            public bool IsCompleted { get; set; }
            public int CreationOptions { get; set; }
            public object AsyncState { get; set; }
            public bool IsFaulted { get; set; }
        }

        public class GetCarInfo
        {
            public ModCarEntry data { get; set; }
        }

        public class ModCarEntry
        {
            public string id { get; set; }
            public string name { get; set; }
            public string descriptionShort { get; set; }
            public string description { get; set; }
            public int userId { get; set; }
            public string userName { get; set; }
            public bool wip { get; set; }
            public int publishedAt { get; set; }
            public int numDownloads { get; set; }
            public int curUsage { get; set; }
            public float rating { get; set; }
            public int numRatings { get; set; }
            public int version { get; set; }
            public int lastDownloadedAt { get; set; }
            public int Class { get; set; }
            public bool ev { get; set; }
            public bool staffPick { get; set; }
            public bool tweakMod { get; set; }
            public string coverUrl { get; set; }
            public List<string> screenshotUrls { get; set; }

            public CarDetails vehicle { get; set; }
        }
        public class CarDetails
        {
            public int iceCc { get; set; }
            public int iceNumCylinders { get; set; }
            public int iceLayout { get; set; }
            public float evRedLine { get; set; }
            public int drive { get; set; }
            public int shiftType { get; set; }
            public double power { get; set; }
            public int maxPowerRpm { get; set; }
            public double torque { get; set; }
            public int maxTorqueRpm { get; set; }
            public double mass { get; set; }
            public double bhp { get; set; }
            public double powerWeightRatio { get; set; }
            public double bhpTon { get; set; }
            public double fuelTankSize { get; set; }
        }

        public enum Class
        {
            Object,         //0: Object
            Touring_Car,    //1: Touring car
            Saloon_Car,     //2: Saloon car
            Buggy,          //3: Buggy
            Formula,        //4: Formula
            GT,             //5: GT
            Kart,           //6: Kart
            Bike,           //7: Bike
            Van,            //8: Van
            Truck,          //9: Truck
            Formula_1,      //10: Formula 1
            Formula_SAE    //11: Formula SAE
        };

        public enum iceLayout
        {
            Inline,     //0: inline
            Flat,       //1: flat
            V          //2: V Shape
        };

        public enum drivetrains
        {
            None,                   //0: None
            Rear_Wheel_Drive_RWD,   //1: Rear-Wheel Drive
            Front_Wheel_Drive_FWD,  //2: Front-Wheel Drive
            All_Wheel_Drive_AWD,    //3: All-Wheel Drive 
            Four_Wheel_Drive_4WD   //4: Four Wheel Drive
        };

        public enum shiftType
        {
            None,                           //0: None
            H_Pattern,                      //1: H-pattern gearbox
            Motorbike,                      //2: Motorbike
            Sequential,                     //3: Sequential
            Sequential_with_ignition_cut,   //4: Sequential with ignition cut
            Paddle,                         //5: Paddle
            Electric_Motor,                 //6: Electric motor
            Centrifugal_Clutch             //7: Centrifugal clutch
        };
    }
}
