#!/bin/bash
# 🎙️ Transcriptor — Instalador + Build .app para macOS
# Salve como "Transcriptor Installer.command" e dê duplo-clique

set -e

APP_NAME="Transcriptor"
VERSION="1.0.0"
INSTALL_DIR="$HOME/.transcriptor"
APP_DIR="$INSTALL_DIR/app"
BUILD_DIR="$INSTALL_DIR/build"

clear
echo "╔══════════════════════════════════════════════╗"
echo "║     🎙️  $APP_NAME $VERSION           ║"
echo "║  Transcrição automática de reuniões          ║"
echo "╚══════════════════════════════════════════════╝"
echo ""

if [ "$(uname)" != "Darwin" ]; then
    echo "❌ Apenas macOS. Detectado: $(uname)"
    read -p "Enter para sair..."
    exit 1
fi

# ─── 1. Homebrew ──────────────────────────────────
echo "[1/5] Verificando Homebrew..."
if ! command -v brew &>/dev/null; then
    echo "  → Instalando..."
    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    [ -f "/opt/homebrew/bin/brew" ] && eval "$(/opt/homebrew/bin/brew shellenv)"
fi
echo "  ✅ Homebrew: $(brew --version | head -1)"

# ─── 2. BlackHole ─────────────────────────────────
echo ""
echo "[2/5] Verificando BlackHole..."
if ! system_profiler SPAudioDataType 2>/dev/null | grep -q "BlackHole"; then
    echo "  → Instalando blackhole-2ch..."
    brew install blackhole-2ch
    echo ""
    echo "  ⚠️  Configure o áudio agora:"
    echo "  1. Abra Utilitário de Áudio MIDI (Audio MIDI Setup)"
    echo "  2. Clique + → Criar Dispositivo Multi-Saída"
    echo "  3. Marque BlackHole 2ch + seus fones"
    echo "  4. Ajustes de Som → Saída → selecione o Multi-Saída"
    echo ""
    read -p "  Enter após configurar..."
else
    echo "  ✅ BlackHole OK"
fi

# ─── 3. ffmpeg ────────────────────────────────────
echo ""
echo "[3/5] Verificando ffmpeg..."
brew install ffmpeg 2>/dev/null || true
echo "  ✅ ffmpeg: $(ffmpeg -version 2>&1 | head -1)"

# ─── 4. Instalar app + compilar .app ──────────────
echo ""
echo "[4/5] Instalando e compilando $APP_NAME..."
mkdir -p "$APP_DIR"

# ====== CÓDIGO DO APP (auto-contido) ======

cat > "$APP_DIR/config.py" << 'PYEOF'
import json; from pathlib import Path
d = {"server_url":"https://transcribe.gmec-apps.com.br","default_language":"pt","global_vocabulary":"","monitor_teams":True,"monitor_chrome":True,"auto_start_recording":True,"auto_start_app":True,"record_mic":False,"output_dir":str(Path.home()/".transcriptor"/"recordings")}
p = Path.home()/".transcriptor"/"config.json"
def load():
    if p.exists():
        try:
            with open(p) as f: c = json.load(f)
            for k,v in d.items(): c.setdefault(k,v)
            return c
        except: pass
    return dict(d)
def save(c):
    Path(p.parent).mkdir(parents=True,exist_ok=True)
    with open(p,"w") as f: json.dump(c,f,indent=2)
PYEOF

cat > "$APP_DIR/detector.py" << 'PYEOF'
import subprocess
K = {"Microsoft Teams":["reunião","meeting","chamada","call","ongoing","sala","room"],"Google Chrome":["google meet","meet.google.com","meet","videoconferência"],"Chromium":["google meet","meet"],"Edge":["google meet","meet"],"Brave Browser":["google meet","meet"]}
def check():
    r = {"in_meeting":False,"app":None,"title":None}
    try:
        p = subprocess.run(["osascript","-e",'tell app "System Events" to get name of every process whose background only is false'],capture_output=True,text=True,timeout=5)
        if p.returncode!=0: return r
        apps = [a.strip() for a in p.stdout.strip().split(", ")]
    except: return r
    for an,kw in K.items():
        for ra in apps:
            if an.lower() not in ra.lower(): continue
            try:
                s = subprocess.run(["osascript","-e",f'tell app "System Events" to get name of every window of first process whose name is "{ra}"'],capture_output=True,text=True,timeout=3)
                for t in [t.strip() for t in s.stdout.strip().split(", ") if t.strip()]:
                    for k in kw:
                        if k in t.lower(): r["in_meeting"]=True; r["app"]=ra; r["title"]=t; return r
            except: pass
    return r
PYEOF

cat > "$APP_DIR/recorder.py" << 'PYEOF'
import subprocess,os,time,signal; from pathlib import Path; from datetime import datetime
class R:
    def __init__(s,o=None):
        s.o=Path(o or Path.home()/".transcriptor"/"recordings"); s.o.mkdir(parents=True,exist_ok=True)
        s._p=None; s._f=None; s._r=False
    @property
    def is_recording(s): return s._r
    def start(s,d="BlackHole 2ch"):
        if s._r: return s._f
        p=s.o/f"reuniao_{datetime.now().strftime('%Y%m%d_%H%M%S')}.wav"
        try:
            s._p=subprocess.Popen(["ffmpeg","-y","-f","avfoundation","-i",f":{d}","-ac","1","-ar","16000","-sample_fmt","s16","-acodec","pcm_s16le",str(p)],stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL,preexec_fn=os.setsid)
            s._f=p; s._r=True; time.sleep(1)
            if s._p.poll()is not None: s._r=False; s._f=None; return None
            return p
        except: return None
    def stop(s):
        if not s._r or not s._p: return None
        p=s._f
        try:
            os.killpg(os.getpgid(s._p.pid),signal.SIGINT)
            try: s._p.wait(10)
            except: os.killpg(os.getpgid(s._p.pid),signal.SIGKILL)
        except:
            try: s._p.kill()
            except: pass
        s._p=None; s._r=False; s._f=None
        return p if p and p.exists() and p.stat().st_size>1000 else None
PYEOF

cat > "$APP_DIR/uploader.py" << 'PYEOF'
import requests,json,shutil; from pathlib import Path
class U:
    def __init__(s,u="https://transcribe.gmec-apps.com.br",q=None):
        s.u=u.rstrip("/"); s.q=Path(q or Path.home()/".transcriptor"/"queue"); s.q.mkdir(parents=True,exist_ok=True)
    def upload(s,ap,title="",lang="pt",vocab=""):
        t=title or ap.stem
        try:
            with open(ap,"rb") as f:
                r=requests.post(f"{s.u}/api/transcribe",files={"file":(ap.name,f,"audio/wav")},data={"title":t,"language":lang,"vocabulary":vocab},timeout=300)
            if r.status_code==200:
                tid=r.json().get("transcript_id"); print(f"[Upload] ✅ {t} → {tid}"); return tid
        except: print("[Upload] 🔌 Offline, enfileirando...")
        shutil.copy2(ap,s.q/ap.name)
        with open(s.q/f"{ap.name}.meta","w") as f: json.dump({"title":t,"language":lang},f)
        return None
PYEOF

cat > "$APP_DIR/app.py" << 'PYEOF'
import rumps,threading,time,webbrowser,os,sys; from pathlib import Path
sys.path.insert(0,str(Path(__file__).parent))
from config import load as cfg; from detector import check as detect; from recorder import R as Rec; from uploader import U as Up

class App(rumps.App):
    def __init__(s):
        super().__init__("🎙️",title="🎙️")
        s.c=cfg(); s.rec=Rec(o=Path(s.c.get("output_dir","~/.transcriptor/recordings")).expanduser())
        s.up=Up(u=s.c.get("server_url","https://transcribe.gmec-apps.com.br"))
        s._m=s.c.get("auto_start_recording",True); s._in=False
        s._b(); s._update()
        if s._m: threading.Thread(target=s._loop,daemon=True).start()
    def _b(s):
        s.menu.clear()
        s._si=rumps.MenuItem("🟢"); s._st=rumps.MenuItem("▶ Iniciar",callback=lambda _:s._start())
        s._sp=rumps.MenuItem("⏹ Parar",callback=lambda _:s._stop())
        s.menu=[s._si,None,s._st,s._sp,None,
            rumps.MenuItem("📋 Transcrições",callback=lambda _:webbrowser.open(s.c.get("server_url","")+"/history")),
            rumps.MenuItem("🔍 Buscar",callback=lambda _:webbrowser.open(s.c.get("server_url","")+"/search")),
            rumps.MenuItem("⚙️ Config",callback=lambda _:webbrowser.open(s.c.get("server_url","")+"/config")),
            None,rumps.MenuItem("🌐 Abrir Site",callback=lambda _:webbrowser.open(s.c.get("server_url","")))]
    def _update(s):
        if s.rec.is_recording: s.title="🔴"; s._si.title="🔴 Gravando..."
        elif s._in: s.title="🟡"; s._si.title="🟡 Em reunião"
        else: s.title="🎙️"; s._si.title="🟢 Aguardando"
    def _start(s):
        if s.rec.start(): rumps.notification("Transcriptor","▶️ Gravando","Áudio sendo capturado...")
        else: rumps.notification("Transcriptor","❌ Erro","brew install blackhole-2ch")
        s._update()
    def _stop(s):
        p=s.rec.stop(); s._update()
        if p: rumps.notification("Transcriptor","⏹️ Gravado","Transcrevendo..."); s.up.upload(p,lang=s.c.get("default_language","pt"))
    def _loop(s):
        while s._m:
            try:
                w=s._in; r=s.rec.is_recording; d=detect(); s._in=d["in_meeting"]
                if s._in and not w and s.c.get("auto_start_recording",True):
                    p=s.rec.start()
                    if p: rumps.notification("Transcriptor","🔴 Reunião",f"Gravando: {d['app']}")
                elif not s._in and w and r:
                    p=s.rec.stop()
                    if p: s.up.upload(p,lang=s.c.get("default_language","pt"))
                s._update()
            except: pass
            time.sleep(5)
if __name__=="__main__": App().run()
PYEOF

chmod +x "$APP_DIR/app.py"

# Instala dependências
python3 -m venv "$INSTALL_DIR/.venv" 2>/dev/null
source "$INSTALL_DIR/.venv/bin/activate" 2>/dev/null
pip install -q --upgrade pip
pip install -q rumps requests py2app setuptools

# ─── 5. Compilar .app e criar atalho ─────────────
echo ""
echo "[5/5] Compilando $APP_NAME.app..."

mkdir -p "$BUILD_DIR"
cp -r "$APP_DIR"/*.py "$BUILD_DIR/"

# Cria setup.py pro py2app
cat > "$BUILD_DIR/setup.py" << 'PYEOF'
from setuptools import setup
setup(
    name="Transcriptor",
    app=["app.py"],
    options={"py2app": {
        "argv_emulation": False,
        "plist": {
            "CFBundleName": "Transcriptor",
            "CFBundleDisplayName": "Transcriptor",
            "CFBundleIdentifier": "com.gmec-apps.transcriptor",
            "CFBundleVersion": "1.0.0",
            "LSUIElement": True,
            "NSMicrophoneUsageDescription": "Gravar áudio das reuniões.",
        },
        "packages": ["rumps","requests"],
        "includes": ["config","detector","recorder","uploader"],
        "excludes": ["tkinter","PyQt5","PySide","matplotlib","numpy","scipy","pandas"],
    }},
    setup_requires=["py2app"],
)
PYEOF

cd "$BUILD_DIR"
python3 setup.py py2app 2>&1 | grep -iv "copying\|reading\|creating"

# Copia .app pro diretório de instalação
if [ -d "dist/Transcriptor.app" ]; then
    rm -rf "$INSTALL_DIR/Transcriptor.app" 2>/dev/null
    cp -r "dist/Transcriptor.app" "$INSTALL_DIR/"
    echo "  ✅ .app compilado!"
else
    echo "  ⚠️  Compilação falhou. Usando modo script."
fi

# Cria atalho pra rodar modo script
LAUNCHER="$INSTALL_DIR/Iniciar Transcriptor.command"
cat > "$LAUNCHER" << EOF
#!/bin/bash
cd "$APP_DIR"
source "$INSTALL_DIR/.venv/bin/activate" 2>/dev/null
python3 app.py
EOF
chmod +x "$LAUNCHER"

cd "$INSTALL_DIR"

clear
echo "╔══════════════════════════════════════════════╗"
echo "║     ✅  $APP_NAME instalado!          ║"
echo "╚══════════════════════════════════════════════╝"
echo ""

if [ -d "$INSTALL_DIR/Transcriptor.app" ]; then
    echo "📦 .app compilado: $INSTALL_DIR/Transcriptor.app"
    echo ""
    echo "👉 Para instalar no Applications:"
    echo "   cp -r \"$INSTALL_DIR/Transcriptor.app\" /Applications/"
    echo "   open /Applications/Transcriptor.app"
    echo ""
    echo "   (Na 1ª vez: Ctrl+clique → Abrir)"
else
    echo "👉 Para iniciar:"
    echo "   Duplo-clique em: $INSTALL_DIR/Iniciar Transcriptor.command"
fi

echo ""
echo "O icone 🎙️ aparece na barra de menus."
echo ""

open "$INSTALL_DIR"
read -p "Pressione Enter para sair..."
