import csv
import io
import json
import xml.etree.ElementTree as ET
from pathlib import Path

from bs4 import BeautifulSoup
from docx import Document as DocxDocument
from pypdf import PdfReader

from app.models.knowledge import FileType


def extract_text(storage_path: str, file_type: FileType) -> str:
    path = Path(storage_path)

    if file_type == FileType.pdf:
        reader = PdfReader(str(path))
        return "\n\n".join(page.extract_text() or "" for page in reader.pages)

    if file_type == FileType.docx:
        doc = DocxDocument(str(path))
        return "\n\n".join(p.text for p in doc.paragraphs if p.text.strip())

    if file_type in (FileType.txt, FileType.markdown):
        return path.read_text(encoding="utf-8", errors="ignore")

    if file_type == FileType.html:
        soup = BeautifulSoup(path.read_text(encoding="utf-8", errors="ignore"), "html.parser")
        for tag in soup(["script", "style"]):
            tag.decompose()
        return soup.get_text(separator="\n")

    if file_type == FileType.csv:
        text = path.read_text(encoding="utf-8", errors="ignore")
        reader = csv.reader(io.StringIO(text))
        rows = list(reader)
        if not rows:
            return ""
        header, *body = rows
        lines = []
        for row in body:
            pairs = ", ".join(f"{h}: {v}" for h, v in zip(header, row))
            lines.append(pairs)
        return "\n".join(lines)

    if file_type == FileType.json:
        data = json.loads(path.read_text(encoding="utf-8", errors="ignore"))
        return json.dumps(data, indent=2, ensure_ascii=False)

    if file_type == FileType.xml:
        tree = ET.parse(str(path))
        return ET.tostring(tree.getroot(), encoding="unicode", method="text")

    raise ValueError(f"Unsupported file type: {file_type}")
