from bs4 import BeautifulSoup
import re
import io
import gzip
from .. import models


async def packages_parser(html: str, url: str, client=None):
    soup = BeautifulSoup(html, "html.parser")
    pre_tag = soup.find("pre")
    if not pre_tag:
        return {}

    pre_text = pre_tag.get_text(strip=True)
    if "Было удалено вложение" in pre_text and "attachment" in pre_text:
        attachment_link = pre_tag.find("a", href=True)
        if attachment_link and client:
            attachment_url = attachment_link["href"]
            compressed_data = await client.get_bytes(attachment_url)
            with gzip.GzipFile(fileobj=io.BytesIO(compressed_data)) as gz:
                text = gz.read().decode('utf-8')
        else:
            return models.PackagesModel(**{"added": [], "removed": [], "updated": [], "url": "none"})
    else:
        text = pre_tag.get_text()

    lines = text.strip().splitlines()
    sections = {"added": [], "removed": [], "updated": []}
    current_section = None
    current_package = {}
    seen_changelog = False

    for line in lines:
        # Смена секции
        if re.search(r"^\s*\d+\s+ADDED package[s]?", line):
            if current_package and current_section:
                sections[current_section].append(current_package)
            current_section = "added"
            current_package = {}
            seen_changelog = False
            continue
        elif re.search(r"^\s*\d+\s+REMOVED package[s]?", line):
            if current_package and current_section:
                sections[current_section].append(current_package)
            current_section = "removed"
            current_package = {}
            seen_changelog = False
            continue
        elif re.search(r"^\s*\d+\s+UPDATED packages[s]?", line):
            if current_package and current_section:
                sections[current_section].append(current_package)
            current_section = "updated"
            current_package = {}
            seen_changelog = False
            continue

        if current_section == "removed":
            if line.strip():
                parts = line.strip().split("\t")
                if len(parts) == 2:
                    name, version = parts
                    sections["removed"].append({
                        "name": name.strip(),
                        "version": version.strip()
                    })
            continue

        match = re.match(r"^(\S+)\s+-\s+(.*)", line)
        if match and not line.startswith("- "):
            if current_package and current_section:
                sections[current_section].append(current_package)

            current_package = {
                "name": match.group(1),
                "description": _clean_description(match.group(2)),
            }
            seen_changelog = False
            continue

        if (
            current_package
            and current_section != "removed"
            and not seen_changelog
        ):
            match = re.match(r"^\*\s+\w+\s+\w+\s+\d+\s+\d+\s+(.+?) <([^@\s>]+)(?:@altlinux| на altlinux)>", line)
            if match:
                current_package["maintainer_name"] = match.group(1).strip()
                current_package["maintainer_nick"] = match.group(2).strip()
                seen_changelog = True
            continue

        match = re.search(r'^Total (\d+) source packages\.$', line)
        if match:
            sections["total"] = int(match.group(1))

    if current_package and current_section:
        sections[current_section].append(current_package)
    
    sections["url"] = url

    return models.PackagesModel(**sections)


def _clean_description(desc: str):
    desc = desc.strip()
    desc = re.sub(r'\s+', ' ', desc)
    desc = re.sub(r'\[\d+[KMG]?\]', '', desc).strip()
    return desc
