"""
Word document parser implementation.
[AC-AISVC-34] Word (.docx) parsing using python-docx.

Extracts text content from Word documents.
"""

import logging
from pathlib import Path
from typing import Any

from app.services.document.base import (
    DocumentParseException,
    DocumentParser,
    ParseResult,
)

logger = logging.getLogger(__name__)


class WordParser(DocumentParser):
    """
    Parser for Word documents.
    [AC-AISVC-34] Uses python-docx for text extraction.
    """

    def __init__(self, include_headers: bool = True, include_footers: bool = True, **kwargs: Any):
        self._include_headers = include_headers
        self._include_footers = include_footers
        self._extra_config = kwargs
        self._docx = None

    def _get_docx(self):
        """Lazy import of python-docx."""
        if self._docx is None:
            try:
                from docx import Document
                self._docx = Document
            except ImportError:
                raise DocumentParseException(
                    "python-docx not installed. Install with: pip install python-docx",
                    parser="word"
                )
        return self._docx

    def parse(self, file_path: str | Path) -> ParseResult:
        """
        Parse a Word document and extract text content.
        [AC-AISVC-34] Extracts text while preserving paragraph structure.
        """
        path = Path(file_path)

        if not path.exists():
            raise DocumentParseException(
                f"File not found: {path}",
                file_path=str(path),
                parser="word"
            )

        if not self.supports_extension(path.suffix):
            raise DocumentParseException(
                f"Unsupported file extension: {path.suffix}",
                file_path=str(path),
                parser="word"
            )

        Document = self._get_docx()

        try:
            doc = Document(path)

            text_parts = []

            if self._include_headers:
                for section in doc.sections:
                    header = section.header
                    if header and header.paragraphs:
                        header_text = "\n".join(p.text for p in header.paragraphs if p.text.strip())
                        if header_text:
                            text_parts.append(f"[Header]\n{header_text}")

            for para in doc.paragraphs:
                if para.text.strip():
                    style_name = para.style.name if para.style else ""
                    if "Heading" in style_name:
                        text_parts.append(f"\n## {para.text}")
                    else:
                        text_parts.append(para.text)

            for table in doc.tables:
                table_text = self._format_table(table)
                if table_text.strip():
                    text_parts.append(f"\n[Table]\n{table_text}")

            if self._include_footers:
                for section in doc.sections:
                    footer = section.footer
                    if footer and footer.paragraphs:
                        footer_text = "\n".join(p.text for p in footer.paragraphs if p.text.strip())
                        if footer_text:
                            text_parts.append(f"[Footer]\n{footer_text}")

            full_text = "\n\n".join(text_parts)
            file_size = path.stat().st_size

            paragraph_count = len(doc.paragraphs)
            table_count = len(doc.tables)

            logger.info(
                f"Parsed Word: {path.name}, paragraphs={paragraph_count}, "
                f"tables={table_count}, chars={len(full_text)}, size={file_size}"
            )

            return ParseResult(
                text=full_text,
                source_path=str(path),
                file_size=file_size,
                metadata={
                    "format": "docx",
                    "paragraph_count": paragraph_count,
                    "table_count": table_count,
                }
            )

        except DocumentParseException:
            raise
        except Exception as e:
            raise DocumentParseException(
                f"Failed to parse Word document: {e}",
                file_path=str(path),
                parser="word",
                details={"error": str(e)}
            )

    def _format_table(self, table) -> str:
        """Format a table as text."""
        lines = []
        for row in table.rows:
            cells = [cell.text.strip() for cell in row.cells]
            lines.append(" | ".join(cells))
        return "\n".join(lines)

    def get_supported_extensions(self) -> list[str]:
        """Get supported file extensions."""
        return [".docx"]
