/// Created by Haoyi on 2023/5/5

import 'dart:convert';

import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:guru_app/analytics/data/analytics_model.dart';
import 'package:guru_app/analytics/guru_analytics.dart';
import 'package:guru_app/guru_app.dart';
import 'package:guru_app/property/property_keys.dart';
import 'package:guru_utils/log/log.dart';
import 'package:guru_utils/property/app_property.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:logger/logger.dart';

import 'dma_test.mocks.dart';

class MockPurposeConsents {
  static String purposeConsents = "0";
}

class ConsentTest {
  final String purpose;
  final String expect;

  ConsentTest(this.purpose, this.expect);
}

@GenerateMocks([GuruApp, AppSpec, Deployment, AdjustProfile, AppProperty])
void main() {
  TestWidgetsFlutterBinding.ensureInitialized();

  Log.init("DMA-TEST", persistentLevel: LogLevel.nothing);

  MethodChannel platformDataChannel = const MethodChannel('app.guru.guru_platform_data');
  TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger
      .setMockMethodCallHandler(platformDataChannel, (call) async {
    switch (call.method) {
      case "get_purpose_consents":
        return MockPurposeConsents.purposeConsents;
    }
  });

  MethodChannel adjustChannel = const MethodChannel('com.adjust.sdk/api');
  TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger
      .setMockMethodCallHandler(adjustChannel, (call) async {
    switch (call.method) {
      case "trackThirdPartySharing":
        print(call.arguments);
        break;
    }
  });

  const analyticChannel = MethodChannel("flutter.guru.guru_analytics_flutter");
  TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger
      .setMockMethodCallHandler(analyticChannel, (call) async {
    print("${call.method} ${call.arguments}");
    return true;
  });

  final guruApp = MockGuruApp();
  GuruApp.setMockInstance(guruApp);
  final MockAdjustProfile adjustProfile = MockAdjustProfile();
  when(adjustProfile.isEnabled).thenReturn(true);

  final MockAppSpec appSpec = MockAppSpec();
  final MockDeployment deployment = MockDeployment();

  when(deployment.enableAnalyticsStatistic).thenReturn(false);
  when(appSpec.deployment).thenReturn(deployment);
  when(guruApp.appSpec).thenReturn(appSpec);

  final MockAppProperty mockAppProperty = MockAppProperty();
  when(mockAppProperty.getString(PropertyKeys.googleDma, defValue: anyNamed('defValue')))
      .thenAnswer((_) async => "");
  when(mockAppProperty.setString(PropertyKeys.googleDma, any)).thenAnswer((_) async => true);
  AppProperty.setMock(mockAppProperty);
  GuruAnalytics.setMock();
  test("Test Dma", () async {
    when(guruApp.adjustProfile).thenReturn(adjustProfile);
    final consents = [
      ConsentTest("0", "0100"),
      ConsentTest("0000001", "0100"),
      ConsentTest("00000010", "0100"),
      ConsentTest("00000010000", "0100"),
      ConsentTest("0010001", "0100"),
      ConsentTest("0001001", "0100"),
      ConsentTest("00100010000", "0100"),
      ConsentTest("00010010000", "0100"),
      ConsentTest("0011001", "0110"),
      ConsentTest("00110010", "0110"),
      ConsentTest("00110010000", "0110"),
      ConsentTest("1", "1100"),
      ConsentTest("10", "1100"),
      ConsentTest("1000001", "1101"),
      ConsentTest("10000010", "1101"),
      ConsentTest("10000010000", "1101"),
      ConsentTest("1010001", "1101"),
      ConsentTest("1001001", "1101"),
      ConsentTest("10100010000", "1101"),
      ConsentTest("10010010000", "1101"),
      ConsentTest("1011001", "1111"),
      ConsentTest("10110010", "1111"),
      ConsentTest("10110010000", "1111"),
      ConsentTest("11111111111", "1111"),
      ConsentTest("1011001000000000011100", "1111"),
      ConsentTest("1010001000000000001110", "1101"),
      ConsentTest("adfadf2132", ""),
    ];

    final analyticsConfig = json.decode(
        '{"cap":"firebase|facebook|guru", "init_delay_s": 10, "google_dma": [1, 0, 12, 65], "dma_country": []}');
    GuruAnalytics.mockCountryCode = "cn";
    for (int i = 0; i < consents.length; ++i) {
      MockPurposeConsents.purposeConsents = consents[i].purpose;
      String result = await GuruAnalytics.instance
          .refreshConsents(analyticsConfig: AnalyticsConfig.fromJson(analyticsConfig));
      expect(result, consents[i].expect);
    }
  });
}
