"""LTX Desktop ve ACE-Step backend'lerinin durumunu izleyen/başlatan servis.

Durum kontrolleri (wmic/netstat/HTTP) arka plan thread'inde yapılır;
UI thread'i asla blok edilmez.
"""
from __future__ import annotations
from pathlib import Path
import os
import subprocess
import sys
import threading
import time

from PySide6.QtCore import QObject, Signal

from pipeline import LTXClient, ACEStepClient

# Kök dizin: fiko-video-studio'nun bir üstü (video-uretim/)
KOK_DIZIN = Path(__file__).resolve().parent.parent.parent
LTX_BAT = KOK_DIZIN / "LTX-Desktop-WanGP-Baslat.bat"
ACE_BAT = KOK_DIZIN / "ACE-Step-1.5" / "start_api_server.bat"

_BAYRAK = 0x08000000 if sys.platform == "win32" else 0

# Kontrol aralığı. LTX bulunduğunda seyrekleştir.
ARALIK_ARAMA = 5.0     # LTX henüz bulunmadığında
ARALIK_SAGLIK = 10.0   # LTX bulunduğunda sadece health check


class BackendYonetici(QObject):
    """LTX ve ACE-Step backend durumlarını ayrı thread'de sorgular."""

    ltx_durumu = Signal(bool, str)
    ace_durumu = Signal(bool, str)
    log = Signal(str, str)

    def __init__(self, ltx_client: LTXClient, ace_client: ACEStepClient, parent=None):
        super().__init__(parent)
        self.ltx = ltx_client
        self.ace = ace_client
        self._son_ltx = None
        self._son_ace = None

        self._calisiyor = False
        self._thread: threading.Thread | None = None

    # --------------------------------------------------------------- yaşam
    def basla(self) -> None:
        if self._calisiyor:
            return
        self._calisiyor = True
        self._thread = threading.Thread(target=self._dongu, daemon=True)
        self._thread.start()

    def dur(self) -> None:
        self._calisiyor = False

    # ------------------------------------------------------------- kontrol
    def _dongu(self) -> None:
        while self._calisiyor:
            aralik = self._tek_tur()
            # Küçük dilimler halinde uyu ki dur() hızlı cevap versin
            for _ in range(int(aralik * 10)):
                if not self._calisiyor:
                    return
                time.sleep(0.1)

    def _tek_tur(self) -> float:
        # LTX
        try:
            ltx_ok, url = self._ltx_kontrol()
        except Exception:
            ltx_ok, url = False, ""
        if ltx_ok != self._son_ltx:
            self.ltx_durumu.emit(ltx_ok, url)
            self._son_ltx = ltx_ok

        # ACE-Step
        try:
            ace_ok = self.ace.saglikli_mi()
        except Exception:
            ace_ok = False
        if ace_ok != self._son_ace:
            self.ace_durumu.emit(ace_ok, self.ace.api_url if ace_ok else self.ace.api_url)
            self._son_ace = ace_ok

        return ARALIK_SAGLIK if ltx_ok else ARALIK_ARAMA

    def _ltx_kontrol(self) -> tuple[bool, str]:
        """Mevcut URL sağlıklıysa koru, değilse yeniden ara."""
        # Mevcut URL sağlıklı mı?
        if self.ltx.api_url:
            d = self.ltx.durum()
            if d is not None:
                return True, self.ltx.api_url
            # API çalışıyor ama auth değişmiş olabilir — bir kez token'ı yeniden dene
            if self.ltx.baglan() and self.ltx.durum() is not None:
                return True, self.ltx.api_url
            # Ayakta değil — sıfırla
            self.ltx.api_url = ""

        # Port tara
        url = LTXClient.portu_bul()
        if not url:
            return False, ""
        self.ltx.api_url = url
        if not self.ltx.token:
            try:
                self.ltx.token = self.ltx.token_kesfet(url) or ""
            except Exception:
                pass
        return True, url

    # --------------------------------------------------------- başlatma
    def _bat_calistir(self, bat: Path, cwd: Path) -> None:
        """BAT dosyasını yeni/görünür konsol penceresinde çalıştırır."""
        if sys.platform == "win32":
            # CREATE_NEW_CONSOLE: yeni görünür pencere aç
            subprocess.Popen(
                ["cmd", "/c", str(bat)],
                cwd=str(cwd),
                creationflags=0x00000010,  # CREATE_NEW_CONSOLE
                close_fds=True,
            )
        else:
            subprocess.Popen(["bash", str(bat)], cwd=str(cwd))

    def ltx_baslat(self) -> bool:
        if not LTX_BAT.exists():
            self.log.emit("hata", f"LTX başlatıcı bulunamadı: {LTX_BAT}")
            return False
        try:
            self._bat_calistir(LTX_BAT, KOK_DIZIN)
            self.log.emit("bilgi", "LTX Desktop başlatılıyor (ilk yükleme uzun sürebilir)...")
            return True
        except Exception as e:
            self.log.emit("hata", f"LTX başlatma hatası: {e}")
            return False

    def ace_baslat(self) -> bool:
        if not ACE_BAT.exists():
            self.log.emit("hata", f"ACE-Step başlatıcı bulunamadı: {ACE_BAT}")
            return False
        try:
            self._bat_calistir(ACE_BAT, ACE_BAT.parent)
            self.log.emit("bilgi", "ACE-Step API başlatılıyor (model yükleme 1-2 dk)...")
            return True
        except Exception as e:
            self.log.emit("hata", f"ACE-Step başlatma hatası: {e}")
            return False
