#!/home/user/adhan/venv/bin/python3
"""
Connect to Google Nest Mini and play the Adhan audio.
Supports prayer-specific audio files served via local HTTP.
Usage: cast_adhan.py "Fajr"
"""
import os
import sys
import time
import pychromecast
from datetime import datetime

CONFIG_FILE = "/home/user/adhan/config.env"
config = {}
with open(CONFIG_FILE) as f:
    for line in f:
        line = line.strip()
        if line and not line.startswith("#") and "=" in line:
            key, val = line.split("=", 1)
            config[key.strip()] = val.strip()

CAST_NAME = config["CAST_NAME"]
LOG_FILE = "/home/user/adhan/adhan.log"

# Prayer-specific audio files — must be HTTPS URLs (Nest Mini rejects HTTP and self-signed certs)
# Falls back to DEFAULT_AUDIO_URL if prayer not in this map
FAJR_AUDIO_URL = config.get("FAJR_AUDIO_URL",
    "https://hpt520.tail4ddd0.ts.net/fajr_azaan.mp3")
PRAYER_AUDIO = {
    "Fajr": FAJR_AUDIO_URL,
}

# Default audio URL for prayers without a specific file
DEFAULT_AUDIO_URL = config.get("AUDIO_URL", "https://www.islamcan.com/audio/adhan/azan1.mp3")


def log(msg):
    timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    line = "[{}] {}".format(timestamp, msg)
    print(line)
    try:
        with open(LOG_FILE, "a") as f:
            f.write(line + "\n")
    except Exception:
        pass


def cast_audio(prayer_name):
    audio_url = PRAYER_AUDIO.get(prayer_name, DEFAULT_AUDIO_URL)
    log("=== {} Adhan ===".format(prayer_name))
    log("Audio: {}".format(audio_url))
    log("Looking for device \"{}\"...".format(CAST_NAME))

    # Try name-based discovery first
    chromecasts, browser = pychromecast.get_listed_chromecasts(
        friendly_names=[CAST_NAME],
        discovery_timeout=8,
    )

    if not chromecasts:
        log("Name discovery failed. Trying direct IP from config...")
        fallback_ip = config.get("CAST_IP", "")
        if fallback_ip:
            try:
                cast = pychromecast.Chromecast(fallback_ip)
                cast.wait(timeout=10)
                log("Direct connect OK: {} @ {}:{}".format(
                    cast.cast_info.friendly_name,
                    cast.cast_info.host,
                    cast.cast_info.port))
            except Exception as e:
                log("ERROR: Direct connect failed: {}".format(e))
                sys.exit(1)
        else:
            log("ERROR: Device \"{}\" not found and no CAST_IP configured".format(CAST_NAME))
            sys.exit(1)
    else:
        cast = chromecasts[0]
        cast.wait(timeout=10)

    ci = cast.cast_info
    log("Connected to \"{}\" ({} @ {}:{})".format(
        ci.friendly_name, ci.model_name, ci.host, ci.port))

    # Ensure volume is audible
    try:
        if cast.status.volume_muted:
            cast.set_volume_muted(False)
            log("Unmuted device")
        if cast.status.volume_level < 0.2:
            cast.set_volume(0.5)
            log("Set volume to 0.5")
        log("Volume: {:.0%}{}".format(
            cast.status.volume_level,
            " (muted)" if cast.status.volume_muted else ""))
    except Exception as e:
        log("Volume check skipped: {}".format(e))

    try:
        mc = cast.media_controller

        # Stop any existing playback
        try:
            mc.stop()
            time.sleep(0.5)
        except Exception:
            pass

        # Play the audio
        mc.play_media(audio_url, "audio/mpeg", autoplay=True)
        log("play_media sent, waiting for active state...")

        mc.block_until_active(timeout=15)
        log("Player state after block_until_active: {}".format(
            mc.status.player_state if mc.status else "unknown"))

        # FIX: If state is PAUSED, explicitly resume
        if mc.status and mc.status.player_state == "PAUSED":
            log("State is PAUSED - sending explicit play() command")
            mc.play()
            time.sleep(3)
            mc.update_status()
            log("State after play(): {}".format(
                mc.status.player_state if mc.status else "unknown"))

        # Monitor playback
        max_wait = 480  # max 8 minutes
        waited = 0
        was_playing = False
        while waited < max_wait:
            time.sleep(5)
            waited += 5
            mc.update_status()
            status = mc.status
            if status:
                if status.player_state == "PLAYING":
                    was_playing = True
                    # Don't log every 5s to reduce noise
                elif status.player_state in ("IDLE", "STOPPED"):
                    if was_playing:
                        # Actually finished (was playing before, now idle)
                        log("Playback finished after {}s (state={})".format(
                            waited, status.player_state))
                        break
                    elif waited >= 15:
                        # Never started playing after 15s — likely a load failure
                        log("Playback failed to start after {}s (state={})".format(
                            waited, status.player_state))
                        break
                    # else: transitional IDLE, wait for playback to start
                elif status.player_state == "PAUSED":
                    log("State PAUSED at {}s - attempting resume".format(waited))
                    mc.play()
            else:
                log("No status at {}s".format(waited))
        else:
            log("Playback timeout after {}s".format(max_wait))

    except Exception as e:
        log("ERROR during cast: {}".format(e))
        import traceback
        log(traceback.format_exc())
        sys.exit(1)
    finally:
        try:
            cast.disconnect()
            log("Disconnected")
        except Exception:
            pass


def main():
    prayer_name = sys.argv[1] if len(sys.argv) > 1 else "Adhan"
    cast_audio(prayer_name)


if __name__ == "__main__":
    main()
