import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:get/get.dart';
import 'package:mocktail/mocktail.dart';
import 'package:rasadyar_app/presentation/pages/splash/logic.dart';
import 'package:rasadyar_core/core.dart';

class MockGService extends Mock implements GService {}

class MockTokenStorageService extends Mock implements TokenStorageService {}

class MockTickerProvider extends Mock implements TickerProvider {
  @override
  Ticker createTicker(TickerCallback onTick) {
    return Ticker(onTick);
  }
}

void main() {
  group('SplashLogic Tests', () {
    late SplashLogic splashLogic;
    late MockGService mockGService;
    late MockTokenStorageService mockTokenService;

    setUp(() {
      mockGService = MockGService();
      mockTokenService = MockTokenStorageService();

      Get.put<GService>(mockGService);
      Get.put<TokenStorageService>(mockTokenService);

      splashLogic = SplashLogic();
    });

    tearDown(() {
      Get.reset();
    });

    test('should initialize animation controllers on init', () {
      // Act
      splashLogic.onInit();

      // Assert
      expect(splashLogic.scaleController, isA<AnimationController>());
      expect(splashLogic.rotateController, isA<AnimationController>());
      expect(splashLogic.scaleAnimation.value, isA<Animation<double>>());
      expect(splashLogic.rotationAnimation.value, isA<Animation<double>>());
    });

    test('should have correct initial values for reactive variables', () {
      // Assert
      expect(splashLogic.hasUpdated.value, false);
      expect(splashLogic.onUpdateDownload.value, false);
      expect(splashLogic.percent.value, 0.0);
    });

    test('should dispose animation controllers on close', () {
      // Arrange
      splashLogic.onInit();

      // Act
      splashLogic.onClose();

      // Assert - controllers should be disposed
      expect(() => splashLogic.scaleController.forward(), throwsA(isA<AssertionError>()));
      expect(() => splashLogic.rotateController.forward(), throwsA(isA<AssertionError>()));
    });

    test('should update percent value correctly', () {
      // Act
      splashLogic.percent.value = 0.5;

      // Assert
      expect(splashLogic.percent.value, 0.5);
    });

    test('should update hasUpdated value correctly', () {
      // Act
      splashLogic.hasUpdated.value = true;

      // Assert
      expect(splashLogic.hasUpdated.value, true);
    });

    test('should update onUpdateDownload value correctly', () {
      // Act
      splashLogic.onUpdateDownload.value = true;

      // Assert
      expect(splashLogic.onUpdateDownload.value, true);
    });
  });
}
