#!/usr/bin/env python
"""
Enhanced Scheduler Bot with SQLite database support
"""

import sqlite3
import datetime
from telegram import Update
from telegram.ext import Application, CommandHandler, ContextTypes, MessageHandler, filters

# 🔑 REPLACE THIS with your bot token from @BotFather
BOT_TOKEN = "8248686383:AAGN5UJ73H9i7LQzIBR3TjuJgUGNTFyRHk8"

# Database setup
DATABASE_NAME = "schedule.db"

def init_db():
    """Initialize the SQLite database and create tables if they don't exist."""
    conn = sqlite3.connect(DATABASE_NAME)
    cursor = conn.cursor()
    
    # Create table for schedule entries
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS schedule (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            day TEXT NOT NULL,
            period INTEGER NOT NULL,
            subject TEXT NOT NULL,
            class_name TEXT NOT NULL,
            room TEXT NOT NULL,
            UNIQUE(day, period)
        )
    ''')
    
    conn.commit()
    conn.close()

def add_schedule_entry(day, period, subject, class_name, room):
    """Add a new schedule entry to the database."""
    conn = sqlite3.connect(DATABASE_NAME)
    cursor = conn.cursor()
    
    try:
        cursor.execute('''
            INSERT OR REPLACE INTO schedule (day, period, subject, class_name, room)
            VALUES (?, ?, ?, ?, ?)
        ''', (day, period, subject, class_name, room))
        
        conn.commit()
        conn.close()
        return True
    except sqlite3.Error as e:
        print(f"Database error: {e}")
        conn.close()
        return False

def load_schedule_from_db():
    """Load schedule from the SQLite database."""
    conn = sqlite3.connect(DATABASE_NAME)
    cursor = conn.cursor()
    
    cursor.execute("SELECT day, period, subject, class_name, room FROM schedule ORDER BY day, period")
    rows = cursor.fetchall()
    
    conn.close()
    
    # Group by day
    schedule = {}
    for day, period, subject, class_name, room in rows:
        if day not in schedule:
            schedule[day] = []
        
        class_info = f"Subject: {subject} Class: {class_name} Room: {room}"
        schedule[day].append((str(period), class_info))
    
    return schedule

# Initialize the database
init_db()

# Map period numbers to times - Updated as requested
period_times = {
    '1': ('09:00', '09:40'),
    '2': ('10:00', '10:40'),
    '3': ('11:00', '11:40'),
    '4': ('11:50', '12:30'),
    '5': ('12:40', '13:20'),
    '6': ('13:30', '14:10'),
    '7': ('14:20', '15:00'),
    '8': ('15:20', '16:00'),
    '9': ('16:15', '16:55'),
    '10': ('17:05', '17:45'),
    '11': ('17:55', '18:35'),
    '12': ('18:45', '19:20'),
    '13': ('19:20', '20:00')
}

# User states for tracking conversations
user_states = {}  # Stores user conversation state

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """Send welcome message when command /start is issued."""
    await update.message.reply_text(
        "🤖 Hello! I'm your enhanced class scheduler bot with database support!\n"
        "Use /whereami to find your current class\n"
        "Use /schedule to see today's full schedule\n"
        "Use /tomorrow to see tomorrow's schedule\n"
        "Use /add to add a new class to the schedule\n"
        "Use /help for all commands"
    )


async def where_am_i(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """Tell user where they should be right now."""
    # Reload schedule from DB to ensure latest data
    schedule = load_schedule_from_db()
    
    if not schedule:
        await update.message.reply_text("❌ Schedule not loaded from database.")
        return

    now = datetime.datetime.now()
    current_time = now.strftime("%H:%M")
    current_day = now.strftime("%A")

    await update.message.reply_text(f"📅 Today is {current_day}")
    await update.message.reply_text(f"⏰ Current time: {current_time}")

    # Check if we have schedule for today
    if current_day not in schedule:
        await update.message.reply_text("😊 No classes scheduled for today!")
        return

    # Find current class
    found_class = False
    for period_num, class_info in schedule[current_day]:
        start_time, end_time = period_times[period_num]
        
        if start_time <= current_time <= end_time:
            await update.message.reply_text(f"🎯 You should be in: {class_info}")
            found_class = True
            break

    if not found_class:
        await update.message.reply_text("😊 No class right now! Free period.")


async def schedule(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """Show the complete weekly schedule."""
    # Reload schedule from DB to ensure latest data
    schedule = load_schedule_from_db()
    
    if not schedule:
        await update.message.reply_text("❌ Schedule not loaded from database.")
        return

    schedule_text = "📚 Weekly Schedule:\n\n"
    
    # Define the standard order of days in a week
    days_of_week = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
    
    for day in days_of_week:
        if day in schedule and schedule[day]:  # Check if the day exists in the schedule and has classes
            schedule_text += f"*{day}'s Schedule:*\n"
            for period_num, class_info in schedule[day]:
                start, end = period_times[period_num]
                schedule_text += f"  ⏰ {start}-{end}: {class_info}\n"
            schedule_text += "\n"
        else:
            schedule_text += f"{day}: No classes scheduled\n\n"

    await update.message.reply_text(schedule_text)


async def tomorrow(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """Show tomorrow's schedule."""
    # Reload schedule from DB to ensure latest data
    schedule = load_schedule_from_db()
    
    if not schedule:
        await update.message.reply_text("❌ Schedule not loaded from database.")
        return

    tomorrow_date = datetime.datetime.now() + datetime.timedelta(days=1)
    tomorrow_day = tomorrow_date.strftime("%A")

    if tomorrow_day not in schedule or not schedule[tomorrow_day]:
        await update.message.reply_text(f"😊 No classes scheduled for {tomorrow_day}!")
        return

    schedule_text = f"📚 {tomorrow_day}'s Schedule:\n\n"
    for period_num, class_info in schedule[tomorrow_day]:
        start, end = period_times[period_num]
        schedule_text += f"⏰ {start}-{end}: {class_info}\n"

    await update.message.reply_text(schedule_text)


async def add(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """Start the process of adding a new schedule entry."""
    user_id = update.effective_user.id
    user_states[user_id] = {"step": "waiting_day"}
    
    await update.message.reply_text(
        "📅 Adding a new class to the schedule.\n"
        "Please enter the day of the week (e.g., Monday, Tuesday, etc.):"
    )


async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """Handle user messages during the add process."""
    user_id = update.effective_user.id
    
    if user_id not in user_states:
        # Not in a conversation, ignore
        return
    
    state_info = user_states[user_id]
    message_text = update.message.text.strip()
    
    if state_info["step"] == "waiting_day":
        # Validate day input
        valid_days = ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"]
        if message_text.lower() not in valid_days:
            await update.message.reply_text(
                f"'{message_text}' is not a valid day of the week.\n"
                "Please enter a valid day (e.g., Monday, Tuesday, etc.):"
            )
            return
        
        state_info["day"] = message_text.capitalize()
        state_info["step"] = "waiting_period"
        
        await update.message.reply_text(
            f"Got it! Day: {state_info['day']}\n"
            "Now please enter the period number (1-13):"
        )
    
    elif state_info["step"] == "waiting_period":
        try:
            period = int(message_text)
            if period < 1 or period > 13:
                raise ValueError("Period must be between 1 and 13")
            
            state_info["period"] = period
            state_info["step"] = "waiting_subject"
            
            await update.message.reply_text(
                f"Got it! Period: {period}\n"
                "Now please enter the subject name:"
            )
        except ValueError:
            await update.message.reply_text(
                f"'{message_text}' is not a valid period number.\n"
                "Please enter a number between 1 and 13:"
            )
    
    elif state_info["step"] == "waiting_subject":
        state_info["subject"] = message_text
        state_info["step"] = "waiting_class"
        
        await update.message.reply_text(
            f"Got it! Subject: {message_text}\n"
            "Now please enter the class name (e.g., 10ABC, 6A/6B, etc.):"
        )
    
    elif state_info["step"] == "waiting_class":
        state_info["class_name"] = message_text
        state_info["step"] = "waiting_room"
        
        await update.message.reply_text(
            f"Got it! Class: {message_text}\n"
            "Finally, please enter the room number:"
        )
    
    elif state_info["step"] == "waiting_room":
        state_info["room"] = message_text
        
        # Add to database
        success = add_schedule_entry(
            state_info["day"],
            state_info["period"],
            state_info["subject"],
            state_info["class_name"],
            message_text
        )
        
        if success:
            await update.message.reply_text(
                f"✅ Successfully added to schedule!\n\n"
                f"Day: {state_info['day']}\n"
                f"Period: {state_info['period']}\n"
                f"Subject: {state_info['subject']}\n"
                f"Class: {state_info['class_name']}\n"
                f"Room: {state_info['room']}"
            )
        else:
            await update.message.reply_text(
                f"❌ Failed to add to schedule. Please try again."
            )
        
        # Clean up user state
        del user_states[user_id]


async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """Send help message with all commands."""
    await update.message.reply_text(
        "Available commands:\n"
        "/start - Start the bot\n"
        "/whereami - Find your current class\n"
        "/schedule - Show today's full schedule\n"
        "/tomorrow - Show tomorrow's schedule\n"
        "/add - Add a new class to the schedule\n"
        "/help - Show this help message"
    )


def main():
    """Start the bot."""
    # Create the Application
    application = Application.builder().token(BOT_TOKEN).build()

    # Add command handlers
    application.add_handler(CommandHandler("start", start))
    application.add_handler(CommandHandler("whereami", where_am_i))
    application.add_handler(CommandHandler("schedule", schedule))
    application.add_handler(CommandHandler("tomorrow", tomorrow))
    application.add_handler(CommandHandler("add", add))
    application.add_handler(CommandHandler("help", help_command))
    
    # Add message handler for conversation flow
    application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))

    # Start the Bot
    print("🤖 Enhanced scheduler bot with database support is running...")
    print("📊 Database initialized successfully!")
    print("Press Ctrl+C to stop the bot")

    application.run_polling()


if __name__ == "__main__":
    main()