// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:clock/clock.dart';
import 'package:file/file.dart';
import 'package:file/memory.dart';

import 'package:unified_analytics/src/constants.dart';
import 'package:unified_analytics/src/enums.dart';
import 'package:unified_analytics/src/survey_handler.dart';
import 'package:unified_analytics/unified_analytics.dart';

/// This example code is intended to only be used as guidance for
/// clients using this package. Clients using this package should avoid
/// the use of the [Analytics.fake] static method.
///
/// It was used in this example file so that the real [FileSystem] was swapped
/// out for a [MemoryFileSystem] so that repeated runs of this script yield
/// the same results.
void main() async {
  late final MemoryFileSystem fs;
  late final Analytics analytics;
  late final Directory home;
  // We need to initialize with a fake clock since the surveys have
  // a period of time they are valid for
  await withClock(Clock.fixed(DateTime(2023, 3, 3, 12, 0)), () async {
    // Use a memory file system to repeatedly run this example
    // file with the test instance
    fs = MemoryFileSystem(style: FileSystemStyle.posix);
    home = fs.directory('home');
    home.createSync();

    // The purpose of `initialAnalytics` is so that the tool is able to
    // send events after its first run; this instance won't be used below
    //
    // ignore: invalid_use_of_visible_for_testing_member
    final initialAnalytics = Analytics.fake(
      tool: DashTool.flutterTool,
      homeDirectory: home,
      dartVersion: 'dartVersion',
      fs: fs,
      platform: DevicePlatform.macos,
    );
    // The below command allows `DashTool.flutterTool` to send telemetry
    initialAnalytics.clientShowedMessage();

    // ignore: invalid_use_of_visible_for_testing_member
    analytics = Analytics.fake(
        tool: DashTool.flutterTool,
        homeDirectory: home,
        dartVersion: 'dartVersion',
        fs: fs,
        platform: DevicePlatform.macos,
        surveyHandler: FakeSurveyHandler.fromList(
          dismissedSurveyFile: home
              .childDirectory(kDartToolDirectoryName)
              .childFile(kDismissedSurveyFileName),
          initializedSurveys: [
            Survey(
              uniqueId: 'uniqueId',
              startDate: DateTime(2023, 1, 1),
              endDate: DateTime(2023, 5, 31),
              description: 'description',
              snoozeForMinutes: 10,
              samplingRate: 1.0,
              excludeDashToolList: [],
              conditionList: [],
              buttonList: [
                SurveyButton(
                  buttonText: 'View Survey',
                  action: 'accept',
                  promptRemainsVisible: false,
                  url: 'http://example.com',
                ),
                SurveyButton(
                  buttonText: 'More Info',
                  action: 'snooze',
                  promptRemainsVisible: true,
                  url: 'http://example2.com',
                ),
                SurveyButton(
                  buttonText: 'Dismiss Survey',
                  action: 'dismiss',
                  promptRemainsVisible: false,
                )
              ],
            ),
          ],
        ));
  });

  // Each client of this package will be able to fetch all of
  // the available surveys with the below method
  //
  // Sample rate will be applied automatically; it also won't
  // fetch any surveys in the snooze period or if they have
  // been dismissed
  final surveyList = await analytics.fetchAvailableSurveys();
  assert(surveyList.length == 1);

  // Grab the first and only survey to simulate displaying it to a user
  final survey = surveyList.first;
  print('Simulating displaying the survey with a print below:');
  print('Survey id: ${survey.uniqueId}\n');

  // Immediately after displaying the survey, the method below
  // should be run so that no other clients using this tool will show
  // it at the same time
  //
  // It will "snoozed" when the below is run as well as reported to
  // Google Analytics 4 that this survey was shown
  analytics.surveyShown(survey);

  // Get the file where this is persisted to show it getting updated
  final persistedSurveyFile = home
      .childDirectory(kDartToolDirectoryName)
      .childFile(kDismissedSurveyFileName);
  print('The contents of the json file '
      'after invoking `analytics.surveyShown(survey);`');
  print('${persistedSurveyFile.readAsStringSync()}\n');

  // Change the index below to decide which button to simulate pressing
  //
  // 0 - accept
  // 1 - snooze
  // 2 - dismiss
  final selectedButtonIndex = 1;
  assert([0, 1, 2].contains(selectedButtonIndex));

  // Get the survey button by index that will need to be passed along with
  // the survey to simulate an interaction with the survey
  final selectedSurveyButton = survey.buttonList[selectedButtonIndex];
  print('The simulated button pressed was: '
      '"${selectedSurveyButton.buttonText}" '
      '(action = ${selectedSurveyButton.action})\n');

  // The below method will handle whatever action the button
  analytics.surveyInteracted(
    survey: survey,
    surveyButton: selectedSurveyButton,
  );

  // Conditional to check if there is a URl to route to
  if (selectedSurveyButton.url != null) {
    print('***This button also has a survey URL link '
        'to route to at "${selectedSurveyButton.url}"***\n');
  }

  // Conditional to check what simulating a popup to stay up
  if (selectedSurveyButton.promptRemainsVisible) {
    print('***This button has its promptRemainsVisible field set to `true` '
        'so this simulates what seeing a pop up again would look like***\n');
  }

  print('The contents of the json file '
      'after invoking '
      '`analytics.surveyInteracted(survey: survey, '
      'surveyButton: selectedSurveyButton);`');
  print('${persistedSurveyFile.readAsStringSync()}\n');

  // Demonstrating that the survey doesn't get returned again
  print('Attempting to fetch surveys again will result in an empty list');
  print(await analytics.fetchAvailableSurveys());
}
