import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

import 'package:muning_menu_recommender/main.dart';

void main() {
  group('Muning Menu Recommender App Tests', () {
    testWidgets('App should start without crashing', (
      WidgetTester tester,
    ) async {
      // Build our app and trigger a frame.
      await tester.pumpWidget(
        const ProviderScope(child: AmoriMenuRecommenderApp()),
      );

      // Verify that the app starts
      expect(find.byType(MaterialApp), findsOneWidget);
    });

    testWidgets('Splash screen should be displayed initially', (
      WidgetTester tester,
    ) async {
      await tester.pumpWidget(
        const ProviderScope(child: AmoriMenuRecommenderApp()),
      );

      // Should show splash screen initially
      expect(find.text('Muning Menu Recommender'), findsOneWidget);
    });
  });

  group('Black Box Testing - Equivalence Class Partitioning', () {
    test('Valid email format should pass validation', () {
      final validEmails = [
        'user@example.com',
        'test.email@domain.co.id',
        'user123@gmail.com',
      ];

      for (final email in validEmails) {
        expect(
          _isValidEmail(email),
          true,
          reason: 'Email $email should be valid',
        );
      }
    });

    test('Invalid email format should fail validation', () {
      final invalidEmails = [
        'invalid-email',
        '@domain.com',
        'user@',
        'user.domain.com',
        '',
      ];

      for (final email in invalidEmails) {
        expect(
          _isValidEmail(email),
          false,
          reason: 'Email $email should be invalid',
        );
      }
    });

    test('Valid password should pass validation', () {
      final validPasswords = ['password123', 'myPassword1', 'securePass2024'];

      for (final password in validPasswords) {
        expect(
          _isValidPassword(password),
          true,
          reason: 'Password should be valid',
        );
      }
    });

    test('Invalid password should fail validation', () {
      final invalidPasswords = [
        '123', // Too short
        'pass', // Too short
        '', // Empty
        'password', // No numbers
        '12345678', // No letters
      ];

      for (final password in invalidPasswords) {
        expect(
          _isValidPassword(password),
          false,
          reason: 'Password should be invalid',
        );
      }
    });
  });

  group('Black Box Testing - Boundary Value Analysis', () {
    test('Budget range boundary values', () {
      // Test minimum boundary
      expect(_isValidBudget(10000), true);
      expect(_isValidBudget(9999), false);

      // Test maximum boundary
      expect(_isValidBudget(200000), true);
      expect(_isValidBudget(200001), false);

      // Test middle values
      expect(_isValidBudget(50000), true);
      expect(_isValidBudget(100000), true);
    });

    test('OCR confidence threshold boundary values', () {
      // Test minimum acceptable confidence
      expect(_isAcceptableOCRConfidence(0.6), true);
      expect(_isAcceptableOCRConfidence(0.59), false);

      // Test maximum confidence
      expect(_isAcceptableOCRConfidence(1.0), true);
      expect(_isAcceptableOCRConfidence(1.01), false);
    });
  });

  group('Black Box Testing - Decision Table', () {
    test('User authentication decision table', () {
      // Test case 1: Valid email, valid password, terms accepted
      expect(_canUserRegister(true, true, true), true);

      // Test case 2: Valid email, valid password, terms not accepted
      expect(_canUserRegister(true, true, false), false);

      // Test case 3: Valid email, invalid password, terms accepted
      expect(_canUserRegister(true, false, true), false);

      // Test case 4: Invalid email, valid password, terms accepted
      expect(_canUserRegister(false, true, true), false);

      // Test case 5: All invalid
      expect(_canUserRegister(false, false, false), false);
    });

    test('Menu recommendation decision table', () {
      // Test case 1: Has preferences, menu available, no allergies
      expect(_shouldRecommendMenu(true, true, false), true);

      // Test case 2: Has preferences, menu available, has allergies
      expect(_shouldRecommendMenu(true, true, true), false);

      // Test case 3: No preferences, menu available, no allergies
      expect(_shouldRecommendMenu(false, true, false), true);

      // Test case 4: Has preferences, menu not available, no allergies
      expect(_shouldRecommendMenu(true, false, false), false);
    });
  });
}

// Helper functions for testing
bool _isValidEmail(String email) {
  return RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(email);
}

bool _isValidPassword(String password) {
  if (password.length < 6) return false;
  if (!RegExp(r'^(?=.*[a-zA-Z])(?=.*\d)').hasMatch(password)) return false;
  return true;
}

bool _isValidBudget(int budget) {
  return budget >= 10000 && budget <= 200000;
}

bool _isAcceptableOCRConfidence(double confidence) {
  return confidence >= 0.6 && confidence <= 1.0;
}

bool _canUserRegister(bool validEmail, bool validPassword, bool termsAccepted) {
  return validEmail && validPassword && termsAccepted;
}

bool _shouldRecommendMenu(
  bool hasPreferences,
  bool menuAvailable,
  bool hasAllergies,
) {
  if (!menuAvailable) return false;
  if (hasAllergies) return false;
  return true;
}
