import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:recipe_flutter/features/admin/data/admin_repository.dart';
import 'package:recipe_flutter/features/admin/domain/admin_ai_categorize_result.dart';
import 'package:recipe_flutter/features/admin/domain/admin_ai_trace.dart';
import 'package:recipe_flutter/features/admin/domain/admin_ai_trace_detail.dart';
import 'package:recipe_flutter/features/admin/domain/admin_category_node.dart';
import 'package:recipe_flutter/features/admin/domain/admin_inventory_item.dart';
import 'package:recipe_flutter/features/admin/domain/admin_pantry_item.dart';
import 'package:recipe_flutter/features/admin/domain/admin_product.dart';
import 'package:recipe_flutter/features/admin/domain/ai_model_info.dart';
import 'package:recipe_flutter/features/admin/domain/pending_product.dart';
import 'package:recipe_flutter/features/admin/domain/receipt_alias.dart';
import 'package:recipe_flutter/features/admin/domain/user_admin.dart';
import 'package:recipe_flutter/features/admin/presentation/admin_aliases_panel.dart';

// Test wrapper that implements AdminRepository with minimal methods
class TestAdminRepositoryWrapper implements AdminRepository {
  final FakeAdminRepository _fakeRepo;

  TestAdminRepositoryWrapper(this._fakeRepo);

  @override
  Future<List<ReceiptAlias>> listReceiptAliases() =>
      _fakeRepo.listReceiptAliases();

  @override
  Future<List<AdminProduct>> listGlobalProducts() =>
      _fakeRepo.listGlobalProducts();

  @override
  Future<void> updateReceiptAlias(int id,
          {String? receiptName, int? productId, bool? isGlobal}) =>
      _fakeRepo.updateReceiptAlias(id,
          receiptName: receiptName, productId: productId, isGlobal: isGlobal);

  // Stub implementations for other required methods
  @override
  Future<List<AdminAiCategorizeResult>> aiCategorizeBulk(
          {List<int>? productIds}) =>
      throw UnimplementedError();
  @override
  Future<int> bulkSetCategory(List<int> ids, {required int? categoryId}) =>
      throw UnimplementedError();
  @override
  Future<AdminInventoryItem> createAdminInventory(
          {int? userId,
          required int productId,
          required double quantity,
          required String unit,
          String? location,
          String? brand,
          String? receiptName,
          String? suitableFor,
          String? comment}) =>
      throw UnimplementedError();
  @override
  Future<AdminPantryItem> createAdminPantry(
          {int? userId, required int productId, String? location}) =>
      throw UnimplementedError();
  @override
  Future<Map<String, dynamic>> createProduct(String name, {int? categoryId}) =>
      throw UnimplementedError();
  @override
  Future<UserAdmin> createUser(
          {required String username,
          required String email,
          required String password,
          String role = 'user'}) =>
      throw UnimplementedError();
  @override
  Future<void> deleteUser(int userId) => throw UnimplementedError();
  @override
  Future<List<AdminInventoryItem>> listAdminInventory(
          {int? userId, String? sort}) =>
      throw UnimplementedError();
  @override
  Future<List<AdminPantryItem>> listAdminPantry({int? userId}) =>
      throw UnimplementedError();
  @override
  Future<List<AiModelInfo>> listAiModels() => throw UnimplementedError();
  @override
  Future<AdminAiTraceDetail> getAiTraceById(String traceId) =>
      throw UnimplementedError();
  @override
  Future<AdminAiTraceListResponse> listAiTraces(
          {required AdminAiTraceSource source,
          int limit = 25,
          String? cursor,
          String? period,
          bool onlyErrors = false}) =>
      throw UnimplementedError();
  @override
  Future<List<AdminCategoryNode>> listCategoryTree() =>
      throw UnimplementedError();
  @override
  Future<List<AdminProduct>> listDeletedProducts() =>
      throw UnimplementedError();
  @override
  Future<List<PendingProduct>> listPendingProducts() =>
      throw UnimplementedError();
  @override
  Future<List<PendingProduct>> listPrivateProducts() =>
      throw UnimplementedError();
  @override
  Future<List<AdminProduct>> listProducts() => throw UnimplementedError();
  @override
  Future<List<AdminProduct>> listSelectableProductsForAdmin(
          {bool forceRefresh = false}) =>
      throw UnimplementedError();
  @override
  Future<List<UserAdmin>> listUsers() => throw UnimplementedError();
  @override
  Future<void> mergeAdminInventory(
          {required int sourceInventoryId, required int targetInventoryId}) =>
      throw UnimplementedError();
  @override
  Future<void> mergeProducts(
          {required int sourceProductId, required int targetProductId}) =>
      throw UnimplementedError();
  @override
  Future<void> mergeProductsPrivate(
          {required int sourceProductId, required int targetProductId}) =>
      throw UnimplementedError();
  @override
  Future<void> moveAdminInventoryToPantry(int inventoryId) =>
      throw UnimplementedError();
  @override
  Future<void> moveAdminPantryToInventory(
          int pantryItemId, Map<String, dynamic> body) =>
      throw UnimplementedError();
  @override
  Future<Map<String, dynamic>> previewAdminInventoryMerge(
          {required int sourceInventoryId, required int targetInventoryId}) =>
      throw UnimplementedError();
  @override
  Future<Map<String, dynamic>> previewMerge(
          {required int sourceProductId, required int targetProductId}) =>
      throw UnimplementedError();
  @override
  Future<AdminProduct> promotePrivateProduct(int productId) =>
      throw UnimplementedError();
  @override
  Future<void> removeAdminInventory(int inventoryId) =>
      throw UnimplementedError();
  @override
  Future<void> removeAdminPantryItem(int pantryItemId) =>
      throw UnimplementedError();
  @override
  Future<void> removeProduct(int productId) => throw UnimplementedError();
  @override
  Future<void> removeReceiptAlias(int id) => throw UnimplementedError();
  @override
  Future<Map<String, dynamic>> resetPassword(int userId) =>
      throw UnimplementedError();
  @override
  Future<void> restoreProduct(int productId) => throw UnimplementedError();
  @override
  Future<UserAdmin> setPremium(int userId, {required bool isPremium}) =>
      throw UnimplementedError();
  @override
  Future<void> setProductCategory(int productId, {required int? categoryId}) =>
      throw UnimplementedError();
  @override
  Future<void> setProductStatus(int productId, String status) =>
      throw UnimplementedError();
  @override
  Future<UserAdmin> setRecipeSharing(int userId,
          {required bool canShareRecipes}) =>
      throw UnimplementedError();
  @override
  Future<UserAdmin> setRole(int userId, String newRole) =>
      throw UnimplementedError();
  @override
  Future<AdminInventoryItem> updateAdminInventory(int inventoryId,
          {int? productId,
          double? quantity,
          String? unit,
          String? location,
          String? brand,
          String? receiptName,
          String? suitableFor,
          String? comment}) =>
      throw UnimplementedError();
  @override
  Future<AdminPantryItem> updateAdminPantry(int pantryItemId,
          {int? productId, String? location}) =>
      throw UnimplementedError();
  @override
  Future<void> updateCanonicalName(int productId, String canonicalName) =>
      throw UnimplementedError();
  @override
  Future<void> updateCanonicalNamePrivate(
          int productId, String canonicalName) =>
      throw UnimplementedError();
  @override
  Future<void> updateEmail(int userId, String email) =>
      throw UnimplementedError();
  @override
  Future<void> upsertReceiptAlias(
          {required String receiptName,
          required int productId,
          bool isGlobal = false}) =>
      throw UnimplementedError();
}

// Simple fake that only implements the methods we need
class FakeAdminRepository {
  List<ReceiptAlias> _aliases = [];
  List<AdminProduct> _products = [];

  Future<List<ReceiptAlias>> listReceiptAliases() async {
    return _aliases;
  }

  Future<List<AdminProduct>> listGlobalProducts() async {
    return _products;
  }

  Future<void> updateReceiptAlias(int id,
      {String? receiptName, int? productId, bool? isGlobal}) async {
    // Find and update alias
    final index = _aliases.indexWhere((a) => a.id == id);
    if (index >= 0) {
      _aliases[index] = ReceiptAlias(
        id: id,
        receiptName: receiptName ?? _aliases[index].receiptName,
        productId: productId ?? _aliases[index].productId,
        ownerId: _aliases[index].ownerId,
        productName: _products
            .firstWhere((p) => p.id == (productId ?? _aliases[index].productId))
            .displayName,
        isGlobal: isGlobal ?? _aliases[index].isGlobal,
      );
    }
  }

  void setAliases(List<ReceiptAlias> aliases) {
    _aliases = aliases;
  }

  void setProducts(List<AdminProduct> products) {
    _products = products;
  }
}

void main() {
  group('AdminAliasesPanel - Switch Tests', () {
    late FakeAdminRepository fakeRepo;
    late TestAdminRepositoryWrapper wrapper;
    late List<ReceiptAlias> mockAliases;
    late List<AdminProduct> mockProducts;

    setUp(() {
      fakeRepo = FakeAdminRepository();
      wrapper = TestAdminRepositoryWrapper(fakeRepo);
      mockProducts = [
        AdminProduct(
          id: 1,
          name: 'Test Product',
          canonicalName: 'Test Product',
          categoryPath: 'Test > Category',
        ),
      ];
      fakeRepo.setProducts(mockProducts);
    });

    testWidgets('Switch should be disabled for global alias', (tester) async {
      mockAliases = [
        ReceiptAlias(
          id: 1,
          receiptName: 'Global Alias',
          productId: 1,
          ownerId: null,
          productName: 'Test Product',
          isGlobal: true,
        ),
      ];
      fakeRepo.setAliases(mockAliases);

      await tester.pumpWidget(
        ProviderScope(
          overrides: [
            adminRepositoryProvider.overrideWithValue(wrapper),
          ],
          child: MaterialApp(
            home: Scaffold(
              body: AdminAliasesPanel(embedded: true),
            ),
          ),
        ),
      );

      await tester.pumpAndSettle();

      await tester.tap(find.byIcon(Icons.edit_outlined).first);
      await tester.pumpAndSettle();

      final switchListTileFinder = find.byType(SwitchListTile);
      expect(switchListTileFinder, findsOneWidget);

      final switchTile = tester.widget<SwitchListTile>(switchListTileFinder);
      expect(switchTile.value, isTrue);
      expect(switchTile.onChanged, isNull); // Disabled

      expect(find.text('Aliaset är redan globalt.'), findsOneWidget);
    });

    testWidgets('Switch should be enabled for private alias', (tester) async {
      mockAliases = [
        ReceiptAlias(
          id: 1,
          receiptName: 'Private Alias',
          productId: 1,
          ownerId: 123,
          productName: 'Test Product',
          isGlobal: false,
        ),
      ];
      fakeRepo.setAliases(mockAliases);

      await tester.pumpWidget(
        ProviderScope(
          overrides: [
            adminRepositoryProvider.overrideWithValue(wrapper),
          ],
          child: MaterialApp(
            home: Scaffold(
              body: AdminAliasesPanel(embedded: true),
            ),
          ),
        ),
      );

      await tester.pumpAndSettle();

      await tester.tap(find.byIcon(Icons.edit_outlined).first);
      await tester.pumpAndSettle();

      final switchListTileFinder = find.byType(SwitchListTile);
      expect(switchListTileFinder, findsOneWidget);

      final switchTile = tester.widget<SwitchListTile>(switchListTileFinder);
      expect(switchTile.value, isFalse);
      expect(switchTile.onChanged, isNotNull); // Enabled

      expect(find.text('Du kan göra privata alias globala.'), findsOneWidget);
    });
  });
}
