#!/usr/bin/env python3
"""Telegram bot: receives audio files, transcribes with faster-whisper, replies with text."""
import json, os, time, tempfile
import requests

DIR = os.path.dirname(os.path.abspath(__file__))
CFG = json.load(open(os.path.join(DIR, 'config.json')))
BOT = f"https://api.telegram.org/bot{CFG['telegram_bot_token']}"
ALLOWED = {CFG['chat_id']}

os.environ['PATH'] = '/home/admin/.local/bin:' + os.environ.get('PATH', '')

# Model loaded lazily on first transcription to save memory
_model = None

def get_model():
    global _model
    if _model is None:
        from faster_whisper import WhisperModel
        print("Loading faster-whisper tiny model...")
        _model = WhisperModel("tiny", device="cpu", compute_type="int8")
        print("Model loaded.")
    return _model


def get_updates(offset=None):
    params = {'timeout': 30}
    if offset:
        params['offset'] = offset
    try:
        r = requests.get(f"{BOT}/getUpdates", params=params, timeout=35)
        return r.json().get('result', [])
    except Exception:
        return []


def send_msg(chat_id, text):
    while text:
        chunk = text[:4000]
        requests.post(f"{BOT}/sendMessage", json={
            'chat_id': chat_id, 'text': chunk
        }, timeout=15)
        text = text[4000:]
        if text:
            time.sleep(0.5)


def download_file(file_id):
    r = requests.get(f"{BOT}/getFile", params={'file_id': file_id}, timeout=10).json()
    file_path = r['result']['file_path']
    url = f"https://api.telegram.org/file/bot{CFG['telegram_bot_token']}/{file_path}"
    resp = requests.get(url, timeout=120)
    ext = os.path.splitext(file_path)[1] or '.ogg'
    tmp = tempfile.NamedTemporaryFile(delete=False, suffix=ext, dir='/tmp')
    tmp.write(resp.content)
    tmp.close()
    return tmp.name


def transcribe(filepath):
    model = get_model()
    segments, info = model.transcribe(filepath, language='en')
    text = ' '.join(seg.text.strip() for seg in segments)
    return text


def main():
    print("Transcribe bot started. Waiting for audio messages...")
    offset = None
    while True:
        updates = get_updates(offset)
        for u in updates:
            offset = u['update_id'] + 1
            msg = u.get('message', {})
            chat_id = msg.get('chat', {}).get('id')

            if chat_id not in ALLOWED:
                continue

            file_id = None
            fname = ''
            if msg.get('audio'):
                file_id = msg['audio']['file_id']
                fname = msg['audio'].get('file_name', 'audio')
            elif msg.get('voice'):
                file_id = msg['voice']['file_id']
                fname = 'voice message'
            elif msg.get('video_note'):
                file_id = msg['video_note']['file_id']
                fname = 'video note'
            elif msg.get('document'):
                mime = msg['document'].get('mime_type', '')
                if mime.startswith('audio/') or mime.startswith('video/') or \
                   msg['document'].get('file_name', '').split('.')[-1].lower() in \
                   ('mp3', 'wav', 'ogg', 'flac', 'm4a', 'aac', 'wma', 'mp4', 'webm'):
                    file_id = msg['document']['file_id']
                    fname = msg['document'].get('file_name', 'document')

            if not file_id:
                continue

            print(f"Received: {fname} from {chat_id}")
            send_msg(chat_id, f"'{fname}' 텍스트 추출 중...")

            filepath = None
            try:
                filepath = download_file(file_id)
                text = transcribe(filepath)

                if text.strip():
                    send_msg(chat_id, f"[Transcription] {fname}\n\n{text.strip()}")
                else:
                    send_msg(chat_id, "텍스트를 추출하지 못했습니다.")
                print(f"  Transcribed: {len(text)} chars")
            except Exception as e:
                send_msg(chat_id, f"오류 발생: {e}")
                print(f"  Error: {e}")
            finally:
                if filepath:
                    try:
                        os.unlink(filepath)
                    except Exception:
                        pass


if __name__ == '__main__':
    main()
