namespace Parser;


public record KitchenReceipt(string Location, string Date, string Owner, string Tisch, List<KitchenItem> items) :ASTNode;
public record KitchenItem(string Name) : ASTNode;
public record KitchenProduct(int Amount, string Name):KitchenItem(Name);
public record KitchenGang(string Name) :KitchenItem(Name);

public record FinalReceipt(string Location, string Phone, string URL, string Date, List<FinalReceiptItem> items, string total, string MWST, string Comment, string Thanks) : ASTNode;

public record FinalReceiptItem(string Name):ASTNode;
public record FinalReceiptProduct(string Name, int Amount, string Price, string Total) : FinalReceiptItem(Name);
public record FinalReceiptGang(string Name) : FinalReceiptItem(Name);

public class RecipeTranslator
{
    public ASTNode ParseReceipt(string receiptText)
    {
        // Determine receipt type based on content
        bool isFinalReceipt = receiptText.Contains("http") ||
                              receiptText.Contains("+41") ||
                              receiptText.Contains("Summe CHF") ||
                              receiptText.Contains("MWST") ||
                              receiptText.Contains("Thank you");

        bool isKitchenReceipt = receiptText.Contains("TISCH:");

        if (isKitchenReceipt && !isFinalReceipt)
        {
            return ParseKitchenReceipt(receiptText);
        }
        else if (isFinalReceipt)
        {
            return ParseFinalReceipt(receiptText);
        }
        else
        {
            // Default to kitchen receipt if unclear
            return ParseKitchenReceipt(receiptText);
        }
    }

    public static FinalReceipt ParseFinalReceipt(string receiptText)
    {
        var lines = receiptText.Split('\n', StringSplitOptions.RemoveEmptyEntries)
            .Select(l => l.Trim())
            .ToList();

        // Extract header information
        string location = lines[0];
        string phone = lines[1];
        string url = lines[2];

        // Find and extract date
        var dateLine = lines.FirstOrDefault(l => l.StartsWith("Datum:"));
        string date = dateLine?.Replace("Datum:", "").Trim() ?? "";

        // Find total line
        var totalLine = lines.FirstOrDefault(l => l.Contains("Summe CHF :"));
        string total = totalLine?.Split(':').Last().Trim() ?? "";

        // Find MWST line (comes after "TOTAL         MWST" header)
        var mwstLineIndex = lines.FindIndex(l => l.StartsWith("TOTAL") && l.Contains("MWST"));
        string mwst = mwstLineIndex >= 0 && mwstLineIndex + 1 < lines.Count
            ? lines[mwstLineIndex + 1].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).LastOrDefault() ?? ""
            : "";

        // Extract comment (line after MWST values)
        string comment = mwstLineIndex >= 0 && mwstLineIndex + 2 < lines.Count
            ? lines[mwstLineIndex + 2]
            : "";

        // Extract thank you message (last non-separator line)
        string thanks = lines.LastOrDefault(l => !l.Contains("--")) ?? "";

        // Parse items
        var items = new List<FinalReceiptItem>();
        var startIndex = lines.FindIndex(l => l.StartsWith("Datum:")) + 2; // Skip date and separator
        var endIndex = lines.FindIndex(l => l.Contains("Summe CHF"));

        for (int i = startIndex; i < endIndex; i++)
        {
            var line = lines[i];

            // Skip separator lines and empty lines
            if (line.Contains("---") || string.IsNullOrWhiteSpace(line))
                continue;

            
            // Check if line contains item data (has * separator)
            if (line.Contains("*"))
            {
                // Parse format: "Name  Amount *  Price  Total"
                var parts = line.Split('*');
                if (parts.Length == 2)
                {
                    var leftPart = parts[0].Trim();
                    var rightPart = parts[1].Trim();

                    // Extract name and amount from left part
                    var leftTokens = leftPart.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                    var amount = int.Parse(leftTokens.Last());
                    var name = string.Join(" ", leftTokens.Take(leftTokens.Length - 1));

                    // Extract price and total from right part
                    var rightTokens = rightPart.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                    var price = rightTokens.Length > 0 ? rightTokens[0] : "";
                    var itemTotal = rightTokens.Length > 1 ? rightTokens[1] : "";

                    items.Add(new FinalReceiptProduct(name, amount, price, itemTotal));
                }
            }
        }

        return new FinalReceipt(location, phone, url, date, items, total, mwst, comment, thanks);
    }

    public static KitchenReceipt ParseKitchenReceipt(string receiptText)
    {
        var lines = receiptText.Split('\n', StringSplitOptions.RemoveEmptyEntries)
            .Select(l => l.Trim())
            .ToList();

        int currentIndex = 0;

        // Skip optional "*** KOPIE ***" header
        if (lines[currentIndex].Contains("***"))
        {
            currentIndex++;
        }

        // Extract location (can be any phrase)
        string location = lines[currentIndex];
        currentIndex++;

        // Skip separator line
        while (currentIndex < lines.Count && lines[currentIndex].Contains("---"))
        {
            currentIndex++;
        }

        // Extract date line
        string date = lines[currentIndex];
        currentIndex++;

        // Extract owner
        string owner="";
        do
        {
            if (owner!="")
            {
                owner += "/n";
            }
            owner += lines[currentIndex];
            currentIndex++;
        } while (!lines[currentIndex].ToLower().Contains("tisch:"));
        

        // Extract table (extract text after "TISCH:")
        string tisch = lines[currentIndex].Replace("TISCH:", "").Trim();
        currentIndex++;

        // Skip empty lines and separators until we reach items
        while (currentIndex < lines.Count &&
               (string.IsNullOrWhiteSpace(lines[currentIndex]) || lines[currentIndex].Contains("-")))
        {
            currentIndex++;
        }

        // Parse items
        var items = new List<KitchenItem>();
        while (currentIndex < lines.Count)
        {
            var line = lines[currentIndex];

            // Stop at separator or end
            if (line.Contains("---") || string.IsNullOrWhiteSpace(line))
            {
                break;
            }

            if ( line.ToLower().Contains(". gang"))
            {
                items.Add(new KitchenGang(line.Trim()));
                currentIndex++;
                continue;
            }

            // Parse format: "1x Espresso" or " 1x Espresso"
            var trimmedLine = line.Trim();
            if (trimmedLine.Contains("x"))
            {
                var parts = trimmedLine.Split('x', 2);
                if (parts.Length == 2 && int.TryParse(parts[0].Trim(), out int amount))
                {
                    var itemName = parts[1].Trim();
                    items.Add(new KitchenProduct(amount, itemName));
                }
            }

            currentIndex++;
        }

        return new KitchenReceipt(location, date, owner, tisch, items);
    }

    
}

