from flask import Flask, request
from telegram import Bot, Update
from telegram.ext import Application, CommandHandler, MessageHandler, filters, ContextTypes
import requests
import logging
import threading
import os
from supabase import create_client, Client

# 📋 로그 설정
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Telegram Bot Token 및 N8N Webhook URL 설정
TELEGRAM_TOKEN = "7826854238:AAEQ8HoyFirFYE38-b5Z-5hiRZ4fPws34wY"
N8N_WEBHOOK_URL_SEARCH = "https://n8n.jjickjjicks.com/webhook/receive-bot-data"
N8N_WEBHOOK_URL_MAP = "https://n8n.jjickjjicks.com/webhook/receive-map-data"  # 새 Webhook 추가
N8N_WEBHOOK_URL_MOEF_SEARCH = "https://n8n.jjickjjicks.com/webhook/receive-moef-bot-data"
N8N_WEBHOOK_URL_MOEF_MAP = "https://n8n.jjickjjicks.com/webhook/receive-moef-map-data"  # 새 Webhook 추가
SUPABASE_URL = "https://eswjvuhysqjrkofuqoaq.supabase.co"
SUPABASE_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImVzd2p2dWh5c3FqcmtvZnVxb2FxIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MzQxNTc5OTMsImV4cCI6MjA0OTczMzk5M30.fxcd3--rTYfFjHlbx0e7k_7gL_Kf7taOrzWxdHHsKyQ"

# 📌 Supabase 클라이언트
supabase: Client = create_client(SUPABASE_URL, SUPABASE_KEY)

# 봇 초기화
bot = Bot(token=TELEGRAM_TOKEN)
app = Flask(__name__)

# 🚀 N8N으로 데이터 전송 함수 (검색 및 조직도 요청)
def send_to_n8n(webhook_url, data):
    """Telegram에서 받은 데이터를 n8n으로 전달"""
    try:
        response = requests.post(webhook_url, json=data)
        logger.info(f"✅ N8N으로 데이터 전송 성공 ({webhook_url}): {data}")
        return response.status_code
    except requests.exceptions.RequestException as e:
        logger.error(f"❌ N8N 전송 실패 ({webhook_url}): {e}")
        return None

# 📍 `/motie_map` 명령어 처리 (조직도 요청)
async def motie_map(update: Update, context: ContextTypes.DEFAULT_TYPE):
    chat_id = update.effective_chat.id
    logger.info(f"📍 /motie_map 요청 수신 - Chat ID: {chat_id}")

    # 🔹 N8N으로 조직도 요청
    send_to_n8n(N8N_WEBHOOK_URL_MAP, {"chat_id": chat_id})

    await update.message.reply_text("📍 조직도를 불러오는 중입니다...")

# 💬 사용자 입력 처리 (이름 검색 요청)
async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
    chat_id = update.effective_chat.id
    text = update.message.text.strip()
    logger.info(f"📨 메시지 수신 - Chat ID: {chat_id}, 메시지: {text}")

    # 검색 모드인지 확인
    if context.user_data.get("search_mode", False):
        send_to_n8n(N8N_WEBHOOK_URL_SEARCH, {"chat_id": chat_id, "name": text})  # 🔹 검색 요청
        await update.message.reply_text("🔍 검색 요청을 처리 중입니다. 잠시만 기다려주세요!")
        context.user_data["search_mode"] = False  # 검색 모드 종료

# 🌐 Flask 엔드포인트 (Telegram Webhook)
@app.route('/webhook', methods=['POST'])
def webhook():
    logger.info("🔗 Webhook 요청 수신")
    try:
        data = request.get_json(force=True)
        logger.info(f"📩 수신된 데이터: {data}")

        update = Update.de_json(data, bot)
        application.update_queue.put_nowait(update)

        return "OK", 200
    except Exception as e:
        logger.error(f"❌ Webhook 처리 중 오류 발생: {e}")
        return f"Error: {e}", 500

# ✅ `/subscribe` (구독 등록)
async def motie_subscribe(update: Update, context: ContextTypes.DEFAULT_TYPE):
    chat_id = update.effective_chat.id
    first_name = update.effective_chat.first_name

    # Supabase에 chat_id 저장 (중복 방지)
    try:
        response = supabase.table("motie_subscribers").upsert({
            "chat_id": chat_id,
            "first_name": first_name
        }).execute()
        
        await update.message.reply_text("✅ 인사발령 알림을 구독하셨습니다!")
        logger.info(f"📩 구독 등록: {chat_id} - {first_name}")

    except Exception as e:
        await update.message.reply_text("❌ 구독 중 오류 발생!")
        logger.error(f"❌ 구독 오류: {e}")

# ✅ `/unsubscribe` (구독 취소)
async def motie_unsubscribe(update: Update, context: ContextTypes.DEFAULT_TYPE):
    chat_id = update.effective_chat.id

    # Supabase에서 chat_id 삭제
    try:
        supabase.table("motie_subscribers").delete().eq("chat_id", chat_id).execute()
        await update.message.reply_text("🛑 구독이 취소되었습니다.")
        logger.info(f"📩 구독 취소: {chat_id}")

    except Exception as e:
        await update.message.reply_text("❌ 구독 취소 중 오류 발생!")
        logger.error(f"❌ 구독 취소 오류: {e}")

# 📍 `/moef_map` 명령어 처리 (조직도 요청)
async def moef_map(update: Update, context: ContextTypes.DEFAULT_TYPE):
    chat_id = update.effective_chat.id
    logger.info(f"📍 /moef_map 요청 수신 - Chat ID: {chat_id}")

    # 🔹 N8N으로 조직도 요청
    send_to_n8n(N8N_WEBHOOK_URL_MOEF_MAP, {"chat_id": chat_id})

    await update.message.reply_text("📍 조직도를 불러오는 중입니다...")

# ✅ `/subscribe` (구독 등록)
async def moef_subscribe(update: Update, context: ContextTypes.DEFAULT_TYPE):
    chat_id = update.effective_chat.id
    first_name = update.effective_chat.first_name

    # Supabase에 chat_id 저장 (중복 방지)
    try:
        response = supabase.table("moef_subscribers").upsert({
            "chat_id": chat_id,
            "first_name": first_name
        }).execute()
        
        await update.message.reply_text("✅ 인사발령 알림을 구독하셨습니다!")
        logger.info(f"📩 구독 등록: {chat_id} - {first_name}")

    except Exception as e:
        await update.message.reply_text("❌ 구독 중 오류 발생!")
        logger.error(f"❌ 구독 오류: {e}")

# ✅ `/unsubscribe` (구독 취소)
async def moef_unsubscribe(update: Update, context: ContextTypes.DEFAULT_TYPE):
    chat_id = update.effective_chat.id

    # Supabase에서 chat_id 삭제
    try:
        supabase.table("moef_subscribers").delete().eq("chat_id", chat_id).execute()
        await update.message.reply_text("🛑 구독이 취소되었습니다.")
        logger.info(f"📩 구독 취소: {chat_id}")

    except Exception as e:
        await update.message.reply_text("❌ 구독 취소 중 오류 발생!")
        logger.error(f"❌ 구독 취소 오류: {e}")

# ✅ 상태 관리 (사용자별 검색 부처 추적)
search_state = {}

# 🔍 `/motie_search` 명령어 (산업부 인물 검색)
async def motie_search(update: Update, context: ContextTypes.DEFAULT_TYPE):
    chat_id = update.effective_chat.id
    search_state[chat_id] = "motie"  # 산업부 검색 상태 설정
    logger.info(f"📥 /motie_search 실행 - Chat ID: {chat_id}")
    await bot.send_message(chat_id=chat_id, text="🔎 산업부에서 검색할 이름을 입력하세요.")

# 🔍 `/moef_search` 명령어 (기재부 인물 검색)
async def moef_search(update: Update, context: ContextTypes.DEFAULT_TYPE):
    chat_id = update.effective_chat.id
    search_state[chat_id] = "moef"  # 기재부 검색 상태 설정
    logger.info(f"📥 /moef_search 실행 - Chat ID: {chat_id}")
    await bot.send_message(chat_id=chat_id, text="🔎 기재부에서 검색할 이름을 입력하세요.")

# 💬 사용자 입력을 받아 Webhook 호출 (산업부 or 기재부)
async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
    chat_id = update.effective_chat.id
    text = update.message.text
    department = search_state.get(chat_id)

    if not department:
        await bot.send_message(chat_id=chat_id, text="❌ 먼저 검색할 부처를 선택하세요. `/motie_search` 또는 `/moef_search`를 입력하세요.")
        return

    webhook_url = N8N_WEBHOOK_URL_SEARCH if department == "motie" else N8N_WEBHOOK_URL_MOEF_SEARCH

    logger.info(f"📨 메시지 수신 - Chat ID: {chat_id}, 검색 이름: {text}, 부처: {department}")
    logger.info(f"🔗 Webhook 호출: {webhook_url}")

    try:
        # 1️⃣ Webhook 호출하여 n8n에서 검색 처리
        response = requests.post(webhook_url, json={"chat_id": chat_id, "name": text})
        response.raise_for_status()  # 오류 발생 시 예외 처리

        await bot.send_message(chat_id=chat_id, text="🔍 검색 요청이 접수되었습니다. 결과를 기다려주세요.")

    except requests.exceptions.RequestException as e:
        await bot.send_message(chat_id=chat_id, text="❌ 검색 요청 중 오류 발생!")
        logger.error(f"❌ Webhook 호출 오류: {e}")

    # 2️⃣ 검색 완료 후, 상태 초기화
    search_state.pop(chat_id, None)

# ✅ `/start` 명령어 처리
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    chat_id = update.effective_chat.id
    logger.info(f"📥 /start 명령어 실행 - Chat ID: {chat_id}")

    message = (
        "📢 *산업부·기재부·전력그룹사 인사 발령 알림 봇*\n\n"
        "아래 명령어를 통해 검색 및 알림 수신을 설정할 수 있습니다.\n"
        "(메뉴 기능을 활용하거나 직접 입력하여 사용 가능합니다.)\n\n"
        "🔍 *직원 검색 기능*\n"
        "1️⃣ `/motie_search` - 산업부 직원 검색\n"
        "2️⃣ `/moef_search` - 기재부 직원 검색\n\n"
        "📌 *주요 간부 명단 조회*\n"
        "3️⃣ `/motie_map` - 산업부 주요 간부 명단 (팀장 이상)\n"
        "4️⃣ `/moef_map` - 기재부 주요 간부 명단 (팀장 이상)\n\n"
        "🔔 *인사발령 알림 설정*\n"
        "📢 *산업부*\n"
        "5️⃣ `/motie_subscribe` - 산업부 인사발령 알림 켜기\n"
        "6️⃣ `/motie_unsubscribe` - 산업부 인사발령 알림 끄기\n\n"
        "📢 *기재부*\n"
        "7️⃣ `/moef_subscribe` - 기재부 인사발령 알림 켜기\n"
        "8️⃣ `/moef_unsubscribe` - 기재부 인사발령 알림 끄기\n\n"
        "📢 *전력그룹사*\n"
        "9️⃣ `/kepco_subscribe` - 전력그룹사 인사발령 알림 켜기\n"
        "🔟 `/kepco_unsubscribe` - 전력그룹사 인사발령 알림 끄기\n\n"
        "ℹ️ *인사발령 정보는 공시된 정부 홈페이지 및 알리오에서 수집됩니다.*\n"
        "(언론 등 외부 출처 인사발령 정보는 포함되지 않습니다.)\n\n"
        "ℹ️ *알림은 미수신이 기본 값이므로, 수신을 원하실 경우 반드시 알림 켜기를 실행해주세요.*"
    )

    await bot.send_message(chat_id=chat_id, text=message, parse_mode="Markdown")

# ✅ `/subscribe` (구독 등록)
async def kepco_subscribe(update: Update, context: ContextTypes.DEFAULT_TYPE):
    chat_id = update.effective_chat.id
    first_name = update.effective_chat.first_name

    # Supabase에 chat_id 저장 (중복 방지)
    try:
        response = supabase.table("kepco_subscribers").upsert({
            "chat_id": chat_id,
            "first_name": first_name
        }).execute()
        
        await update.message.reply_text("✅ 인사발령 알림을 구독하셨습니다!")
        logger.info(f"📩 구독 등록: {chat_id} - {first_name}")

    except Exception as e:
        await update.message.reply_text("❌ 구독 중 오류 발생!")
        logger.error(f"❌ 구독 오류: {e}")

# ✅ `/unsubscribe` (구독 취소)
async def kepco_unsubscribe(update: Update, context: ContextTypes.DEFAULT_TYPE):
    chat_id = update.effective_chat.id

    # Supabase에서 chat_id 삭제
    try:
        supabase.table("kepco_subscribers").delete().eq("chat_id", chat_id).execute()
        await update.message.reply_text("🛑 구독이 취소되었습니다.")
        logger.info(f"📩 구독 취소: {chat_id}")

    except Exception as e:
        await update.message.reply_text("❌ 구독 취소 중 오류 발생!")
        logger.error(f"❌ 구독 취소 오류: {e}")

# ✅ Application 초기화 및 핸들러 등록
application = Application.builder().token(TELEGRAM_TOKEN).build()
application.add_handler(CommandHandler("motie_search", motie_search))
application.add_handler(CommandHandler("motie_map", motie_map))  # `/motie_map` 추가
application.add_handler(CommandHandler("motie_subscribe", motie_subscribe))
application.add_handler(CommandHandler("motie_unsubscribe", motie_unsubscribe))
application.add_handler(CommandHandler("moef_search", moef_search))
application.add_handler(CommandHandler("moef_map", moef_map))  # `/motie_map` 추가
application.add_handler(CommandHandler("moef_subscribe", moef_subscribe))
application.add_handler(CommandHandler("moef_unsubscribe", moef_unsubscribe))
application.add_handler(CommandHandler("kepco_subscribe", kepco_subscribe))
application.add_handler(CommandHandler("kepco_unsubscribe", kepco_unsubscribe))
application.add_handler(CommandHandler("start", start))  # ✅ /start 핸들러 추가
application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))

# 🚀 Flask 실행을 별도 스레드로 실행
def run_flask():
    logger.info("🚀 Flask 서버 실행 시작 (포트: 8443)")
    app.run(host='0.0.0.0', port=8443, ssl_context=(
        '/etc/letsencrypt/live/jjickjjicks.com-0002/fullchain.pem',
        '/etc/letsencrypt/live/jjickjjicks.com-0002/privkey.pem'
    ))

if __name__ == '__main__':
    flask_thread = threading.Thread(target=run_flask, daemon=True)
    flask_thread.start()
    logger.info("🚀 Telegram Bot 실행 시작")
    application.run_polling()
