using System;
using System.Globalization;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using iTextSharp;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;
using Acumatica.Default_20_200_001.Model;

namespace uri_import.PClasses
{
    public class PDFHelper
    {
        private static string _note = "<200# USE UPS 3RD PARTY ACCT# 266E8F>\n200# USE LTL ROUTING GUIDE- - - - - - - -828-485-5145\nhttp://routeshipment.com/R9322/\nBill to: United Rentals, INC\nC/O TRANSPORTATION INSIGHT\nPO BOX 23000\nHICKORY, NC 28601\nEMAIL LOADCENTER@UR.COM";
        private static List<string> RemoveLine(List<string> list, string contains)
        {
            string line = list.Find(x => x.ToUpper().Contains(contains.ToUpper()));
            if (line != null) list.Remove(line);

            return list;
        }
        private static List<string> RemovePhoneAndFax(List<string> list)
        {
            string line = list.Find(x => x.ToUpper().Contains("PHONE:"));
            if (line != null) list.Remove(line);
            line = list.Find(x => x.ToUpper().Contains("FAX"));
            if (line != null)
            {
                int index = list.FindIndex(x => x == line);
                Regex regex = new Regex(@"\(?\d{3}\)?-? *\d{3}-? *-?\d{4}");
                string faxLine = list[index + 1];
                if (regex.IsMatch(faxLine))
                {
                    list.Remove(line);
                    list.Remove(faxLine);
                }
                else list.Remove(line);
            }

            return list;
        }
        private static SalesOrder CityStateZip(ref List<string> lines, SalesOrder order)
        {
            int index = 0;
            int numIndexes = 2;
            Regex rCSZ = new Regex(@"^.*(\s\s\d{5}(-\d{4})?$)|(^[ABCEGHJKLMNPRSTVXY]{1}\d{1}[A-Z]{1} *\d{1}[A-Z]{1}\d{1}).*$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant);
            foreach (string line in lines)
            {
                if (rCSZ.IsMatch(line))
                {
                    DateTime dt;
                    index = lines.FindIndex(x => x == line);
                    if (DateTime.TryParse(lines[index - 4], out dt))
                    {
                        numIndexes = 3;
                        order.ShipToAddress = new Address();
                        order.ShipToAddress.AddressLine1 = lines[index - 3].Trim();
                        order.ShipToAddress.AddressLine2 = string.Format("{0}\r\n{1}", lines[index - 2].Trim(), lines[index - 1].Trim());
                        string[] csz = line.Split(',');
                        order.ShipToAddress.City = csz[0].Trim();
                        csz[1] = csz[1].Replace("  ", "|");
                        string[] sz = csz[1].Trim().Split('|');
                        order.ShipToAddress.State = sz[0].Trim();
                        order.ShipToAddress.PostalCode = sz[1].Trim();
                        break;

                    }
                    else
                    {
                        order.ShipToAddress = new Address();
                        order.ShipToAddress.AddressLine1 = lines[index - 2].Trim();
                        order.ShipToAddress.AddressLine2 = lines[index - 1].Trim();
                        string[] csz = line.Split(',');
                        order.ShipToAddress.City = csz[0].Trim();
                        csz[1] = csz[1].Replace("  ", "|");
                        string[] sz = csz[1].Trim().Split('|');
                        order.ShipToAddress.State = sz[0].Trim();
                        order.ShipToAddress.PostalCode = sz[1].Trim();
                        break;
                    }
                }
            }
            string pc = order.ShipToAddress.PostalCode.Value;
            pc = pc.Replace("-", "");
            int i = 0;
            bool result = int.TryParse(pc, out i);
            if (result) order.ShipToAddress.Country = "US";
            else order.ShipToAddress.Country = "CA";
            for (int r = index; r >= numIndexes; r--)
            {
                lines.RemoveAt(r);
            }
            string startLine = lines.Find(x => x.Trim().StartsWith("Qty"));
            if (startLine != null)
            {
                index = lines.IndexOf(startLine);
                for (int iIndex = index; iIndex >= 0; iIndex--)
                {
                    lines.RemoveAt(iIndex);
                }
            }
            return order;
        }
        private static SalesOrder GetDetails(SalesOrder order, ref List<string> lines)
        {
            order.Details = new List<SalesOrderDetail>();
            int lrNumb = 1;
            for (int i = 0; i < lines.Count; i++)
            {
                string line = lines[i].Trim().Substring(0, 3).Trim();
                int isInt = 0;
                if (int.TryParse(line, out isInt))
                {
                    try
                    {
                        lines[i] = Regex.Replace(lines[i], @"\s+", "|");
                        string[] clmns = lines[i].Split('|');
                        SalesOrderDetail detail = new SalesOrderDetail();
                        detail.OrderQty = int.Parse(clmns[0].Trim());
                        detail.InventoryID = clmns[1].Trim();
                        detail.LineNbr = lrNumb;
                        detail.RowNumber = lrNumb;
                        order.Details.Add(detail);
                        lrNumb = lrNumb + 1;
                    }
                    catch { }

                }
            }

            return order;
        }
        private static SalesOrder FindThePhoneNumber(ref List<string> list, SalesOrder order)
        {
            bool found = false;
            Regex regex = new Regex(@"\(?\d{3}\)?-? *\d{3}-? *-?\d{4}");
            foreach (string line in list)
            {
                string[] segments = line.Split(' ');
                foreach (string segment in segments)
                {
                    string s = segment.Trim();
                    if (regex.IsMatch(s))
                    {
                        order.ShipToContact = new DocContact();
                        order.ShipToContact.Phone1 = s;
                        found = true;
                        break;
                    }
                }
                if (found)
                {
                    list.Remove(line);
                    break;
                }
            }

            return order;
        }
        public static SalesOrder PDFBuildSalesOrder(List<string> lines)
        {
            SalesOrder order = new SalesOrder();
            for (int l = 0; l < lines.Count; l++)
            {
                lines[l] = lines[l].Trim();

            }
            lines = RemoveLine(lines, "PURCHASE ORDER");
            lines = RemoveLine(lines, "179054");
            lines = RemoveLine(lines, "RPM INDUSTRIES LLC");
            lines = RemoveLine(lines, "Purchase Order Number");
            lines = RemoveLine(lines, "1660 JEFFERSON AVE");
            lines = RemoveLine(lines, "WASHINGTON, PA  15301");
            lines = RemoveLine(lines, "ORDER DATE:");
            lines = RemoveLine(lines, "Phone ");
            lines = RemoveLine(lines, "ORDERED BY:");
            lines = RemoveLine(lines, "LOCATION #:");
            lines = RemoveLine(lines, "Fax ");
            lines = RemoveLine(lines, "ADDRESS");
            lines = RemoveLine(lines, "DO NOT SHIP TO");
            lines = RemoveLine(lines, "STAMFORD, CT  06902");
            lines = RemoveLine(lines, "SEE BELOW");
            lines = RemoveLine(lines, "THE FOLLOWING MUST APPEAR");
            lines = RemoveLine(lines, "SHIPPING PAPERS");
            lines = RemovePhoneAndFax(lines);
            order.CustomerOrder = lines[0];
            DateTime orderDate = DateTime.Parse(lines[1].Trim());
            order.Date = DateTime.Parse(lines[1]);
            if (orderDate.Day > 15)
            {
                orderDate = orderDate.AddMonths(1);
                int lastDay = DateTime.DaysInMonth(orderDate.Year, orderDate.Month);
                orderDate = new DateTime(orderDate.Year, orderDate.Month, lastDay);
                if (orderDate.DayOfWeek == DayOfWeek.Sunday)
                    orderDate = new DateTime(orderDate.Year, orderDate.Month, orderDate.Day - 2);
                if (orderDate.DayOfWeek == DayOfWeek.Saturday)
                    orderDate = new DateTime(orderDate.Year, orderDate.Month, orderDate.Day - 1);
            }
            else
            {
                int lastDay = DateTime.DaysInMonth(orderDate.Year, orderDate.Month);
                orderDate = new DateTime(orderDate.Year, orderDate.Month, lastDay);
                if (orderDate.DayOfWeek == DayOfWeek.Sunday)
                    orderDate = new DateTime(orderDate.Year, orderDate.Month, orderDate.Day - 2);
                if (orderDate.DayOfWeek == DayOfWeek.Saturday)
                    orderDate = new DateTime(orderDate.Year, orderDate.Month, orderDate.Day - 1);
            }
            order.CustomerID = "000000001433";
            order.RequestedOn = orderDate;
            FindThePhoneNumber(ref lines, order);
            order.ShipToAddressOverride = true;
            order = CityStateZip(ref lines, order);
            order.Note = _note;
            order = GetDetails(order, ref lines);



            return order;
        }
        public static List<string> PDFLinesToText(string filePath)
        {
            List<string> list = new List<string>();
            using (PdfReader reader = new PdfReader(filePath))
            {
                StringBuilder text = new StringBuilder();
                ITextExtractionStrategy Strategy = new iTextSharp.text.pdf.parser.LocationTextExtractionStrategy();

                for (int i = 1; i <= reader.NumberOfPages; i++)
                {
                    string page = "";

                    page = PdfTextExtractor.GetTextFromPage(reader, i, Strategy);
                    string[] lines = page.Split('\n');
                    list.AddRange(lines);
                }
            }
            return list;

        }

    }
    public class SBTextRenderer : IRenderListener
    {

        private StringBuilder _builder;
        public SBTextRenderer(StringBuilder builder)
        {
            _builder = builder;
        }
        #region IRenderListener Members

        public void BeginTextBlock()
        {
            Console.Write("Begin Text Block");
        }

        public void EndTextBlock()
        {
            Console.Write("End Text Block");
        }

        public void RenderImage(ImageRenderInfo renderInfo)
        {
        }

        public void RenderText(TextRenderInfo renderInfo)
        {
            _builder.Append(renderInfo.GetText());
        }

        #endregion
    }
}