"""Snack route adapter; quantities/receipts/cleanup remain TravelSnack's job."""
from .errors import CoordinatePreparationRequired, InputInterrupted, require
from .snack import BATCH, TravelSnack, validate_quantity
from .source_common_observation import common_field_ready
from .execution_rules import route


class SourceTravelSnack(TravelSnack):
    fixed_coordinates = False
    def _geometry(self, scene):
        runtime = self.s._ui_route_runtime()
        snapshot = runtime.refresh(self.s.window, force=True)
        if not snapshot.available:
            raise InputInterrupted("간식 계산 문맥 재확인 필요: " + snapshot.reason)
        rows = runtime.prepared_bundle(scene)
        return runtime, snapshot, rows

    def validate_layout(self):
        self._geometry("snack.detail")

    def _crop(self, scene, role, image):
        runtime, snapshot, records = self._geometry(scene)
        if image is not None and tuple(image.size) != snapshot.client_size:
            raise InputInterrupted("간식 판독 중 창 크기 변경")
        try:
            return tuple(records[role]["metadata"]["normalized_roi"])
        except (KeyError, TypeError) as exc:
            raise CoordinatePreparationRequired("준비된 간식 판독 영역이 없습니다: " + role) from exc

    def _region(self, region, image=None):
        roles = {
            "ocr.snack.recipe.title": ("snack.detail", "snack.ocr.title"),
            "ocr.snack.recipe.button": ("snack.detail", "snack.ocr.button"),
            "ocr.snack.count": ("snack.detail", "snack.ocr.count"),
            "ocr.snack.materials": ("snack.detail", "snack.ocr.materials"),
            "ocr.snack.menu": ("snack.menu", "ocr.common.craft_header"),
            "ocr.snack.result.title": ("snack.result", "snack.ocr.result.title"),
            "ocr.snack.result.item": ("snack.result", "snack.ocr.result.item"),
            "ocr.snack.result.footer": ("snack.result", "snack.result.confirm"),
            "ocr.snack.result.body": ("snack.result", "snack.result.confirm"),
        }
        role = self._region_role(region, image)
        require(role in roles, "간식 판독 영역 ID가 등록되지 않았습니다.")
        return self._crop(*roles[role], image)

    def _target(self, scene, role):
        runtime, snapshot, records = self._geometry(scene)
        self.s.check()
        runtime._same_snapshot(runtime.refresh(self.s.window), snapshot)
        return runtime.prepared_ref(scene, role)

    def _click(self, scene, role):
        target = self._target(scene, role)
        sent = self.s.input("click", target)
        if sent is False:
            raise InputInterrupted("간식 메뉴 입력 전 창/전경이 변경되었습니다.")
        return target

    def _open_recipe(self):
        if self.s.ocr is None:
            from .focused_ocr import FocusedOCR
            self.s.ocr = FocusedOCR()
        self.s.window.focus()
        if not self.consume_known_field():
            self.wait_screen(lambda image: common_field_ready(self.s, image), "간식 제작 전 기본화면 확인 필요")
        fallback = (("snack.menu", "snack.tab"), ("snack.list", "snack.food"),
                    ("snack.list", "snack.recipe"))
        steps = route("snack.select.prepared", fallback)
        require(isinstance(steps, (list, tuple)) and 1 <= len(steps) <= 12 and
                all(isinstance(step, (list, tuple)) and len(step) == 2 and tuple(step) in fallback
                    for step in steps), "간식 준비 선택 규칙의 scene/role이 잘못되었습니다.")
        self._recipe_owner = None
        with self.s.coordinate_sequence():
            if self.s.input("key", "K") is False:
                raise InputInterrupted("간식 제작 메뉴 열기 입력 보류")
            for scene, role in steps:
                self._click(scene, role)
            self.s.coordinate_step()
        if tuple(steps[-1]) == ("snack.list", "snack.recipe"):
            self._recipe_owner = self._route_context()

    def _set_batch_count(self, quantity=BATCH):
        validate_quantity(quantity)
        with self.s.coordinate_sequence():
            self._click("snack.detail", "snack.count")
            if self.s.input("snack_text", str(quantity)) is False:
                raise InputInterrupted("간식 수량 입력 보류")
            self._click("snack.detail", "snack.blur")
            self.s.coordinate_step()
        self._batch_owner = self._route_context()

    def craft_target(self):
        return self._target("snack.detail", "snack.craft")

    def result_target(self):
        return self._target("snack.result", "snack.result.confirm")

    def _resume_cleanup(self):
        after = super()._resume_cleanup()
        runtime = self.s._ui_route_runtime()
        runtime.release_scene()
        return after
