using Acumatica.Auth.Api;
using Acumatica.Default_20_200_001.Api;
using Acumatica.Default_20_200_001.Model;
using RestSharp;
using RestSharp.Serializers.Json;
using Newtonsoft.Json;
using Acumatica.Manufacturing_21_200_001.Api;
using Acumatica.Manufacturing_21_200_001.Model;
using Acumatica.RESTClient.Client;
using Acumatica;
using uri_import.FClasses;
using System;
using System.Collections.Generic;
using uri_import.AClasses;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.IO;
using uri_import.EClasses;


namespace uri_import.AClasses
{
    public class AcumaticaREST
    {
        public static string PutFile(RestService service, SalesOrder so, string siteURL, string entityName, string orderNbr, string fileName, byte[] file)
        {
            using (MemoryStream memory = new MemoryStream(file))
            {
                return service.PutFile(siteURL, "SalesOrder", string.Format("SO/{0}", so.OrderNbr), "PurchaseOrder.pdf", memory);
            }



        }
        public static Configuration Config(string siteURL, string username, string password, string tenant = null, string branch = null, string locale = null)
        {
            var authApi = new AuthApi(siteURL,
                requestInterceptor: RequestLogger.LogRequest, responseInterceptor: RequestLogger.LogResponse);
            return authApi.LogIn(username, password, tenant, branch, locale);
        }

        public static void APILogout(string siteURL, string username, string password, string tenant = null, string branch = null, string locale = null)
        {
            var authApi = new AuthApi(siteURL,
                requestInterceptor: RequestLogger.LogRequest, responseInterceptor: RequestLogger.LogResponse);
            if (authApi.TryLogout())
            {
                Console.WriteLine("Logged out successfully.");
            }
            else
            {
                Console.WriteLine("An error occured during logout.");
            }
        }

        public static void UploadPurchaseOrder(Configuration config, SalesOrder entity, string filename, byte[] content)
        {
            try
            {
                Console.WriteLine(string.Format("Attaching Purchase Order:"));
                var soApi = new SalesOrderApi(config);
                
                soApi.PutFile(entity.ID.ToString(), filename, content);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
        public static void CreateSalesOrder(ref SalesOrder entity, Configuration config, string filename, byte[] content)
        {
            try
            {
                Console.WriteLine(string.Format("Creating Sales Order from PO: {0}", entity.CustomerOrder.Value));
                var soApi = new SalesOrderApi(config);

                SalesOrder savedSO = soApi.PutEntity(entity, null, null, "Details");
                entity.OrderNbr = savedSO.OrderNbr;
                entity.ID = savedSO.ID;
                //soApi.PutFile(entity.ID.ToString(), filename, content);

            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);

            }
        }
        public static void CreateProductionOrder(Configuration config, ref ProductionOrder entity, string siteURL, string username, string password, string tenant = null, string branch = null, string locale = null)
        {
            try
            {
                Console.WriteLine(string.Format("Creating Production Order from Sales Order: ", entity.SOOrderNbr.Value));
                var poApi = new ProductionOrderApi(config);
                var cpoApi = new CreateProductionOrderApi(config);
                CreateProductionOrder cpo = new CreateProductionOrder();
                cpo.CreationOrderType = "RO";
                cpo.SOOrderType = "SO";
                cpo.SOOrderNbr = entity.SOOrderNbr;
                cpoApi.WaitActionCompletion(cpoApi.InvokeAction(new CreateProductionOrderProcessAll(cpo)));

            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
        public static List<ProductionOrder> ReleaseAndLinkProductionOrders(Configuration config, EmailAttachment entity, string siteURL, string username, string password, string tenant = null, string branch = null, string locale = null)
        {
            List<ProductionOrder> list = new List<ProductionOrder>();
            try
            {
                Console.WriteLine(string.Format("Retreiving Production Order from Sales Order: ", entity.SalesOrder.OrderNbr.Value));
                var poApi = new ProductionOrderApi(config);
                string filter = string.Format("SOOrderNbr eq '{0}'", entity.SalesOrder.OrderNbr.Value);
                list = poApi.GetList(null, filter, null, null, null, null);
                foreach (ProductionOrder po in list)
                {
                    entity.ProductionOrders.Add(po);
                    poApi.WaitActionCompletion(poApi.InvokeAction(new CreateLinkedProductionOrders(po)));
                    entity.Linked = true;
                    poApi.WaitActionCompletion(poApi.InvokeAction(new ReleaseProductionOrder(po)));
                    entity.Released = true;
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            return list;
        }
        public static void Test(Configuration config, string siteURL, string username, string password, string tenant = null, string branch = null, string locale = null)
        {
            // var authApi = new AuthApi(siteURL,
            //     requestInterceptor: RequestLogger.LogRequest, responseInterceptor: RequestLogger.LogResponse);
            try
            {


                //var configuration = authApi.LogIn(username, password, tenant, branch, locale);
                Console.WriteLine("Reading Accounts...");
                var accountApi = new AccountApi(config);
                var accounts = accountApi.GetList(top: 5);
                foreach (var account in accounts)
                {
                    Console.WriteLine("Account Nbr: " + account.AccountCD.Value + ";");
                }
                Console.WriteLine("Reading Sales Order by Keys...");
                var salesOrderApi = new SalesOrderApi(config);
                var order = salesOrderApi.GetByKeys(new List<string>() { "SO", "009314" }, null, null, "Details");
                Console.WriteLine("Order Total: " + order.OrderTotal.Value);






                var shipmentApi = new ShipmentApi(config);
                var shipment = shipmentApi.GetByKeys(new List<string>() { "002805" });
                Console.WriteLine("ConfirmShipment");
                //shipmentApi.WaitActionCompletion(shipmentApi.InvokeAction(new ConfirmShipment(shipment)));

                Console.WriteLine("CorrectShipment");
                shipmentApi.WaitActionCompletion(shipmentApi.InvokeAction(new CorrectShipment(shipment)));
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
    }
}