using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using EpsonPrinter.Model;
using ESCPOS_NET.Emitters;
using Microsoft.Extensions.Configuration;

namespace EpsonPrinter.Services
{
    public class PrintBody
    {
        private ICommandEmitter _e;
        private IConfiguration _config;

        private int productMaxWidth;

        public PrintBody(ICommandEmitter e, IConfiguration config)
        {
            _e = e;
            _config = config;
        }

        public List<byte[][]> Print(BodyModel model)
        {
            List<byte[][]> data = new List<byte[][]>();

            byte[][] headerModel =
            {
                _e.SetStyles(PrintStyle.None),
                _e.LeftAlign(),
                _e.PrintLine($"Dato.........: {model.ReceiptTime}"),
                _e.PrintLine($"Ekspedient...: {model.Staff}"),
                _e.PrintLine($"Kvittering...: {model.ReceiptNumber}"),
                _e.FeedLines(1)
            };
            data.Add(headerModel);

            int printWidth = Convert.ToInt32(_config["PrintSettings:PrintWidth"]);
            foreach (BodyProductModel product in model.Products)
            {
                //Size of product is max half of recipt
                string totalProductLine = MakeProductNameString(product.Product, printWidth);
                totalProductLine += MakeProductNumber(product.NoOfProduct, product.Price);
                totalProductLine = MakeTotalProductPrice(totalProductLine, product.TotalPrice,printWidth);

                byte[][] p =
                {
                    _e.PrintLine(totalProductLine)
                };
                data.Add(p);
            }

            PrintString printString = new PrintString();
            string totalPricePrint = printString.MakePrintString(printWidth, $"Total: ", $"{model.TotalPrice:F} DKK");
            byte[][] totalPrice =
            {
                _e.FeedLines(1),
                _e.SetStyles(PrintStyle.Bold | PrintStyle.DoubleHeight),
                _e.RightAlign(),
                _e.PrintLine(totalPricePrint)
            };
            data.Add(totalPrice);

            byte[][] vat =
            {
                _e.FeedLines(1),
                _e.SetStyles(PrintStyle.None),
                _e.LeftAlign(),
                _e.PrintLine(MakeVat(printWidth,model.TotalVat))
            };
            data.Add(vat);

            return data;
        }

        private string MakeProductNameString(string product, int totalWidth)
        {
            string productString = product;
            productMaxWidth = (totalWidth / 2) - 5;
            int productLength = product.Length;
            if (productLength < productMaxWidth)
            {

                for (int i = productLength; i < productMaxWidth; i++)
                {
                    productString += ".";
                }
            }
            
            return productString;
        }

        private string MakeProductNumber(int noOfProduct, decimal price)
        {
            return $"{noOfProduct} á {price:F} DKK :";
        }

        private string MakeTotalProductPrice(string buffer, decimal totalPrice, int printWidth)
        {
            PrintString printString = new PrintString();
            string p = $"{totalPrice:F} DKK";
            string makePrintString = printString.MakePrintString(printWidth, buffer, p);
            return makePrintString;
        }

        private string MakeVat(int printWidth, decimal vat)
        {
            PrintString printString = new PrintString();
            string vatDesc = $"Moms udgør 25% :";
            string v = $"{vat:F} DKK";
            string vatString = printString.MakePrintString(printWidth, vatDesc, v);
            return vatString;
        }
    }
}
