"""
PDF text extraction and invoice field parsing.

Extracts text from PDFs and parses invoice fields using regex patterns.
Handles German number and date formats.
"""

import io
import re
from pypdf import PdfReader


EXTRACTION_PATTERNS = {
    "invoice_number": [
        r"Rechnungs?-?(?:Nr|Nummer)[.:\s]*([A-Z0-9\-]+)",
        r"Invoice\s*(?:No|Number)?[.:\s]*([A-Z0-9\-]+)",
        r"Beleg-?Nr[.:\s]*([A-Z0-9\-]+)",
        r"Rechnung\s+[0-9]+/([A-Z0-9\-]+)",
    ],
    "gross_amount": [
        r"Brutto[:\s]*([0-9]+(?:[.,][0-9]+)*)\s*(?:EUR|€)?",
        r"Gesamtbetrag[:\s]*([0-9]+(?:[.,][0-9]+)*)",
        r"Total[:\s]*([0-9]+(?:[.,][0-9]+)*)\s*(?:EUR|€)?",
        r"Endbetrag[:\s]*([0-9]+(?:[.,][0-9]+)*)",
        r"Summe[:\s]*([0-9]+(?:[.,][0-9]+)*)",
    ],
    "net_amount": [
        r"Netto[:\s]*([0-9]+(?:[.,][0-9]+)*)\s*(?:EUR|€)?",
        r"Rechnungsbetrag[:\s]*([0-9]+(?:[.,][0-9]+)*)",
    ],
    "vat_amount": [
        r"MwSt\s*[:\s]*([0-9]+(?:[.,][0-9]+)*)\s*(?:EUR|€)?",
        r"USt\s*[:\s]*([0-9]+(?:[.,][0-9]+)*)\s*(?:EUR|€)?",
        r"Steuer[:\s]*([0-9]+(?:[.,][0-9]+)*)\s*(?:EUR|€)?",
    ],
    "invoice_date": [
        r"Rechnungsdatum[:\s]*(\d{1,2}\.\d{1,2}\.\d{4})",
        r"Datum[:\s]*(\d{1,2}\.\d{1,2}\.\d{4})",
        r"Invoice\s*Date[:\s]*(\d{4}-\d{2}-\d{2})",
    ],
    "supplier_name": [
        r"Lieferant[:\s]+(.+?)(?:\n|$)",
        r"Verkäufer[:\s]+(.+?)(?:\n|$)",
    ],
}


def extract_text_from_pdf(pdf_bytes: bytes) -> str:
    """Extract all text content from PDF bytes.

    Args:
        pdf_bytes: Raw PDF file content as bytes

    Returns:
        Full text content from all PDF pages
    """
    pdf_stream = io.BytesIO(pdf_bytes)
    reader = PdfReader(pdf_stream)
    text_parts = []
    for page in reader.pages:
        text = page.extract_text()
        if text:
            text_parts.append(text)
    return "\n".join(text_parts)


def parse_german_number(num_str: str) -> float:
    """Convert number string to float, handling German and international formats.

    German format: 1.234,56 (thousands separator = dot, decimal separator = comma)
    International: 1,234.56 (thousands separator = comma, decimal separator = dot)
    """
    if "," in num_str and num_str.rfind(",") > num_str.rfind("."):
        return float(num_str.replace(".", "").replace(",", "."))
    else:
        return float(num_str.replace(",", ""))


def parse_german_date(date_str: str) -> str:
    """Convert German date (04.02.2025) to ISO format (2025-02-04)."""
    if "." in date_str and len(date_str.split(".")) == 3:
        day, month, year = date_str.split(".")
        return f"{year}-{month.zfill(2)}-{day.zfill(2)}"
    return date_str


def extract_from_text(text: str) -> dict:
    """Extract invoice key values from text using regex patterns.

    Args:
        text: PDF text content

    Returns:
        Dictionary with extracted values and confidence scores
    """
    result = {}

    for field_name, patterns in EXTRACTION_PATTERNS.items():
        value = None
        confidence = 0.0

        for pattern in patterns:
            match = re.search(pattern, text, re.IGNORECASE | re.MULTILINE)
            if match:
                raw_value = match.group(1).strip()

                if field_name.endswith("_amount"):
                    value = parse_german_number(raw_value)
                elif field_name == "invoice_date":
                    value = parse_german_date(raw_value)
                else:
                    value = raw_value

                pattern_index = patterns.index(pattern)
                confidence = 1.0 - (pattern_index * 0.1)
                break

        result[field_name] = value
        result[f"{field_name}_confidence"] = confidence

    return result
