import 'package:device_info_plus/device_info_plus.dart';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:package_info_plus/package_info_plus.dart';

import '../../../common/config/shorebird_service.dart';
import '../../../common/network/auth_interceptor.dart';
import '../../../common/network/dio_provider.dart';
import '../../../common/router/app_router.dart';
import '../../../common/services/device_header_service.dart';
import '../../../common/storage/storage_keys.dart';
import '../../../common/storage/storage_service.dart';
import '../../../common/theme/theme_controller.dart';

class DebugInfoPage extends ConsumerWidget {
  const DebugInfoPage({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final appConfig = ref.watch(appConfigProvider);
    final dio = ref.watch(dioProvider);
    final themeMode = ref.watch(themeModeControllerProvider);

    return Scaffold(
      appBar: AppBar(
        leading: IconButton(
          onPressed: () {
            if (context.canPop()) {
              context.pop();
            } else {
              context.go(AppRoutes.debug);
            }
          },
          icon: const Icon(Icons.arrow_back_ios_new),
        ),
        title: const Text('Info'),
      ),
      body: FutureBuilder<_DebugInfoSnapshot>(
        future: _loadSnapshot(
          apiBaseUrl: appConfig.apiBaseUrl,
          themeMode: themeMode.name,
          dio: dio,
        ),
        builder: (context, snapshot) {
          final text = snapshot.data?.text ?? 'loading...';
          return Padding(
            padding: const EdgeInsets.all(16),
            child: SelectableText(text, style: const TextStyle(fontSize: 12)),
          );
        },
      ),
    );
  }
}

Future<_DebugInfoSnapshot> _loadSnapshot({
  required String apiBaseUrl,
  required String themeMode,
  required Dio dio,
}) async {
  await DeviceHeaderService.to.ensureInitialized();
  final packageInfo = await PackageInfo.fromPlatform();
  final deviceInfo = await _readDeviceInfo();
  final storage = StorageService.to;
  final jwt = await loadJwt();
  final commonHeaders = DeviceHeaderService.to.commonHeaders();
  final platformHeaders = DeviceHeaderService.to.platformIdentityHeaders();
  final headers = <String, dynamic>{
    ...commonHeaders,
    ...platformHeaders,
    ...dio.options.headers,
  };
  final gitVersion = const String.fromEnvironment(
    'GITVERSION',
    defaultValue: 'unknown',
  );
  final patch = ShorebirdService.instance.currentPatch;
  final jwtLine = jwt?.isNotEmpty == true ? 'Bearer <redacted>' : '';

  final text = StringBuffer()
    ..writeln('[build]')
    ..writeln('app_name: ${packageInfo.appName}')
    ..writeln('mode: ${kReleaseMode ? 'release' : 'debug'}')
    ..writeln('package_name: ${packageInfo.packageName}')
    ..writeln('version: ${packageInfo.version}')
    ..writeln('build_number: ${packageInfo.buildNumber}')
    ..writeln('theme_mode: $themeMode')
    ..writeln('platform: ${defaultTargetPlatform.name}')
    ..writeln('is_web: $kIsWeb')
    ..writeln()
    ..writeln('[environment]')
    ..writeln('api_base: $apiBaseUrl')
    ..writeln(
      'connect_timeout_ms: ${dio.options.connectTimeout?.inMilliseconds}',
    )
    ..writeln(
      'receive_timeout_ms: ${dio.options.receiveTimeout?.inMilliseconds}',
    )
    ..writeln('response_type: ${dio.options.responseType.name}')
    ..writeln('git_version: $gitVersion')
    ..writeln()
    ..writeln('[storage]')
    ..writeln('privacy_agreed: ${storage.getBool(storagePrivacyAgreed)}')
    ..writeln('ios_startup_seen: ${storage.getBool(storageIosStartupSeen)}')
    ..writeln('device_id: ${DeviceHeaderService.to.deviceId}')
    ..writeln('android_id: ${storage.getString(storageAndroidId) ?? ''}')
    ..writeln('device_token: ${storage.getString(storageDeviceToken) ?? ''}')
    ..writeln('android_oaid: ${storage.getString(storageAndroidOaid) ?? ''}')
    ..writeln('android_imei: ${storage.getString(storageAndroidImei) ?? ''}')
    ..writeln('android_mac: ${storage.getString(storageAndroidMac) ?? ''}')
    ..writeln('ios_idfa: ${storage.getString(storageIosIdfa) ?? ''}')
    ..writeln('ios_paid: ${storage.getString(storageIosPaid) ?? ''}')
    ..writeln()
    ..writeln('[auth]')
    ..writeln('jwt: $jwtLine')
    ..writeln()
    ..writeln('[headers]')
    ..writeln('common: $commonHeaders')
    ..writeln('platform: $platformHeaders')
    ..writeln('dio: $headers')
    ..writeln()
    ..writeln('[shorebird]')
    ..writeln('current_patch: ${patch?.number ?? 'none'}')
    ..writeln('patch: ${patch ?? 'none'}')
    ..writeln()
    ..writeln('[device]')
    ..writeln(deviceInfo);

  return _DebugInfoSnapshot(text.toString());
}

Future<String> _readDeviceInfo() async {
  try {
    if (!kIsWeb &&
        defaultTargetPlatform == TargetPlatform.android &&
        !StorageService.to.getBool(storagePrivacyAgreed)) {
      return 'privacy policy not accepted; device info not read';
    }
    final plugin = DeviceInfoPlugin();
    if (kIsWeb) {
      final info = await plugin.webBrowserInfo;
      return info.data.toString();
    }

    switch (defaultTargetPlatform) {
      case TargetPlatform.android:
        final info = await plugin.androidInfo;
        return info.data.toString();
      case TargetPlatform.iOS:
        final info = await plugin.iosInfo;
        return info.data.toString();
      case TargetPlatform.macOS:
        final info = await plugin.macOsInfo;
        return info.data.toString();
      case TargetPlatform.windows:
        final info = await plugin.windowsInfo;
        return info.data.toString();
      case TargetPlatform.linux:
        final info = await plugin.linuxInfo;
        return info.data.toString();
      case TargetPlatform.fuchsia:
        return 'fuchsia';
    }
  } catch (error) {
    return 'unavailable: $error';
  }
}

class _DebugInfoSnapshot {
  const _DebugInfoSnapshot(this.text);

  final String text;
}
