from __future__ import annotations

from pathlib import Path
from urllib.parse import urlparse

from worai.errors import UsageError

from .debug_cloud import load_records_from_debug_cloud
from .file import load_urls_from_file
from .models import UrlRecord, UrlSourceOptions
from .sheets import is_spreadsheet_source, load_urls_from_sheet
from .sitemap import load_urls_from_sitemap


def _dedupe(values: list[str]) -> list[str]:
    seen: set[str] = set()
    out: list[str] = []
    for value in values:
        item = value.strip()
        if not item or item in seen:
            continue
        seen.add(item)
        out.append(item)
    return out


def _is_http_url(value: str) -> bool:
    parsed = urlparse(value)
    return parsed.scheme in {"http", "https"}


def _dedupe_records(records: list[UrlRecord]) -> list[UrlRecord]:
    seen: set[str] = set()
    out: list[UrlRecord] = []
    for record in records:
        url = record.url.strip()
        if not url or url in seen:
            continue
        seen.add(url)
        out.append(record)
    return out


def _normalize_records(records: list[UrlRecord]) -> list[UrlRecord]:
    out: list[UrlRecord] = []
    for record in records:
        url = record.url.strip()
        if not url:
            continue
        if _is_http_url(url):
            out.append(
                UrlRecord(
                    url=url,
                    html=record.html,
                    source_type=record.source_type,
                    source_ref=record.source_ref,
                    metadata=record.metadata,
                )
            )
    return _dedupe_records(out)


def resolve_url_records(options: UrlSourceOptions) -> list[UrlRecord]:
    source = options.source.strip()

    if (options.source_type or "").strip().lower() == "debug-cloud":
        return _normalize_records(load_records_from_debug_cloud(source))

    if is_spreadsheet_source(source):
        if not options.sheet_name:
            raise UsageError("When source is a Google Spreadsheet, --sheet-name is required.")
        rows = load_urls_from_sheet(
            source,
            options.sheet_name,
            client_secrets=options.client_secrets,
            token=options.token,
            port=options.port,
        )
        return _normalize_records(
            [UrlRecord(url=value, source_type="sheet", source_ref=source) for value in rows]
        )

    path = Path(source)
    if path.exists():
        if path.suffix.lower() in {".xml", ".gz"}:
            rows = load_urls_from_sitemap(str(path), timeout=options.timeout)
            return _normalize_records(
                [UrlRecord(url=value, source_type="sitemap", source_ref=str(path)) for value in rows]
            )
        rows = load_urls_from_file(path)
        return _normalize_records(
            [UrlRecord(url=value, source_type="file", source_ref=str(path)) for value in rows]
        )

    parsed = urlparse(source)
    if parsed.scheme in {"http", "https", "file"}:
        rows = load_urls_from_sitemap(source, timeout=options.timeout)
        return _normalize_records(
            [UrlRecord(url=value, source_type="sitemap", source_ref=source) for value in rows]
        )

    raise UsageError("SOURCE must be a sitemap URL/path, URL list file, or Google Spreadsheet URL/ID.")


def resolve_urls(options: UrlSourceOptions) -> list[str]:
    return [record.url for record in resolve_url_records(options)]
