"""
Absfuyu: Google form
--------------------
Google form

Version: 6.5.0
Date updated: 19/03/2026 (dd/mm/yyyy)
"""

# Module level
# ---------------------------------------------------------------------------
__all__ = ["GoogleFormParser"]

# Library
# ---------------------------------------------------------------------------
import json
import re
from typing import Self

import requests

from absfuyu.extra.gform.models import FormID, GoogleForm, Question, QuestionType


# Class
# ---------------------------------------------------------------------------
class GoogleFormParser:
    def __init__(self, form_url: str) -> None:
        self.form_url = form_url

    @classmethod
    def from_form_id(cls, form_id: FormID) -> Self:
        return cls(form_id.view)

    def _load_raw_data(self) -> list[list | str | int | None]:
        headers = {"User-Agent": "Mozilla/5.0"}
        html = requests.get(self.form_url, headers=headers).text

        match = re.search(r"FB_PUBLIC_LOAD_DATA_ = (.*?);</script>", html)
        if not match:
            raise ValueError("Form structure not found")

        return json.loads(match.group(1))

    def parse(self) -> GoogleForm:
        raw_data = self._load_raw_data()
        question_blocks = raw_data[1][1]

        questions = []
        page_index = 0
        section_count = 0  # count page breaks

        for q in question_blocks:
            try:
                question_id = q[0]
                question_text = q[1]
                question_type = QuestionType.from_code(q[3])
                answer_block = q[4]

                # SECTION = new page
                if question_type == QuestionType.SECTION:
                    page_index += 1
                    section_count += 1
                    continue

                entry_ids = []
                options = []
                branching = {}

                if answer_block:
                    for ans in answer_block:
                        entry_ids.append(f"entry.{ans[0]}")

                        # Extract options + branching
                        if len(ans) > 1 and isinstance(ans[1], list):
                            for opt in ans[1]:
                                if isinstance(opt, list) and opt:
                                    option_text = opt[0]
                                    options.append(option_text)

                                    # branching target (if exists)
                                    jump_target = None
                                    if len(opt) > 2:
                                        jump_target = opt[2]

                                    branching[option_text] = jump_target

                questions.append(
                    Question(
                        question_id=question_id,
                        text=question_text,
                        type=question_type,
                        entry_ids=entry_ids,
                        options=options,
                        branching=branching,
                        page_index=page_index,
                    )
                )

            except Exception:
                continue

        page_count = section_count + 1

        return GoogleForm(
            form_id=FormID.from_link(self.form_url),
            questions=questions,
            is_multipage=page_count > 1,
            page_count=page_count,
        )


class FormStateMachine:
    """For form with branching - W.I.P"""

    def __init__(self, form: GoogleForm):
        self.form = form

        # page_index -> questions
        self.pages: dict[int, list[Question]] = {}
        for q in form.questions:
            self.pages.setdefault(q.page_index, []).append(q)

    def compute_page_history(self, answers: dict[str, str]) -> str:
        """
        answers:
            {
                "Question text": "Selected Option"
            }
        """

        visited_pages = []
        current_page = 0

        while True:
            visited_pages.append(current_page)

            questions = self.pages.get(current_page, [])
            next_page = current_page + 1

            # Check for branching in this page
            for q in questions:
                if q.text in answers:
                    selected = answers[q.text]
                    target = q.branching.get(selected)

                    if target is not None:
                        next_page = target
                        break

            if next_page >= self.form.page_count:
                break

            current_page = next_page

        return ",".join(map(str, visited_pages))


if __name__ == "__main__":
    from rich import print

    form_url = ""
    parser = GoogleFormParser(form_url)
    form = parser.parse()

    state = FormStateMachine(form)
