namespace Inspectron.Epson.PrintServer.Printers.Utils.KitchenReceipt;

public class KitchenReceiptConverter
{
    private readonly int _lineWidth;
    private readonly int _BigLineWidth;

    public KitchenReceiptConverter(int lineWidth = 42, int bigLineWidth=22)
    {
        _BigLineWidth = bigLineWidth;
        _lineWidth = lineWidth;
    }

    public List<PrintCommand> ConvertToPrintCommands(KitchenReceipt kitchenReceipt)
    {
        var commands = new List<PrintCommand>();

        // Header - Restaurant name in red
        commands.Add(new PrintCommand(Center(kitchenReceipt.Title, true)) { IsRed = true , IsBig = true, IsTall = true });
        commands.Add(new PrintCommand(CreateDashedLine()));
        commands.Add(new PrintCommand(""));

        // Transaction info
        string dateTimeLine = $"{kitchenReceipt.TransactionDateTime:dd-MMM-yy HH:mm} Nr.:{kitchenReceipt.ReceiptNumber}";
        commands.Add(new PrintCommand(Center(dateTimeLine, false)));

        string serverLine = $"{kitchenReceipt.WaiterName}";
        commands.Add(new PrintCommand(Center(serverLine, false)));

        //string serverIdLine = $"{kitchenReceipt.WaiterId}";
        //commands.Add(new PrintCommand(Center(serverIdLine, false)));

        string tableLine = $"Tisch: {kitchenReceipt.TableNumber}";
        commands.Add(new PrintCommand(Center(tableLine, true), true, true));

        if (!string.IsNullOrEmpty(kitchenReceipt.SpecialInstruction))
        {
            commands.Add(new PrintCommand(""));
            commands.Add(new PrintCommand(Center(kitchenReceipt.SpecialInstruction, true), true,true));
            commands.Add(new PrintCommand(""));
        }

        commands.Add(new PrintCommand(CreateDashedLine()));

        
        

        // Gangs
        
        foreach (Gang gang in kitchenReceipt.Gangs)
        {
            
            commands.Add(new PrintCommand(Center($"{gang.Id}. {gang.Name}", true)) { IsRed = true, IsBig = true, IsTall = true});
            foreach (var dish in gang.Dishes)
            {
                PrintDish(dish, commands);
            }

            if (gang != kitchenReceipt.Gangs.Last())
            {
                commands.Add(new PrintCommand(""){IsCut = true});
                commands.Add(new PrintCommand(""));
                commands.Add(new PrintCommand(""));
            }
        }

        if (kitchenReceipt.Gangs.Count > 0)
        {
            commands.Add(new PrintCommand(CreateDashedLine()));
        }

        foreach (var dish in kitchenReceipt.Dishes)
        {
            PrintDish(dish, commands);
        }

        if (kitchenReceipt.Dishes != null && kitchenReceipt.Dishes.Any())
        {
            commands.Add(new PrintCommand(""));
            commands.Add(new PrintCommand(CreateDashedLine()));
            commands.Add(new PrintCommand(""));
        }
        

        //// Additional info section
        //if (kitchenReceipt.AdditionalInfo != null && kitchenReceipt.AdditionalInfo.Count > 0)
        //{
        //    commands.Add(new PrintCommand(CreateAsterisksLine()));
        //    commands.Add(new PrintCommand("Info über zugehörige Artikel"));
        //    commands.Add(new PrintCommand(CreateAsterisksLine()));

        //    foreach (var info in kitchenReceipt.AdditionalInfo)
        //    {
        //        commands.Add(new PrintCommand(info));
        //    }

        //    commands.Add(new PrintCommand(""));
        //}

        return commands;
    }

    private void PrintDish(Dish dish, List<PrintCommand> commands)
    {
        string quantityPrefix = $"{dish.Number}x ";
        string guestInfo = dish.GuestId.HasValue ? $"{dish.GuestId.Value}  " : "";
        string fullPrefix = guestInfo + quantityPrefix;
        string fullLine = fullPrefix + dish.Name;

        if (fullLine.Length <= _lineWidth || string.IsNullOrEmpty(dish.Name))
        {
            commands.Add(new PrintCommand(fullLine) { IsTall = true });
        }
        else
        {
            int availableWidth = _lineWidth - fullPrefix.Length;
            if (availableWidth <= 0)
            {
                // Prefix alone exceeds line width, print without wrapping
                commands.Add(new PrintCommand(fullLine) { IsTall = true });
            }
            else
            {
                string continuationIndent = new string(' ', guestInfo.Length);
                var words = dish.Name.Split(' ');
                var lines = new List<string>();
                string currentLine = "";

                foreach (var word in words)
                {
                    if (currentLine.Length == 0)
                    {
                        currentLine = word;
                    }
                    else if (currentLine.Length + 1 + word.Length <= availableWidth)
                    {
                        currentLine += " " + word;
                    }
                    else
                    {
                        lines.Add(currentLine);
                        currentLine = word;
                    }
                }

                if (currentLine.Length > 0)
                {
                    lines.Add(currentLine);
                }

                // First line with full prefix
                commands.Add(new PrintCommand(fullPrefix + lines[0]) { IsTall = true });

                // Continuation lines with indent to align with dish name
                for (int i = 1; i < lines.Count; i++)
                {
                    commands.Add(new PrintCommand(continuationIndent + lines[i]) { IsTall = true });
                }
            }
        }
        // Modifications
        if (dish.Modifications != null && (dish.Modifications.Removed.Any() || dish.Modifications.Added.Any()))
        {
            string modificationIndent = new string(' ', guestInfo.Length + 1);
            foreach (var removed in dish.Modifications.Removed)
            {
                commands.Add(new PrintCommand($"{modificationIndent}- {removed}", isBold:true) { IsTall = true });
            }

            foreach (var added in dish.Modifications.Added)
            {
                commands.Add(new PrintCommand($"{modificationIndent}+ {added}", isBold: true) { IsTall = true });
            }
        }

        // SpecialInstruction
        if (!string.IsNullOrEmpty(dish.Comment))
        {
            string commentIndent = new string(' ', guestInfo.Length);
            commands.Add(new PrintCommand($"{commentIndent}Comment: {dish.Comment}", isBold: true) { IsTall = true });
        }

        //commands.Add(new PrintCommand($""));
    }

    private string Center(string text, bool isBigFont)
    {
        var actualLineWidth = isBigFont ? _BigLineWidth : _lineWidth;
        if (string.IsNullOrEmpty(text) || text.Length >= actualLineWidth)
            return text;

        int totalPadding = actualLineWidth - text.Length;
        int leftPadding = totalPadding / 2;

        return new string(' ', leftPadding) + text;
    }

    private string CreateDashedLine()
    {
        return new string('-', _lineWidth);
    }

    private string CreateAsterisksLine()
    {
        return new string('*', _lineWidth);
    }
}
