Feature: TUI PermissionsScreen
  Scenarios exercising the PermissionsScreen widget and supporting
  domain models / service for tool permission requests.

  # ── DiffDisplayMode enum ──────────────────────────────────────

  Scenario: DiffDisplayMode has three values
    When I inspect the DiffDisplayMode enum
    Then DiffDisplayMode should have values "unified", "split", "auto"

  # ── FileChangeType enum ───────────────────────────────────────

  Scenario: FileChangeType has three values
    When I inspect the FileChangeType enum
    Then FileChangeType should have values "M", "A", "D"

  # ── PermissionDecision enum ───────────────────────────────────

  Scenario: PermissionDecision has four values
    When I inspect the PermissionDecision enum
    Then PermissionDecision should have values "allow_once", "allow_always", "reject_once", "reject_always"

  # ── PermissionRequest model ───────────────────────────────────

  Scenario: PermissionRequest generates a unified diff
    Given a PermissionRequest for "src/auth/handler.py" with before and after content
    When I render the diff in "unified" mode
    Then the rendered diff should contain "@@"
    And the rendered diff should contain "+"
    And the rendered diff should contain "-"

  Scenario: PermissionRequest generates a split diff
    Given a PermissionRequest for "src/auth/handler.py" with before and after content
    When I render the diff in "split" mode
    Then the rendered diff should contain "|"

  Scenario: PermissionRequest generates an auto diff
    Given a PermissionRequest for "src/auth/handler.py" with before and after content
    When I render the diff in "auto" mode
    Then the rendered diff should contain "***"

  Scenario: PermissionRequest unified diff with no changes returns empty string
    Given a PermissionRequest for "src/empty.py" with identical before and after content
    When I render the diff in "unified" mode
    Then the rendered diff should be empty

  Scenario: PermissionRequest split diff returns equal lines for identical content
    Given a PermissionRequest for "src/empty.py" with identical before and after content
    When I call split_diff on the request
    Then both sides should have the same number of lines

  Scenario: PermissionRequest auto_diff with no changes returns empty string
    Given a PermissionRequest for "src/empty.py" with identical before and after content
    When I render the diff in "auto" mode
    Then the rendered diff should be empty

  Scenario: PermissionRequest render_diff dispatches to unified
    Given a PermissionRequest for "src/auth/handler.py" with before and after content
    When I render the diff in "unified" mode
    Then the rendered diff should contain "a/src/auth/handler.py"

  Scenario: PermissionRequest render_diff dispatches to auto
    Given a PermissionRequest for "src/auth/handler.py" with before and after content
    When I render the diff in "auto" mode
    Then the rendered diff should contain "a/src/auth/handler.py"

  # ── ToolPermissionRequest model ───────────────────────────────

  Scenario: ToolPermissionRequest is pending when no decision is set
    Given a ToolPermissionRequest with no decision
    Then the request should be pending
    And the request should not be allowed
    And the request should not be rejected

  Scenario: ToolPermissionRequest is allowed after allow_once decision
    Given a ToolPermissionRequest with no decision
    When I apply decision "allow_once" to the request
    Then the request should be allowed
    And the request should not be pending

  Scenario: ToolPermissionRequest is allowed after allow_always decision
    Given a ToolPermissionRequest with no decision
    When I apply decision "allow_always" to the request
    Then the request should be allowed

  Scenario: ToolPermissionRequest is rejected after reject_once decision
    Given a ToolPermissionRequest with no decision
    When I apply decision "reject_once" to the request
    Then the request should be rejected
    And the request should not be pending

  Scenario: ToolPermissionRequest is rejected after reject_always decision
    Given a ToolPermissionRequest with no decision
    When I apply decision "reject_always" to the request
    Then the request should be rejected

  Scenario: ToolPermissionRequest apply_decision returns a new instance
    Given a ToolPermissionRequest with no decision
    When I apply decision "allow_once" to the request
    Then the original request should still be pending

  # ── PermissionRequestService ──────────────────────────────────

  Scenario: PermissionRequestService enqueues a request
    Given a fresh PermissionRequestService
    When I enqueue a request with id "req-1" for tool "local/file-write"
    Then the service should have 1 pending request

  Scenario: PermissionRequestService records allow_once decision
    Given a fresh PermissionRequestService
    When I enqueue a request with id "req-1" for tool "local/file-write"
    And I record decision "allow_once" for request "req-1"
    Then the service should have 0 pending requests
    And the request "req-1" should have decision "allow_once"

  Scenario: PermissionRequestService records reject_once decision
    Given a fresh PermissionRequestService
    When I enqueue a request with id "req-1" for tool "local/file-write"
    And I record decision "reject_once" for request "req-1"
    Then the service should have 0 pending requests
    And the request "req-1" should have decision "reject_once"

  Scenario: PermissionRequestService auto-resolves with allow_always session decision
    Given a fresh PermissionRequestService
    When I enqueue a request with id "req-1" for tool "local/file-write"
    And I record decision "allow_always" for request "req-1"
    And I enqueue a request with id "req-2" for tool "local/file-write"
    Then the service should have 0 pending requests
    And the request "req-2" should have decision "allow_always"

  Scenario: PermissionRequestService auto-resolves with reject_always session decision
    Given a fresh PermissionRequestService
    When I enqueue a request with id "req-1" for tool "local/file-write"
    And I record decision "reject_always" for request "req-1"
    And I enqueue a request with id "req-2" for tool "local/file-write"
    Then the service should have 0 pending requests
    And the request "req-2" should have decision "reject_always"

  Scenario: PermissionRequestService get_session_decision returns None when not set
    Given a fresh PermissionRequestService
    Then the session decision for "local/file-write" should be None

  Scenario: PermissionRequestService get_session_decision returns decision after allow_always
    Given a fresh PermissionRequestService
    When I enqueue a request with id "req-1" for tool "local/file-write"
    And I record decision "allow_always" for request "req-1"
    Then the session decision for "local/file-write" should be "allow_always"

  Scenario: PermissionRequestService clear_session_decision removes the decision
    Given a fresh PermissionRequestService
    When I enqueue a request with id "req-1" for tool "local/file-write"
    And I record decision "allow_always" for request "req-1"
    And I clear the session decision for "local/file-write"
    Then the session decision for "local/file-write" should be None

  Scenario: PermissionRequestService clear_session_decision returns False when not set
    Given a fresh PermissionRequestService
    When I clear the session decision for "local/file-write"
    Then the clear result should be False

  Scenario: PermissionRequestService record_decision returns None for unknown id
    Given a fresh PermissionRequestService
    When I record decision "allow_once" for request "nonexistent"
    Then the decision result should be None

  Scenario: PermissionRequestService get returns None for unknown id
    Given a fresh PermissionRequestService
    Then getting request "nonexistent" should return None

  Scenario: PermissionRequestService all_requests returns all requests
    Given a fresh PermissionRequestService
    When I enqueue a request with id "req-1" for tool "local/file-write"
    And I enqueue a request with id "req-2" for tool "local/file-write"
    Then the service should have 2 total requests

  Scenario: PermissionRequestService clear_all removes everything
    Given a fresh PermissionRequestService
    When I enqueue a request with id "req-1" for tool "local/file-write"
    And I record decision "allow_always" for request "req-1"
    And I clear all requests
    Then the service should have 0 total requests
    And the session decision for "local/file-write" should be None

  # ── PermissionsScreen widget ──────────────────────────────────

  Scenario: PermissionsScreen loads a request and renders content
    Given a fresh PermissionsScreen
    When I load a ToolPermissionRequest with 3 file changes
    Then the screen text should contain "Permission Request"
    And the screen text should contain "Files (3 changes)"
    And the screen text should contain "local/file-write"

  Scenario: PermissionsScreen shows the first file selected by default
    Given a fresh PermissionsScreen
    When I load a ToolPermissionRequest with 3 file changes
    Then the selected index should be 0
    And the screen text should contain "❯"

  Scenario: PermissionsScreen navigate_next moves to next file
    Given a fresh PermissionsScreen
    When I load a ToolPermissionRequest with 3 file changes
    And I navigate next on the screen
    Then the selected index should be 1

  Scenario: PermissionsScreen navigate_prev wraps around
    Given a fresh PermissionsScreen
    When I load a ToolPermissionRequest with 3 file changes
    And I navigate prev on the screen
    Then the selected index should be 2

  Scenario: PermissionsScreen navigate_next wraps around at end
    Given a fresh PermissionsScreen
    When I load a ToolPermissionRequest with 3 file changes
    And I navigate next on the screen
    And I navigate next on the screen
    And I navigate next on the screen
    Then the selected index should be 0

  Scenario: PermissionsScreen cycle_diff_mode cycles through modes
    Given a fresh PermissionsScreen
    When I load a ToolPermissionRequest with 3 file changes
    Then the diff mode should be "unified"
    When I cycle the diff mode
    Then the diff mode should be "split"
    When I cycle the diff mode
    Then the diff mode should be "auto"
    When I cycle the diff mode
    Then the diff mode should be "unified"

  Scenario: PermissionsScreen set_diff_mode sets mode directly
    Given a fresh PermissionsScreen
    When I load a ToolPermissionRequest with 3 file changes
    And I set the diff mode to "split"
    Then the diff mode should be "split"

  Scenario: PermissionsScreen allow_once records decision
    Given a fresh PermissionsScreen
    When I load a ToolPermissionRequest with 3 file changes
    And I press allow_once on the screen
    Then the screen decision should be "allow_once"

  Scenario: PermissionsScreen allow_always records decision
    Given a fresh PermissionsScreen
    When I load a ToolPermissionRequest with 3 file changes
    And I press allow_always on the screen
    Then the screen decision should be "allow_always"

  Scenario: PermissionsScreen reject_once records decision
    Given a fresh PermissionsScreen
    When I load a ToolPermissionRequest with 3 file changes
    And I press reject_once on the screen
    Then the screen decision should be "reject_once"

  Scenario: PermissionsScreen reject_always records decision
    Given a fresh PermissionsScreen
    When I load a ToolPermissionRequest with 3 file changes
    And I press reject_always on the screen
    Then the screen decision should be "reject_always"

  Scenario: PermissionsScreen clear resets state
    Given a fresh PermissionsScreen
    When I load a ToolPermissionRequest with 3 file changes
    And I press allow_once on the screen
    And I clear the screen
    Then the screen decision should be None
    And the screen text should be empty

  Scenario: PermissionsScreen with no request shows placeholder
    Given a fresh PermissionsScreen
    Then the screen text should contain "(no permission request)"

  Scenario: PermissionsScreen navigate_next does nothing with no request
    Given a fresh PermissionsScreen
    When I navigate next on the screen
    Then the selected index should be 0

  Scenario: PermissionsScreen navigate_prev does nothing with no request
    Given a fresh PermissionsScreen
    When I navigate prev on the screen
    Then the selected index should be 0

  Scenario: PermissionsScreen shows diff mode in status bar
    Given a fresh PermissionsScreen
    When I load a ToolPermissionRequest with 3 file changes
    Then the screen text should contain "unified"

  Scenario: PermissionsScreen shows keyboard bindings in status bar
    Given a fresh PermissionsScreen
    When I load a ToolPermissionRequest with 3 file changes
    Then the screen text should contain "Allow"
    And the screen text should contain "Reject"

  Scenario: PermissionsScreen shows diff content for selected file
    Given a fresh PermissionsScreen
    When I load a ToolPermissionRequest with 3 file changes
    Then the screen text should contain "file0.py"

  Scenario: PermissionsScreen navigate_next with empty changes list does nothing
    Given a fresh PermissionsScreen
    When I load a ToolPermissionRequest with 0 file changes
    And I navigate next on the screen
    Then the selected index should be 0

  Scenario: PermissionsScreen navigate_prev with empty changes list does nothing
    Given a fresh PermissionsScreen
    When I load a ToolPermissionRequest with 0 file changes
    And I navigate prev on the screen
    Then the selected index should be 0

  # ── _next_diff_mode helper ────────────────────────────────────

  Scenario: _next_diff_mode cycles unified to split
    When I call _next_diff_mode with "unified"
    Then the next diff mode result should be "split"

  Scenario: _next_diff_mode cycles split to auto
    When I call _next_diff_mode with "split"
    Then the next diff mode result should be "auto"

  Scenario: _next_diff_mode cycles auto back to unified
    When I call _next_diff_mode with "auto"
    Then the next diff mode result should be "unified"

  # ── Rendering helpers ─────────────────────────────────────────

  Scenario: _render_file_list marks selected file with arrow
    When I render a file list with 2 files and selected index 1
    Then the file list should contain "❯" on the second entry

  Scenario: _render_diff_panel returns placeholder for None change
    When I render a diff panel with no change
    Then the diff panel should contain "(no file selected)"

  Scenario: _render_diff_panel returns placeholder for empty diff
    When I render a diff panel with an identical-content change
    Then the diff panel should contain "(no changes)"

  Scenario: _render_status_bar includes tool name and resource name
    When I render a status bar for tool "local/file-write" and resource "local/api-service"
    Then the status bar should contain "local/file-write"
    And the status bar should contain "local/api-service"

  # ── PermissionsScreen property accessors ─────────────────────

  Scenario: PermissionsScreen current_request returns None initially
    Given a fresh PermissionsScreen
    Then the screen current_request should be None

  Scenario: PermissionsScreen current_request returns loaded request
    Given a fresh PermissionsScreen
    When I load a ToolPermissionRequest with 3 file changes
    Then the screen current_request should not be None

  # ── PermissionRequest split_diff delete/insert branches ────────

  Scenario: PermissionRequest split_diff handles delete-only change
    Given a PermissionRequest with only deleted lines
    When I call split_diff on the request
    Then the left side should have non-empty lines
    And the right side should have empty lines for deleted content

  Scenario: PermissionRequest split_diff handles insert-only change
    Given a PermissionRequest with only inserted lines
    When I call split_diff on the request
    Then the right side should have non-empty lines
    And the left side should have empty lines for inserted content

  # ── PermissionRequestService clear_session_decision return True ─

  Scenario: PermissionRequestService clear_session_decision returns True when decision exists
    Given a fresh PermissionRequestService
    When I enqueue a request with id "req-1" for tool "local/file-write"
    And I record decision "allow_always" for request "req-1"
    And I clear the session decision for "local/file-write"
    Then the clear result should be True

  # ── Bug #10488: PermissionsScreen must inherit from Screen ────

  @tdd_issue @tdd_issue_10488
  Scenario: Bug #10488 - PermissionsScreen inherits from textual.app.Screen
    When I check the base class of PermissionsScreen
    Then PermissionsScreen should be a subclass of textual.app.Screen

  @tdd_issue @tdd_issue_10488
  Scenario: Bug #10488 - PermissionsScreen has BINDINGS class variable
    When I check the base class of PermissionsScreen
    Then PermissionsScreen should have a BINDINGS class variable

  @tdd_issue @tdd_issue_10488
  Scenario: Bug #10488 - PermissionsScreen has action methods for keyboard bindings
    When I check the base class of PermissionsScreen
    Then PermissionsScreen should have action method "action_allow_once"
    And PermissionsScreen should have action method "action_allow_always"
    And PermissionsScreen should have action method "action_reject_once"
    And PermissionsScreen should have action method "action_reject_always"
    And PermissionsScreen should have action method "action_nav_next"
    And PermissionsScreen should have action method "action_nav_prev"
    And PermissionsScreen should have action method "action_cycle_diff"
    And PermissionsScreen should have action method "action_dismiss_screen"
