// SWE.4 unit tests for the BackIntentPolicy pure decision function.
//
// Requirement trace:
//   SDD-028 §2 (deterministic route-pop ordering) / SAD-018.
//   Verification-plan row: SWE4-UV-042 (swe4-unit-verification-plan.md).
//
// Strategy: enumerate ALL 8 combinations of the three boolean inputs
// (pttActive, modalOpen, atRoot) and assert the exact decision variant
// returned by `decideBackIntent`. The function is pure-Dart with no
// Flutter dependency, so no widget tester or platform channel is needed.

import 'package:flutter_test/flutter_test.dart';

import 'package:chanora_flutter/services/back_intent_policy.dart';

void main() {
  group('SWE4-UV-042 decideBackIntent truth table', () {
    // Branch 1 (highest priority): pttActive == true → IgnoreDueToPtt.
    // Four combinations of (modalOpen, atRoot) must all yield the same
    // decision because PTT-active short-circuits the whole policy.

    test('SWE4-UV-042: ptt=T, modal=F, atRoot=F → IgnoreDueToPtt', () {
      final d = decideBackIntent(
        pttActive: true,
        modalOpen: false,
        atRoot: false,
      );
      expect(d, isA<IgnoreDueToPtt>());
    });

    test('SWE4-UV-042: ptt=T, modal=F, atRoot=T → IgnoreDueToPtt', () {
      final d = decideBackIntent(
        pttActive: true,
        modalOpen: false,
        atRoot: true,
      );
      expect(d, isA<IgnoreDueToPtt>());
    });

    test('SWE4-UV-042: ptt=T, modal=T, atRoot=F → IgnoreDueToPtt', () {
      final d = decideBackIntent(
        pttActive: true,
        modalOpen: true,
        atRoot: false,
      );
      expect(d, isA<IgnoreDueToPtt>());
    });

    test('SWE4-UV-042: ptt=T, modal=T, atRoot=T → IgnoreDueToPtt', () {
      final d = decideBackIntent(
        pttActive: true,
        modalOpen: true,
        atRoot: true,
      );
      expect(d, isA<IgnoreDueToPtt>());
    });

    // Branch 2: pttActive == false && modalOpen == true → CloseModal.
    // atRoot is irrelevant when a modal is on top.

    test('SWE4-UV-042: ptt=F, modal=T, atRoot=F → CloseModal', () {
      final d = decideBackIntent(
        pttActive: false,
        modalOpen: true,
        atRoot: false,
      );
      expect(d, isA<CloseModal>());
    });

    test('SWE4-UV-042: ptt=F, modal=T, atRoot=T → CloseModal', () {
      final d = decideBackIntent(
        pttActive: false,
        modalOpen: true,
        atRoot: true,
      );
      expect(d, isA<CloseModal>());
    });

    // Branch 3: pttActive == false && modalOpen == false && atRoot == false
    // → PopRoute.

    test('SWE4-UV-042: ptt=F, modal=F, atRoot=F → PopRoute', () {
      final d = decideBackIntent(
        pttActive: false,
        modalOpen: false,
        atRoot: false,
      );
      expect(d, isA<PopRoute>());
    });

    // Branch 4 (default): all false except atRoot → ExitApp.

    test('SWE4-UV-042: ptt=F, modal=F, atRoot=T → ExitApp', () {
      final d = decideBackIntent(
        pttActive: false,
        modalOpen: false,
        atRoot: true,
      );
      expect(d, isA<ExitApp>());
    });

    test('SWE4-UV-042: variants are distinct and correctly typed', () {
      // Sanity: the four variants are NOT interchangeable. This guards
      // against an accidental refactor that collapses the sealed
      // hierarchy.
      const ignore = IgnoreDueToPtt();
      const close = CloseModal();
      const pop = PopRoute();
      const exit = ExitApp();

      expect(ignore, isA<BackIntentDecision>());
      expect(close, isA<BackIntentDecision>());
      expect(pop, isA<BackIntentDecision>());
      expect(exit, isA<BackIntentDecision>());

      expect(ignore, isNot(isA<CloseModal>()));
      expect(close, isNot(isA<PopRoute>()));
      expect(pop, isNot(isA<ExitApp>()));
      expect(exit, isNot(isA<IgnoreDueToPtt>()));

      expect(ignore.runtimeType, isNot(equals(close.runtimeType)));
      expect(pop.runtimeType, isNot(equals(exit.runtimeType)));
    });
  });
}
