import 'dart:async';
import 'dart:io';

import 'package:app_tracking_transparency/app_tracking_transparency.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
import 'package:lottie/lottie.dart';
import 'package:provider/provider.dart';
import 'package:puzzleweave/ads/applovin_ads_controller.dart';
import 'package:puzzleweave/audio/jc_audio_controller.dart';
import 'package:puzzleweave/config/device.dart';
import 'package:puzzleweave/firebase/adjust_helper.dart';
import 'package:puzzleweave/gallery/grid_item.dart';
import 'package:puzzleweave/models/cached_request.dart';
import 'package:puzzleweave/models/data.dart';
import 'package:puzzleweave/models/items.dart';
import 'package:puzzleweave/persistence/persistence.dart';

final Logger _log = Logger('gallery_screen');

class GalleryScreen extends StatefulWidget {
  const GalleryScreen({super.key});

  @override
  State<StatefulWidget> createState() => _GalleryScreen();
}

const int minimumRemoteLoadCount = 30; // 假设加载到 30 张图才算网络畅通

class _GalleryScreen extends State<GalleryScreen> {
  late Device device;
  late JcAudioController audio;
  late Data data;
  List<ListItem>? latest;
  late CachedRequest latestCachedRequest;
  late StreamSubscription? latestSubscription;

  @override
  void initState() {
    super.initState();

    device = context.read<Device>();
    audio = context.read<JcAudioController>();
    data = context.read<Data>();
    latestCachedRequest = data.latest;
    // 主动获取缓存数据（关键）
    final cachedData = latestCachedRequest.cachedData;
    if (cachedData != null) {
      _onLatestDataUpdate(cachedData);
    }
    latestSubscription = latestCachedRequest.stream.listen(_onLatestDataUpdate, onError: _onLatestDataError);

    audio.startMusic();
  }

  _onLatestDataUpdate(datalist) {
    _log.info('_onLatestDataUpdate.... ');
    if (datalist != null) {
      latest = datalist as List<ListItem>;

      setState(() {});

      final bool hasSufficientData = datalist.length >= minimumRemoteLoadCount;
      if (hasSufficientData) {
        // 如果数据完整，无论是否是缓存数据，都尝试初始化第三方服务（因为主页已经可以显示了）
        if (!hasInit) {
          initThird();
        }
      }
    }
  }

  _onLatestDataError(error) {
    _log.info('_onLatestDataError.... $error');
    if (latest == null || latest!.isEmpty || latest!.length < minimumRemoteLoadCount) {
      _log.warning("_onLatestDataError, retry again");
      // refresh();
      Future.delayed(Duration(seconds: 3), () => refresh());
    }
  }

  Future<void> refresh() async {
    _log.info('refresh...');
    await latestCachedRequest.refresh();
  }

  @override
  Widget build(BuildContext context) {
    final device = context.read<Device>();
    final isTablet = device.isTablet;

    return Scaffold(
      body: latest == null
          ? scrollableDummy
          : RefreshIndicator(
              onRefresh: refresh,
              child: CustomScrollView(
                slivers: <Widget>[
                  SliverPadding(
                    sliver: SliverGrid(
                      gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(maxCrossAxisExtent: isTablet ? 300 : 210, childAspectRatio: 2 / 3),
                      delegate: SliverChildBuilderDelegate((BuildContext context, int index) {
                        return _buildItem(context, index);
                      }, childCount: latest!.length),
                    ),
                    padding: const EdgeInsets.only(left: 10.0, right: 10.0),
                  ),
                ],
              ),
            ),
    );
  }

  Widget get scrollableDummy => LayoutBuilder(
    builder: (p0, p1) {
      return SingleChildScrollView(
        physics: const AlwaysScrollableScrollPhysics(),
        child: SizedBox(
          height: p1.maxHeight,
          child: Center(
            child: ListView(
              shrinkWrap: true,
              children: [
                Lottie.asset('assets/lottie/loading.json', height: 100),
                const Center(child: Text("loading...")),
              ],
            ),
          ),
        ),
      );
    },
  );

  Widget _buildItem(context, index) {
    ListItem item = latest![index];
    return Padding(
      padding: const EdgeInsets.all(10.0),
      child: GridItem(item: item, lock: false, index: index),
    );
  }

  ///////////////////////// 初始化相关 /////////////////////////

  static bool hasInit = false;

  // 在列表刷出来后才正式初始化admod等组件
  void initThird() async {
    if (hasInit) return;

    hasInit = true;

    // 有了UMP后， 这里的ATT就不需要了
    // bool auth = await initATT();
    // if (auth) {
    //   await platform.setHasUserConsent(true);
    //   await platform.setAdvertiserTrackingEnabled(true);
    // }
    // await initUMP(); // 征询欧洲用户同意 // applovin max 已经可以自动处理，这里不需要了
    TrackingStatus attStatus = await AppTrackingTransparency.trackingAuthorizationStatus;
    if (attStatus == TrackingStatus.authorized && Platform.isIOS) {
      // ATT 通过之后，ios需要调用相关的原生sdk接口做进一步的初始化
      // await platform.setHasUserConsent(true);
      // await platform.setAdvertiserTrackingEnabled(true);
    }
    initFCM(); // 消息推送许可弹窗
    initAd(); // admod 的广告加载安排在iOS ATT 之后，以便能够加载到个性化广告
    AdjustHelper.init(Persistence().uuid); // 初始化Adjust

    final idfa = await AppTrackingTransparency.getAdvertisingIdentifier();
    _log.info("idfa: $idfa");
  }

  /////////////////////////// ATT ///////////////////////////
  // Platform messages are asynchronous, so we initialize in an async method.
  Future<bool> initATT() async {
    TrackingStatus status = await AppTrackingTransparency.trackingAuthorizationStatus;
    _log.info('initATT111 $status');
    // If the system can show an authorization request dialog
    if (status == TrackingStatus.notDetermined) {
      // Show a custom explainer dialog before the system dialog
      // await showCustomTrackingDialog(context);
      // Wait for dialog popping animation
      // await Future.delayed(const Duration(milliseconds: 200));
      // Request system's tracking authorization dialog
      status = await AppTrackingTransparency.requestTrackingAuthorization();
      _log.info('initATT222 $status');
    }
    if (status == TrackingStatus.authorized) {
      return true;
    }
    return false;
  }

  // no need
  Future<void> showCustomTrackingDialog(BuildContext context) async => await showDialog<void>(
    context: context,
    builder: (context) => AlertDialog(
      title: const Text('Dear User'),
      content: const Text(
        'We care about your privacy and data security. We keep this app free by showing ads. '
        'Can we continue to use your data to tailor ads for you?\n\nYou can change your choice anytime in the app settings. '
        'Our partners will collect data and use a unique identifier on your device to show you ads.',
      ),
      actions: [TextButton(onPressed: () => Navigator.pop(context), child: const Text('Continue'))],
    ),
  );
  /////////////////////////////////////////////////////////
  ///
  /// 初始化广告模块
  initAd() {
    _log.info('initAd');
    ApplovinAdsController applovinAdsController = context.read<ApplovinAdsController>();
    applovinAdsController.initialize();
  }

  /////////////////////////// FCM ///////////////////////////
  // 消息推送许可弹框
  initFCM() async {
    try {
      final fcmToken = await FirebaseMessaging.instance.getToken();
      _log.info("FCM Token: $fcmToken");

      FirebaseMessaging messaging = FirebaseMessaging.instance;
      NotificationSettings settings = await messaging.requestPermission(
        alert: true,
        announcement: false,
        badge: true,
        carPlay: false,
        criticalAlert: false,
        provisional: false,
        sound: true,
      );

      _log.warning('User granted permission: ${settings.authorizationStatus}');
    } catch (e) {
      FirebaseCrashlytics.instance.log("FCM FirebaseMessaging.instance.getToken error: $e");
      _log.warning(e);
    }
  }
}
