package controller;

import model.*;
import service.*;
import view.*;

import javax.swing.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;


public class AppController {
    // 模型和服务
    private final UserManager userManager;
    private final ExamManager examManager;
    private final EmailService emailService;

    // 视图
    private final MainFrame mainFrame;
    private final LoginView loginView;
    private final RegisterView registerView;
    private final PasswordSetView passwordSetView;
    private final MainMenuView mainMenuView;
    private final ExamView examView;
    private final ScoreView scoreView;

    // 应用状态
    private User currentUser;
    private String emailForRegistration;
    private String usernameForRegistration;
    private final Map<String, String> registrationCodes = new HashMap<>();
    private List<Question> currentExam;
    private int currentQuestionIndex;
    private int score;
    private int[] userAnswers; // 新增：用于存储用户每一题的答案

    public AppController() {
        this.mainFrame = new MainFrame();
        this.userManager = new UserManager();
        this.examManager = new ExamManager();
        this.emailService = new EmailService();

        this.loginView = new LoginView();
        this.registerView = new RegisterView();
        this.passwordSetView = new PasswordSetView();
        this.mainMenuView = new MainMenuView();
        this.examView = new ExamView();
        this.scoreView = new ScoreView();

        mainFrame.addPanel(loginView, "LOGIN");
        mainFrame.addPanel(registerView, "REGISTER");
        mainFrame.addPanel(passwordSetView, "PASSWORD_SET");
        mainFrame.addPanel(mainMenuView, "MAIN_MENU");
        mainFrame.addPanel(examView, "EXAM");
        mainFrame.addPanel(scoreView, "SCORE");

        attachListeners();
        mainFrame.showPanel("LOGIN");
    }

    /**
     * 附加所有UI组件的事件监听器。
     */
    private void attachListeners() {
        // --- 登录逻辑 ---
        loginView.getLoginButton().addActionListener(e -> handleLogin());
        loginView.getRegisterButton().addActionListener(e -> mainFrame.showPanel("REGISTER"));

        // --- 注册逻辑 ---
        registerView.getGetCodeButton().addActionListener(e -> handleGetCode());
        registerView.getRegisterButton().addActionListener(e -> handleVerifyCode());
        registerView.getBackButton().addActionListener(e -> mainFrame.showPanel("LOGIN"));

        // --- 密码设置逻辑 ---
        passwordSetView.getSubmitButton().addActionListener(e -> handleSetPassword());

        // --- 主菜单逻辑 ---
        mainMenuView.getStartExamButton().addActionListener(e -> handleStartExam());
        mainMenuView.getChangePasswordButton().addActionListener(e -> handleChangePassword());
        mainMenuView.getLogoutButton().addActionListener(e -> handleLogout());

        // --- 考试逻辑 (已重构) ---
        examView.getPrevButton().addActionListener(e -> handlePreviousQuestion());
        examView.getNextButton().addActionListener(e -> handleNextQuestion());
        examView.getFinishButton().addActionListener(e -> handleFinishExam());

        // --- 分数界面逻辑 ---
        scoreView.getContinueButton().addActionListener(e -> {
            String welcomeName = currentUser.getUsername() != null && !currentUser.getUsername().isEmpty() ? currentUser.getUsername() : currentUser.getEmail();
            mainMenuView.setWelcomeMessage("欢迎, " + welcomeName);
            mainFrame.showPanel("MAIN_MENU");
        });
        scoreView.getExitButton().addActionListener(e -> handleLogout());
    }

    // --- 核心处理方法 ---

    private void handleLogin() {
        User user = userManager.authenticate(loginView.getIdentifier(), loginView.getPassword());
        if (user != null) {
            currentUser = user;
            String welcomeName = user.getUsername() != null && !user.getUsername().isEmpty() ? user.getUsername() : user.getEmail();
            mainMenuView.setWelcomeMessage("欢迎, " + welcomeName);
            mainFrame.showPanel("MAIN_MENU");
        } else {
            JOptionPane.showMessageDialog(mainFrame, "邮箱/用户名或密码错误", "登录失败", JOptionPane.ERROR_MESSAGE);
        }
        loginView.clearFields();
    }

    private void handleGetCode() {
        String email = registerView.getEmail();
        String username = registerView.getUsername();

        if (!ValidationService.isValidEmail(email)) {
            JOptionPane.showMessageDialog(mainFrame, "请输入有效的邮箱格式！", "格式错误", JOptionPane.ERROR_MESSAGE);
            return;
        }
        if (username.trim().isEmpty() || username.contains("|") || username.contains(" ")) {
            JOptionPane.showMessageDialog(mainFrame, "用户名不能为空，且不能包含'|'或空格！", "格式错误", JOptionPane.ERROR_MESSAGE);
            return;
        }
        if (userManager.emailExists(email)) {
            JOptionPane.showMessageDialog(mainFrame, "该邮箱已被注册！", "注册失败", JOptionPane.ERROR_MESSAGE);
            return;
        }
        if (userManager.usernameExists(username)) {
            JOptionPane.showMessageDialog(mainFrame, "该用户名已被使用！", "注册失败", JOptionPane.ERROR_MESSAGE);
            return;
        }

        emailForRegistration = email;
        usernameForRegistration = username;
        String code = String.format("%06d", new Random().nextInt(1000000));
        registrationCodes.put(emailForRegistration, code);

        final JButton getCodeButton = registerView.getGetCodeButton();
        getCodeButton.setEnabled(false);
        getCodeButton.setText("发送中...");

        SwingWorker<Void, Void> worker = new SwingWorker<>() {
            private Exception mailException = null;

            @Override
            protected Void doInBackground() {
                try {
                    emailService.sendVerificationCode(emailForRegistration, code);
                } catch (Exception e) {
                    this.mailException = e;
                }
                return null;
            }

            @Override
            protected void done() {
                getCodeButton.setEnabled(true);
                getCodeButton.setText("发送验证邮件");

                if (mailException == null) {
                    JOptionPane.showMessageDialog(mainFrame, "一封包含验证码的【电子邮件】已发送至您的邮箱，请登录邮箱查收。", "发送成功", JOptionPane.INFORMATION_MESSAGE);
                } else {
                    String errorMessage = "邮件发送失败，请检查：\n1. 网络连接是否正常。\n2. config.properties 中的邮箱和授权码是否正确。\n\n错误详情: " + mailException.getMessage();
                    JOptionPane.showMessageDialog(mainFrame, errorMessage, "发送失败", JOptionPane.ERROR_MESSAGE);
                    mailException.printStackTrace();
                }
            }
        };
        worker.execute();
    }

    private void handleVerifyCode() {
        String code = registerView.getCode();
        if (code.equals(registrationCodes.get(emailForRegistration))) {
            mainFrame.showPanel("PASSWORD_SET");
        } else {
            JOptionPane.showMessageDialog(mainFrame, "注册码错误！", "验证失败", JOptionPane.ERROR_MESSAGE);
        }
    }

    private void handleSetPassword() {
        String pass1 = passwordSetView.getPassword();
        String pass2 = passwordSetView.getConfirmPassword();

        if (!pass1.equals(pass2)) {
            JOptionPane.showMessageDialog(mainFrame, "两次输入的密码不一致！", "错误", JOptionPane.ERROR_MESSAGE);
            return;
        }
        if (!ValidationService.isPasswordStrong(pass1)) {
            JOptionPane.showMessageDialog(mainFrame, "密码必须为6-10位，且包含大小写字母和数字。", "密码格式错误", JOptionPane.ERROR_MESSAGE);
            return;
        }

        userManager.registerUser(emailForRegistration, usernameForRegistration, pass1, UserType.PRIMARY);
        JOptionPane.showMessageDialog(mainFrame, "注册成功！请返回登录。", "成功", JOptionPane.INFORMATION_MESSAGE);
        mainFrame.showPanel("LOGIN");
    }

    private void handleStartExam() {
        UserType type = mainMenuView.getSelectedType();
        int count = mainMenuView.getQuestionCount();

        if(currentUser.getUserType() != type) {
            currentUser.setUserType(type);
            userManager.updateUser(currentUser);
        }

        currentExam = examManager.generateExam(currentUser, type, count);
        if (currentExam.size() < count) {
            JOptionPane.showMessageDialog(mainFrame, "抱歉，未能生成足够数量的不重复题目，实际生成 " + currentExam.size() + " 道。", "提示", JOptionPane.WARNING_MESSAGE);
        }
        if (currentExam.isEmpty()) return;

        currentQuestionIndex = 0;
        score = 0;
        userAnswers = new int[currentExam.size()];
        Arrays.fill(userAnswers, -1); // -1 代表未作答

        examView.setupForExam(currentExam.size());
        displayCurrentQuestion();
        mainFrame.showPanel("EXAM");
    }

    private void displayCurrentQuestion() {
        Question q = currentExam.get(currentQuestionIndex);
        int savedAnswer = userAnswers[currentQuestionIndex];
        examView.displayQuestion(q, currentQuestionIndex + 1, currentExam.size(), savedAnswer);
        examView.updateNavigationButtons(currentQuestionIndex, currentExam.size());
    }

    private void handlePreviousQuestion() {
        saveCurrentAnswer();
        if (currentQuestionIndex > 0) {
            currentQuestionIndex--;
            displayCurrentQuestion();
        }
    }

    private void handleNextQuestion() {
        saveCurrentAnswer();
        if (currentQuestionIndex < currentExam.size() - 1) {
            currentQuestionIndex++;
            displayCurrentQuestion();
        }
    }

    private void saveCurrentAnswer() {
        int selectedIndex = examView.getSelectedIndex();
        userAnswers[currentQuestionIndex] = selectedIndex;
    }

    private void handleFinishExam() {
        saveCurrentAnswer();

        int choice = JOptionPane.showConfirmDialog(mainFrame,
                "您确定要交卷吗？\n未完成的题目将按 0 分计算。",
                "确认交卷",
                JOptionPane.YES_NO_OPTION);

        if (choice == JOptionPane.YES_OPTION) {
            calculateScore();
            int finalScore = (int) Math.round((double) score / currentExam.size() * 100);
            scoreView.setScore(finalScore, score, currentExam.size());
            mainFrame.showPanel("SCORE");
        }
    }

    private void calculateScore() {
        score = 0;
        for (int i = 0; i < currentExam.size(); i++) {
            if (userAnswers[i] != -1 && userAnswers[i] == currentExam.get(i).getCorrectOptionIndex()) {
                score++;
            }
        }
    }

    private void handleChangePassword() {
        ChangePasswordView dialog = new ChangePasswordView(mainFrame);

        dialog.getConfirmButton().addActionListener(e -> {
            String oldPass = dialog.getOldPassword();
            String newPass = dialog.getNewPassword();
            String confirmPass = dialog.getConfirmPassword();

            if (userManager.authenticate(currentUser.getEmail(), oldPass) == null) {
                JOptionPane.showMessageDialog(dialog, "原密码错误！", "验证失败", JOptionPane.ERROR_MESSAGE);
                return;
            }
            if (!newPass.equals(confirmPass)) {
                JOptionPane.showMessageDialog(dialog, "两次输入的新密码不一致！", "错误", JOptionPane.ERROR_MESSAGE);
                return;
            }
            if (!ValidationService.isPasswordStrong(newPass)) {
                JOptionPane.showMessageDialog(dialog, "新密码必须为6-10位，且包含大小写字母和数字。", "密码格式错误", JOptionPane.ERROR_MESSAGE);
                return;
            }

            currentUser.setHashedPassword(newPass);
            userManager.updateUser(currentUser);

            JOptionPane.showMessageDialog(dialog, "密码修改成功！", "成功", JOptionPane.INFORMATION_MESSAGE);
            dialog.dispose();
        });

        dialog.getCancelButton().addActionListener(e -> dialog.dispose());
        dialog.setVisible(true);
    }

    private void handleLogout() {
        currentUser = null;
        loginView.clearFields();
        mainFrame.showPanel("LOGIN");
    }
}