from __future__ import annotations

import os
import sys
import tempfile
from datetime import datetime, timezone
from pathlib import Path


def _bridge_app():
    return sys.modules["services.asterisk_bridge_service.app"]


def fetch_recording_file(remote_path: str, file_name: str | None) -> tuple[Path, bool]:
    bridge = _bridge_app()
    source = Path(remote_path)
    if source.is_absolute() and source.exists():
        return source.resolve(), False

    if not bridge._sftp_enabled():
        raise RuntimeError("SFTP is not configured and remote_path is not a local file")

    try:
        import paramiko  # type: ignore
    except ImportError as exc:  # pragma: no cover - depends on runtime package set
        raise RuntimeError("paramiko is required for SFTP recording transfer") from exc

    safe_name = file_name or Path(remote_path).name or "asterisk-call.wav"
    suffix = Path(safe_name).suffix or ".wav"
    handle = tempfile.NamedTemporaryFile(prefix="mvpcc-ast-", suffix=suffix, delete=False)
    handle.close()
    target = Path(handle.name)

    transport = paramiko.Transport((bridge._sftp_host(), bridge._sftp_port()))
    try:
        transport.connect(username=bridge._sftp_username(), password=bridge._sftp_password())
        sftp = paramiko.SFTPClient.from_transport(transport)
        try:
            sftp.get(remote_path, str(target))
        finally:
            sftp.close()
    finally:
        transport.close()
    return target.resolve(), True


def recording_search_directories() -> list[str]:
    base = os.getenv("ASTERISK_SFTP_BASE_PATH", "/var/spool/asterisk/monitor").rstrip("/")
    return [f"{base}/mvpcc", base]


def guess_mime_type(file_name: str) -> str:
    lower = file_name.lower()
    if lower.endswith(".mp3"):
        return "audio/mpeg"
    if lower.endswith(".ogg"):
        return "audio/ogg"
    return "audio/wav"


def find_remote_recording_for_call(call_id: str) -> tuple[str, str, str, datetime] | None:
    bridge = _bridge_app()
    suffixes = (".wav", ".mp3", ".ogg")
    candidates: list[tuple[float, str, str]] = []

    if bridge._sftp_enabled():
        try:
            import paramiko  # type: ignore
        except ImportError:
            return None

        transport = paramiko.Transport((bridge._sftp_host(), bridge._sftp_port()))
        try:
            transport.connect(username=bridge._sftp_username(), password=bridge._sftp_password())
            sftp = paramiko.SFTPClient.from_transport(transport)
            try:
                for directory in recording_search_directories():
                    try:
                        names = sftp.listdir(directory)
                    except Exception:  # noqa: BLE001
                        continue
                    for name in names:
                        lower = name.lower()
                        if call_id not in name or not lower.endswith(suffixes):
                            continue
                        full_path = f"{directory}/{name}"
                        try:
                            st = sftp.stat(full_path)
                        except Exception:  # noqa: BLE001
                            continue
                        candidates.append((float(st.st_mtime), full_path, name))
            finally:
                sftp.close()
        finally:
            transport.close()
    else:
        for directory in recording_search_directories():
            root = Path(directory)
            if not root.exists():
                continue
            for file_path in root.glob(f"*{call_id}*"):
                if not file_path.is_file():
                    continue
                lower = file_path.name.lower()
                if not lower.endswith(suffixes):
                    continue
                candidates.append((file_path.stat().st_mtime, str(file_path), file_path.name))

    if not candidates:
        return None
    candidates.sort(key=lambda item: item[0], reverse=True)
    mtime, full_path, file_name = candidates[0]
    mtime_dt = datetime.fromtimestamp(mtime, tz=timezone.utc)
    return full_path, file_name, guess_mime_type(file_name), mtime_dt
