"""
Abertura de ficheiros e pastas com a aplicação predefinida do sistema.

No Windows, ``os.startfile`` por vezes falha (PyInstaller, políticas, associações);
usamos ``cmd /c start`` e ``explorer`` / ``webbrowser`` como alternativas.
"""

from __future__ import annotations

import os
import subprocess
import sys
import webbrowser
from pathlib import Path

from .app_console import fc_log, fc_log_exc


def open_path_with_default_app(path: str, *, log_tag: str = "shell_open") -> bool:
    """
    Abre um ficheiro ou pasta com a aplicação predefinida.
    Retorna True se algum método foi invocado sem exceção final.
    """
    try:
        p = os.path.normpath(os.path.abspath(path))
    except Exception as e:
        fc_log_exc(log_tag, "open_path: caminho invalido", e)
        return False
    if not os.path.exists(p):
        fc_log(log_tag, f"open_path: nao existe: {p}")
        return False

    if sys.platform == "win32":
        return _open_windows(p, log_tag=log_tag)

    # macOS
    if sys.platform == "darwin":
        try:
            subprocess.Popen(["open", p], close_fds=True)
            return True
        except OSError as e:
            fc_log_exc(log_tag, "open_path: open (macOS) falhou", e)
    else:
        # Linux e outros Unix
        try:
            subprocess.Popen(["xdg-open", p], close_fds=True)
            return True
        except OSError as e:
            fc_log_exc(log_tag, "open_path: xdg-open falhou", e)

    try:
        uri = Path(p).as_uri()
        if webbrowser.open(uri):
            return True
    except Exception as e:
        fc_log_exc(log_tag, "open_path: webbrowser falhou", e)
    return False


def _open_windows(p: str, *, log_tag: str) -> bool:
    if os.path.isdir(p):
        try:
            os.startfile(p)  # type: ignore[attr-defined]
            return True
        except OSError as e:
            fc_log_exc(log_tag, "open_path dir: startfile falhou", e)
        try:
            subprocess.Popen(["explorer.exe", p], close_fds=True)
            return True
        except OSError as e:
            fc_log_exc(log_tag, "open_path dir: explorer falhou", e)
        try:
            subprocess.Popen(
                [os.environ.get("COMSPEC", "cmd.exe"), "/c", "start", "", p],
                close_fds=True,
            )
            return True
        except OSError as e:
            fc_log_exc(log_tag, "open_path dir: cmd start falhou", e)
        return False

    try:
        os.startfile(p)  # type: ignore[attr-defined]
        return True
    except OSError as e:
        fc_log_exc(log_tag, "open_path file: startfile falhou", e)
    try:
        subprocess.Popen(
            [os.environ.get("COMSPEC", "cmd.exe"), "/c", "start", "", p],
            close_fds=True,
        )
        return True
    except OSError as e:
        fc_log_exc(log_tag, "open_path file: cmd start falhou", e)
    try:
        uri = Path(p).as_uri()
        if webbrowser.open(uri):
            return True
    except Exception as e:
        fc_log_exc(log_tag, "open_path file: webbrowser falhou", e)
    return False
