import 'package:flutter/foundation.dart';

import '../domain/policy_check_result.dart';
import 'get_policy_checks.dart';

/// Controller that manages the policy-checks workspace state, including
/// filtering by category, free-text search, and check selection.
class PolicyController extends ChangeNotifier {
  final GetPolicyChecks _getPolicyChecks;

  PolicyController(this._getPolicyChecks);

  bool isLoading = false;
  Object? error;

  /// All checks returned by the repository (unfiltered).
  List<PolicyCheckResult> _allChecks = [];

  /// The currently visible checks after applying [activeCategory] and [searchQuery].
  List<PolicyCheckResult> checks = [];

  /// The currently selected check for detail view.
  PolicyCheckResult? selectedCheck;

  /// The active category filter, or `null` for "all".
  ///
  /// Matches [PolicyCheckResult.category] values such as
  /// `'Product Compliance'`, `'Inventory Governance'`, etc.
  String? activeCategory;

  /// The current free-text search query applied to title / summary.
  String searchQuery = '';

  /// Loads all policy checks and applies any current filter / search.
  Future<void> load() async {
    isLoading = true;
    error = null;
    notifyListeners();

    try {
      _allChecks = await _getPolicyChecks();
      _applyFilters();
      // Auto-select the first check if nothing is selected.
      selectedCheck ??= checks.isNotEmpty ? checks.first : null;
    } catch (e) {
      error = e;
    } finally {
      isLoading = false;
      notifyListeners();
    }
  }

  /// Sets the category filter and recomputes the visible list.
  void setCategory(String? category) {
    activeCategory = category;
    _applyFilters();
    notifyListeners();
  }

  /// Sets the search query and recomputes the visible list.
  void setSearchQuery(String query) {
    searchQuery = query;
    _applyFilters();
    notifyListeners();
  }

  /// Selects a policy check for detail view.
  void selectCheck(PolicyCheckResult check) {
    selectedCheck = check;
    notifyListeners();
  }

  /// Attempts to select a check by ID. Returns `true` if found.
  bool selectById(String id) {
    final match = _allChecks.where((c) => c.id == id).firstOrNull;
    if (match != null) {
      selectedCheck = match;
      notifyListeners();
      return true;
    }
    return false;
  }

  // ── Private helpers ────────────────────────────────────────────────────

  void _applyFilters() {
    var result = _allChecks;

    // Category filter
    if (activeCategory != null && activeCategory!.isNotEmpty) {
      result = result.where((c) => c.category == activeCategory).toList();
    }

    // Free-text search on title and summary
    if (searchQuery.isNotEmpty) {
      final q = searchQuery.toLowerCase();
      result = result.where((c) {
        return c.title.toLowerCase().contains(q) || c.summary.toLowerCase().contains(q);
      }).toList();
    }

    checks = result;

    // Keep selection valid; clear if the selected check is no longer visible.
    if (selectedCheck != null && !checks.any((c) => c.id == selectedCheck!.id)) {
      selectedCheck = null;
    }
  }
}
