from __future__ import annotations

from pathlib import Path
from unittest import TestCase

_REPO_ROOT = Path(__file__).resolve().parents[2]


class TestOrderTableActionContracts(TestCase):
    """Source-code contracts for OrderTable status actions."""

    def _read_table_source(self) -> str:
        path = _REPO_ROOT / "frontend/src/lib/components/OrderTable.svelte"
        return path.read_text(encoding="utf-8")

    # ── DropdownMenu action visibility ─────────────────────────────

    def test_dropdown_menu_imported(self) -> None:
        source = self._read_table_source()
        self.assertIn("DropdownMenu", source)
        self.assertIn("$lib/components/ui/dropdown-menu", source)

    def test_actions_scoped_to_valid_transitions(self) -> None:
        source = self._read_table_source()
        self.assertIn("ORDER_TRANSITIONS", source)

    def test_terminal_statuses_show_no_actions(self) -> None:
        source = self._read_table_source()
        self.assertIn("ORDER_TRANSITIONS[o.status]?.length > 0", source)

    def test_status_labels_used_for_action_text(self) -> None:
        source = self._read_table_source()
        self.assertIn("STATUS_LABELS", source)

    # ── Cancel confirmation gating ───────────────────────────────

    def test_alert_dialog_imported(self) -> None:
        source = self._read_table_source()
        self.assertIn("AlertDialog", source)
        self.assertIn("$lib/components/ui/alert-dialog", source)

    def test_cancel_opens_dialog(self) -> None:
        source = self._read_table_source()
        self.assertIn("cancelTarget", source)
        self.assertIn("openCancelDialog", source)

    def test_cancel_action_styled_destructive(self) -> None:
        source = self._read_table_source()
        self.assertIn("text-destructive", source)
        self.assertIn("Cancel Order", source)

    def test_cancel_dialog_has_confirm_action(self) -> None:
        source = self._read_table_source()
        self.assertIn("Confirm Cancel", source)
        self.assertIn("bg-destructive", source)

    # ── Mutation and post-mutation updates ───────────────────────

    def test_tanstack_mutation_used(self) -> None:
        source = self._read_table_source()
        self.assertIn("createMutation", source)
        self.assertIn("@tanstack/svelte-query", source)

    def test_mutation_calls_update_order_status(self) -> None:
        source = self._read_table_source()
        self.assertIn("updateOrderStatus", source)

    def test_success_toast_shown(self) -> None:
        source = self._read_table_source()
        self.assertIn("toast.promise", source)
        self.assertIn("success", source)
        self.assertIn("svelte-sonner", source)

    def test_error_toast_shown(self) -> None:
        source = self._read_table_source()
        self.assertIn("toast.promise", source)
        self.assertIn("error", source)

    def test_invalidate_all_after_mutation(self) -> None:
        source = self._read_table_source()
        self.assertIn("invalidateAll", source)


class TestOrdersPageStatsContracts(TestCase):
    """Source-code contracts for orders page stats display."""

    def _read_page_source(self) -> str:
        path = _REPO_ROOT / "frontend/src/routes/(app)/orders/+page.svelte"
        return path.read_text(encoding="utf-8")

    def _read_server_source(self) -> str:
        path = _REPO_ROOT / "frontend/src/routes/(app)/orders/+page.server.ts"
        return path.read_text(encoding="utf-8")

    def test_page_imports_stat_card(self) -> None:
        source = self._read_page_source()
        self.assertIn("StatCard", source)

    def test_page_displays_five_stat_cards(self) -> None:
        source = self._read_page_source()
        stat_fns = (
            "m.orders_stat_today()",
            "m.orders_stat_pending()",
            "m.orders_stat_preparing()",
            "m.orders_stat_completed()",
            "m.orders_stat_cancelled()",
        )
        for fn in stat_fns:
            self.assertIn(fn, source)

    def test_page_uses_stats_from_data(self) -> None:
        source = self._read_page_source()
        self.assertIn("data.stats", source)

    def test_server_computes_stats(self) -> None:
        source = self._read_server_source()
        self.assertIn("computeOrderStats", source)

    def test_server_returns_stats(self) -> None:
        source = self._read_server_source()
        self.assertIn("stats", source)


class TestOrderApiHelperContracts(TestCase):
    """Source-code contracts for frontend order API helpers."""

    def _read_api_source(self) -> str:
        path = _REPO_ROOT / "frontend/src/lib/api/orders.ts"
        return path.read_text(encoding="utf-8")

    def test_update_order_status_function_exists(self) -> None:
        source = self._read_api_source()
        self.assertIn("export async function updateOrderStatus", source)

    def test_update_uses_patch_method(self) -> None:
        source = self._read_api_source()
        idx = source.index("updateOrderStatus")
        block = source[idx : idx + 500]
        self.assertIn("PATCH", block)

    def test_update_sends_new_status_field(self) -> None:
        source = self._read_api_source()
        self.assertIn("new_status", source)

    def test_order_transitions_map_exported(self) -> None:
        source = self._read_api_source()
        self.assertIn("export const ORDER_TRANSITIONS", source)

    def test_order_status_value_type_exported(self) -> None:
        source = self._read_api_source()
        self.assertIn("export type OrderStatusValue", source)

    def test_compute_order_stats_exported(self) -> None:
        source = self._read_api_source()
        self.assertIn("export function computeOrderStats", source)

    def test_order_stats_interface_exported(self) -> None:
        source = self._read_api_source()
        self.assertIn("export interface OrderStats", source)
