import discord
from discord.ext import commands
from discord import ui
import pandas as pd
import os
import random
from typing import List, Dict

class AnswerButton(ui.Button):
    def __init__(self, option_number: int, option_text: str, correct: bool, is_selected: bool = False, row: int = None):
        style = discord.ButtonStyle.primary if is_selected else discord.ButtonStyle.secondary
        super().__init__(
            style=style,
            label=option_text,
            custom_id=f"answer_{option_number}",
            row=row
        )
        self.correct = correct
        self.option_number = option_number

    async def callback(self, interaction: discord.Interaction):
        assert isinstance(self.view, QuizView)
        await self.view.handle_answer(interaction, self)

class NavigationButton(ui.Button):
    def __init__(self, label: str, custom_id: str, disabled: bool = False, row: int = None):
        super().__init__(
            style=discord.ButtonStyle.secondary,
            label=label,
            custom_id=custom_id,
            disabled=disabled,
            row=row
        )

    async def callback(self, interaction: discord.Interaction):
        assert isinstance(self.view, QuizView)
        await self.view.handle_navigation(interaction, self.custom_id)

class SubmitButton(ui.Button):
    def __init__(self, row: int = None):
        super().__init__(
            style=discord.ButtonStyle.success,
            label="交卷",
            custom_id="submit_quiz",
            row=row
        )

    async def callback(self, interaction: discord.Interaction):
        assert isinstance(self.view, QuizView)
        await self.view.handle_submit(interaction)

class ReviewButton(ui.Button):
    def __init__(self):
        super().__init__(
            style=discord.ButtonStyle.primary,
            label="查看錯題",
            custom_id="review_wrong"
        )

    async def callback(self, interaction: discord.Interaction):
        assert isinstance(self.view, ResultView)
        await self.view.show_wrong_questions(interaction)

class ResultView(ui.View):
    def __init__(self, wrong_questions: List[Dict], all_questions: List[Dict]):
        super().__init__(timeout=None)
        self.wrong_questions = wrong_questions
        self.all_questions = all_questions
        self.add_item(ReviewButton())

    async def show_wrong_questions(self, interaction: discord.Interaction):
        if not self.wrong_questions:
            await interaction.response.send_message("恭喜你全部答對！", ephemeral=True)
            return

        embed = discord.Embed(title="錯題回顧", color=discord.Color.red())
        for i, q in enumerate(self.wrong_questions, 1):
            original_q = next(x for x in self.all_questions if x['題號'] == q['original_number'] 
                            and x['source_file'] == q['source_file'])
            
            options_text = "\n".join([
                f" - 選項{i}: {original_q[f'選項{i}']} "
                f"{'(你的答案)' if original_q[f'選項{i}'] == q['your_answer'] else ''}"
                f"{'(正確答案)' if original_q[f'選項{i}'] == q['correct_answer'] else ''}"
                for i in range(1, 5)
            ])

            embed.add_field(
                name=f"第 {i} 題",
                value=f"題目：{q['question']}\n"
                      f"選項：\n{options_text}\n"
                      f"題目來源：{q['source_file']} - 第 {q['original_number']} 題\n"
                      f"───────────────",
                inline=False
            )
        
        await interaction.response.send_message(embed=embed, ephemeral=True)

class QuizView(ui.View):
    def __init__(self, questions: List[Dict], user_id: int):
        super().__init__(timeout=None)
        self.questions = questions
        self.current_question = 0
        self.total_questions = len(questions)
        self.user_answers = {}
        self.user_id = user_id
        self._add_buttons()

    def _add_buttons(self):
        self.clear_items()
        current_q = self.questions[self.current_question]
        correct_option = int(current_q['正確的選項'])
        
        # 第一行：選項按鈕 (row=0)
        for i in range(1, 5):
            option = current_q[f'選項{i}']
            is_selected = (self.current_question in self.user_answers and 
                         self.user_answers[self.current_question] == i)
            
            button = AnswerButton(
                option_number=i,
                option_text=option,
                correct=(i == correct_option),
                is_selected=is_selected,
                row=0
            )
            self.add_item(button)

        # 第二行：導航按鈕和交卷按鈕 (row=1)
        prev_button = NavigationButton(
            label="上一題",
            custom_id="prev",
            disabled=self.current_question == 0,
            row=1
        )
        next_button = NavigationButton(
            label="下一題",
            custom_id="next",
            disabled=self.current_question == self.total_questions - 1,
            row=1
        )
        submit_button = SubmitButton(row=1)
        
        self.add_item(prev_button)
        self.add_item(next_button)
        self.add_item(submit_button)

    async def handle_answer(self, interaction: discord.Interaction, button: AnswerButton):
        if interaction.user.id != self.user_id:
            await interaction.response.send_message("這不是你的測驗！", ephemeral=True)
            return

        self.user_answers[self.current_question] = button.option_number
        await self.update_message(interaction)

    async def handle_navigation(self, interaction: discord.Interaction, custom_id: str):
        if custom_id == "prev":
            self.current_question = max(0, self.current_question - 1)
        elif custom_id == "next":
            self.current_question = min(self.total_questions - 1, self.current_question + 1)
        
        await self.update_message(interaction)

    async def update_message(self, interaction: discord.Interaction):
        self._add_buttons()
        embed = self._create_question_embed()
        await interaction.response.edit_message(embed=embed, view=self)

    def _create_question_embed(self):
        current_q = self.questions[self.current_question]
        answered_count = len(self.user_answers)
        
        embed = discord.Embed(
            title=f"第 {self.current_question + 1} 題",
            description=current_q['題目'],
            color=discord.Color.blue()
        )
        embed.set_footer(text=
            f"進度: {self.current_question + 1}/{self.total_questions} | "
            f"已作答: {answered_count}/{self.total_questions}\n"
            f"題目來源: {current_q['source_file']} - 第 {current_q['題號']} 題"
        )
        return embed

    async def handle_submit(self, interaction: discord.Interaction):
        if len(self.user_answers) < self.total_questions:
            unanswered = self.total_questions - len(self.user_answers)
            await interaction.response.send_message(
                f"還有 {unanswered} 題未作答，請確保所有題目都已回答後再交卷。",
                ephemeral=True
            )
            return

        correct_answers = 0
        wrong_questions = []
        
        for i, question in enumerate(self.questions):
            user_answer = self.user_answers[i]
            correct_option = int(question['正確的選項'])
            
            if user_answer == correct_option:
                correct_answers += 1
            else:
                wrong_questions.append({
                    'question': question['題目'],
                    'your_answer': question[f'選項{user_answer}'],
                    'correct_answer': question[f'選項{correct_option}'],
                    'source_file': question['source_file'],
                    'original_number': question['題號']
                })

        score = (correct_answers / self.total_questions) * 100

        # 建立包含查看錯題按鈕的結果視圖
        result_view = ResultView(wrong_questions, self.questions)

        # 發送帶有查看錯題按鈕的公開結果訊息
        await interaction.channel.send(
            embed=discord.Embed(
                title="測驗結果",
                description=f"<@{interaction.user.id}> 的測驗結果：\n\n"
                           f"總題數: {self.total_questions}\n"
                           f"答對題數: {correct_answers}\n"
                           f"答錯題數: {len(wrong_questions)}\n"
                           f"正確率: {score:.1f}%",
                color=discord.Color.green() if score >= 60 else discord.Color.red()
            ),
            view=result_view
        )
        
        # 關閉原本的測驗介面
        await interaction.response.edit_message(
            embed=discord.Embed(
                title="測驗已完成",
                description="測驗結果已在頻道中公布。",
                color=discord.Color.blue()
            ),
            view=None
        )

class Quiz(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.questions_cache = {}

    def load_questions(self) -> List[Dict]:
        if not self.questions_cache:
            questions = []
            questions_dir = "data/questions"
            
            for file in os.listdir(questions_dir):
                if file.endswith('.csv'):
                    df = pd.read_csv(os.path.join(questions_dir, file))
                    file_questions = df.to_dict('records')
                    for question in file_questions:
                        question['source_file'] = file
                    questions.extend(file_questions)
            
            self.questions_cache = questions
        
        return random.sample(self.questions_cache, 10)

    async def start_quiz(self, interaction: discord.Interaction):
        try:
            selected_questions = self.load_questions()
            view = QuizView(selected_questions, interaction.user.id)
            
            # 發送開始測驗的公告
            await interaction.channel.send(
                f"<@{interaction.user.id}> 開始了一個測驗！"
            )
            
            # 發送題目（只有使用者能看到）
            first_q = selected_questions[0]
            embed = discord.Embed(
                title="第 1 題",
                description=first_q['題目'],
                color=discord.Color.blue()
            )
            embed.set_footer(text=
                f"進度: 1/{len(selected_questions)} | 已作答: 0/{len(selected_questions)}\n"
                f"題目來源: {first_q['source_file']} - 第 {first_q['題號']} 題"
            )
            
            await interaction.response.send_message(
                embed=embed,
                view=view,
                ephemeral=True  # 設置為只有使用者可見
            )
        except Exception as e:
            print(f"Error starting quiz: {e}")
            await interaction.response.send_message("開始測驗時發生錯誤，請稍後再試。", ephemeral=True)

async def setup(bot):
    await bot.add_cog(Quiz(bot))