/** @odoo-module */

import { Component, onMounted, onWillStart, onWillUnmount, useState, useRef } from "@odoo/owl";

const SEM_THRESHOLD = 0.3;
const MAX_QUESTIONS = 40;

export class PlacementApp extends Component {
    static template = "encoach_exam_session.PlacementApp";
    static props = {};

    setup() {
        this.rootRef = useRef("root");
        this.state = useState({
            loading: true,
            sessionId: 0,
            currentQuestion: null,
            answer: null,
            questionsAnswered: 0,
            theta: 0.0,
            sem: 1.0,
            completed: false,
            cefrLevel: null,
            submitting: false,
            error: null,
        });

        onWillStart(async () => {
            await this.startSession();
        });

        onMounted(() => {
            this.enterFullscreen();
        });
    }

    get sessionIdFromDom() {
        const el = document.getElementById("placement_session_app");
        return el ? parseInt(el.dataset.sessionId) : 0;
    }

    enterFullscreen() {
        const el = document.documentElement;
        if (el.requestFullscreen) {
            el.requestFullscreen().catch(() => {});
        }
    }

    // ── Session Start ─────────────────────────────────────────────

    async startSession() {
        try {
            const domSessionId = this.sessionIdFromDom;
            if (domSessionId) {
                this.state.sessionId = domSessionId;
                await this.loadCurrentQuestion();
            } else {
                const response = await fetch("/api/placement/start", {
                    method: "POST",
                    headers: { "Content-Type": "application/json" },
                });
                const data = await response.json();
                this.state.sessionId = data.session_id;
                this.state.currentQuestion = data.first_question;
            }
            this.state.loading = false;
        } catch (e) {
            this.state.error = "Failed to start placement test.";
            this.state.loading = false;
        }
    }

    async loadCurrentQuestion() {
        try {
            const response = await fetch(
                `/api/placement/current?session_id=${this.state.sessionId}`
            );
            const data = await response.json();
            if (data.question) {
                this.state.currentQuestion = data.question;
                this.state.questionsAnswered = data.questions_answered || 0;
                this.state.theta = data.theta || 0.0;
                this.state.sem = data.sem || 1.0;
            }
        } catch (e) {
            console.error("Failed to load current question:", e);
        }
    }

    // ── Answer Handling ───────────────────────────────────────────

    setAnswer(questionId, value) {
        this.state.answer = value;
    }

    get hasAnswer() {
        return this.state.answer !== null && this.state.answer !== undefined && this.state.answer !== "";
    }

    async submitAnswer() {
        if (!this.hasAnswer || this.state.submitting) return;
        this.state.submitting = true;

        try {
            const response = await fetch("/api/placement/answer", {
                method: "POST",
                headers: { "Content-Type": "application/json" },
                body: JSON.stringify({
                    session_id: this.state.sessionId,
                    question_id: this.state.currentQuestion.id,
                    answer: this.state.answer,
                }),
            });
            const data = await response.json();
            this.state.theta = data.new_theta;
            this.state.sem = data.new_sem;
            this.state.questionsAnswered++;

            if (data.completed) {
                this.state.completed = true;
                this.state.cefrLevel = data.cefr_level;
            } else {
                this.state.currentQuestion = data.next_question;
                this.state.answer = null;
            }
        } catch (e) {
            this.state.error = "Failed to submit answer. Please try again.";
        } finally {
            this.state.submitting = false;
        }
    }

    // ── Progress Helpers ──────────────────────────────────────────

    get progressPercent() {
        const semProgress = Math.max(0, (1.0 - this.state.sem) / (1.0 - SEM_THRESHOLD));
        const questionProgress = this.state.questionsAnswered / MAX_QUESTIONS;
        return Math.min(Math.max(semProgress, questionProgress) * 100, 100);
    }

    get progressStyle() {
        return `width: ${this.progressPercent}%`;
    }

    get questionType() {
        return this.state.currentQuestion?.question_type || "mcq";
    }

    get questionOptions() {
        const opts = this.state.currentQuestion?.options;
        if (Array.isArray(opts)) {
            return opts.map((o, i) => ({
                key: o.key || String.fromCharCode(65 + i),
                label: o.label || o.text || o,
            }));
        }
        if (opts && typeof opts === "object") {
            return Object.entries(opts).map(([key, label]) => ({ key, label }));
        }
        return [];
    }

    selectOption(key) {
        this.state.answer = key;
    }

    get cefrLabel() {
        const map = {
            pre_a1: "Pre-A1",
            a1: "A1",
            a2: "A2",
            b1: "B1",
            b2: "B2",
            c1: "C1",
            c2: "C2",
        };
        return map[this.state.cefrLevel] || this.state.cefrLevel?.toUpperCase() || "";
    }

    goToDashboard() {
        window.location.href = "/my/dashboard";
    }
}

// ── Auto-mount ────────────────────────────────────────────────────

function mountPlacementApp() {
    const target = document.getElementById("placement_session_app");
    if (target) {
        const { mount } = owl;
        mount(PlacementApp, target);
    }
}

if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", mountPlacementApp);
} else {
    mountPlacementApp();
}
