import requests
import time
import os
from pathlib import Path
from audio_splitter import split_audio
from requests_toolbelt.multipart.encoder import MultipartEncoder, MultipartEncoderMonitor
from requests.exceptions import ConnectionError, ReadTimeout, ChunkedEncodingError

BOT_TOKEN = os.environ["TELEGRAM_TOKEN"]
CHAT_ID = os.environ["CHAT_ID"]
MAX_RETRIES = 5

def progress_callback(monitor):
    percent = monitor.bytes_read / monitor.len * 100
    print(f"\rUploading: {percent:5.1f}%", end="", flush=True)

def send_message(text):
    url = f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage"
    r = requests.post(url, data={
        "chat_id": CHAT_ID,
        "text": text
    }, timeout=30)

    if not r.ok:
        print("Telegram message error:", r.text)

def upload_file(file_path, caption):
    url = f"https://api.telegram.org/bot{BOT_TOKEN}/sendAudio"

    for attempt in range(1, MAX_RETRIES + 1):
        print(f"Connecting to Telegram (attempt {attempt}/{MAX_RETRIES})")

        try:
            with open(file_path, "rb") as f:

                encoder = MultipartEncoder(
                    fields={
                        "chat_id": str(CHAT_ID),
                        "title": caption,
                        "audio": (file_path.name, f, "audio/mpeg"),
                    }
                )

                monitor = MultipartEncoderMonitor(encoder, progress_callback)

                print("Connection established, starting upload...")

                r = requests.post(
                    url,
                    data=monitor,
                    headers={"Content-Type": monitor.content_type},
                    timeout=(20, 3600)  # (connect_timeout, read_timeout)
                )

            print("\nServer responded:", r.status_code)

            if r.ok:
                print("Upload success")
                return True

            print("Telegram API error:", r.text)

        except ConnectionError:
            print("\nConnection dropped by Telegram")

        except ReadTimeout:
            print("\nUpload timed out")

        except ChunkedEncodingError:
            print("\nChunked encoding error (connection reset)")

        except Exception as e:
            print("\nUnexpected error:", repr(e))

        wait = 5 * attempt
        print(f"Retrying in {wait} sec...\n")
        time.sleep(wait)

    return False

def send_audio(file_path, title):
    parts = split_audio(Path(file_path))

    for i, part in enumerate(parts, start=1):
        caption = title
        if len(parts) > 1:
            caption = f"{title} (part {i}/{len(parts)})"

        print("Uploading:", part.name)

        success = upload_file(part, caption)
        if not success:
            return False   # upload failed -> KEEP files for retry

    # if we got here, ALL parts uploaded successfully -> cleanup
    for part in parts:
        part.unlink(missing_ok=True)
    # also delete the original mp3 if we were uploading split parts
    original = Path(file_path)
    if len(parts) > 1 and original.exists():
        original.unlink(missing_ok=True)

    return True
