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

import 'package:battery_plus/battery_plus.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:easy_refresh/easy_refresh.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_dmzj/app/app_constant.dart';
import 'package:flutter_dmzj/app/app_error.dart';
import 'package:flutter_dmzj/app/app_style.dart';
import 'package:flutter_dmzj/app/utils.dart';
import 'package:flutter_dmzj/services/app_settings_service.dart';
import 'package:flutter_dmzj/app/controller/base_controller.dart';
import 'package:flutter_dmzj/app/log.dart';
import 'package:flutter_dmzj/models/comic/chapter_info.dart';
import 'package:flutter_dmzj/models/comic/detail_info.dart';
import 'package:flutter_dmzj/models/comic/view_point_model.dart';
import 'package:flutter_dmzj/requests/comic_request.dart';
import 'package:flutter_dmzj/services/db_service.dart';
import 'package:flutter_dmzj/services/user_service.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
import 'package:preload_page_view/preload_page_view.dart';
import 'package:remixicon/remixicon.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';

class ComicReaderController extends BaseController {
  /// 是否为条漫
  final bool isLongComic;
  final int comicId;
  final String comicTitle;
  final String comicCover;
  final ComicDetailChapterItem chapter;
  final List<ComicDetailChapterItem> chapters;
  final FocusNode focusNode = FocusNode();
  final ComicRequest request = ComicRequest();
  ComicReaderController({
    required this.comicId,
    required this.comicTitle,
    required this.chapters,
    required this.chapter,
    required this.comicCover,
    required this.isLongComic,
  }) {
    chapterIndex.value = chapters.indexOf(chapter);
  }

  /// APP设置控制器
  final settings = AppSettingsService.instance;

  /// 预加载控制器
  final PreloadPageController preloadPageController = PreloadPageController();

  /// 上下模式控制器
  final ItemScrollController itemScrollController = ItemScrollController();

  /// 监听上下滚动
  final ItemPositionsListener itemPositionsListener =
      ItemPositionsListener.create();

  /// 章节详情
  Rx<ComicChapterDetail> detail =
      Rx<ComicChapterDetail>(ComicChapterDetail.empty());

  /// 连接信息监听
  StreamSubscription<ConnectivityResult>? connectivitySubscription;

  /// 电量信息监听
  StreamSubscription<BatteryState>? batterySubscription;

  /// 当处于放大图片时，锁定滑动手势
  var lockSwipe = false.obs;

  /// 当前章节索引
  var chapterIndex = 0.obs;

  /// 当前页面
  var currentIndex = 0.obs;

  /// 初始化
  var initialIndex = 0;

  /// 是否显示控制器
  var showControls = false.obs;

  /// 阅读方向
  var direction = 0.obs;

  /// 左手模式
  bool get leftHandMode => settings.comicReaderLeftHandMode.value;

  /// 翻页动画
  bool get pageAnimation => settings.comicReaderPageAnimation.value;

  /// 观点、吐槽
  RxList<ComicViewPointModel> viewPoints = RxList<ComicViewPointModel>();

  /// 连接类型
  Rx<ConnectivityResult> connectivityType =
      Rx<ConnectivityResult>(ConnectivityResult.other);

  /// 电量信息
  Rx<int> batteryLevel = 0.obs;

  /// 显示电量
  RxBool showBattery = true.obs;

  @override
  void onInit() {
    initConnectivity();
    initBattery();
    if (isLongComic) {
      direction.value = ReaderDirection.kUpToDown;
    } else {
      direction.value = settings.comicReaderDirection.value;
    }

    if (settings.comicReaderFullScreen.value) {
      setFull();
    }

    itemPositionsListener.itemPositions.addListener(updateItemPosition);
    loadDetail();
    super.onInit();
  }

  /// 初始化电池信息
  void initBattery() async {
    try {
      //没有电池的Mac似乎会闪退,暂时屏蔽Mac
      //https://github.com/xiaoyaocz/flutter_dmzj/discussions/146
      if (Platform.isMacOS) {
        showBattery.value = false;
        return;
      }
      var battery = Battery();
      batterySubscription =
          battery.onBatteryStateChanged.listen((BatteryState state) async {
        try {
          var level = await battery.batteryLevel;
          batteryLevel.value = level;
          showBattery.value = true;
        } catch (e) {
          showBattery.value = false;
        }
      });
      batteryLevel.value = await battery.batteryLevel;
      showBattery.value = true;
    } catch (e) {
      showBattery.value = false;
    }
  }

  /// 初始化连接状态
  void initConnectivity() async {
    var connectivity = Connectivity();
    connectivitySubscription =
        connectivity.onConnectivityChanged.listen((ConnectivityResult result) {
      //提醒
      if (connectivityType.value != result &&
          result == ConnectivityResult.mobile) {
        SmartDialog.showToast("您已切换至数据网络，请注意流量消耗");
      }
      connectivityType.value = result;
    });
    connectivityType.value = await connectivity.checkConnectivity();
  }

  @override
  void onClose() {
    focusNode.dispose();
    connectivitySubscription?.cancel();
    batterySubscription?.cancel();
    exitFull();
    itemPositionsListener.itemPositions.removeListener(updateItemPosition);
    uploadHistory();
    super.onClose();
  }

  void updateItemPosition() {
    var items = itemPositionsListener.itemPositions.value;
    if (items.isEmpty) {
      return;
    }

    var index = items
        .where((ItemPosition position) => position.itemTrailingEdge > 0)
        .reduce((ItemPosition min, ItemPosition position) =>
            position.itemTrailingEdge < min.itemTrailingEdge ? position : min)
        .index;

    currentIndex.value = index;
  }

  /// 加载信息
  void loadDetail() async {
    try {
      pageLoadding.value = true;
      pageError.value = false;

      detail.value = ComicChapterDetail.empty();
      var chapterId = chapters[chapterIndex.value].chapterId;
      if (chapters[chapterIndex.value].isVip) {
        //禁止观看VIP章节
        throw AppError("请使用动漫之家官方APP观看VIP章节");
      }
      //loadViewPoints();

      var result = await request.chapterDetail(
        comicId: comicId,
        chapterId: chapterId,
        useHD: AppSettingsService.instance.comicReaderHD.value,
      );
      var his = DBService.instance.getComicHistory(comicId);
      if (his != null && his.chapterId == chapterId && his.page != 0) {
        var hisIndex = (his.page - 1) < 0 ? 0 : his.page - 1;
        if (hisIndex >= result.pageUrls.length - 1) {
          hisIndex = 0;
        }
        initialIndex = hisIndex;
      } else {
        initialIndex = 0;
      }
      currentIndex.value = initialIndex;
      // if (settings.comicReaderShowViewPoint.value) {
      //   result.pageUrls.add("TC");
      // }

      detail.value = result;
      Future.delayed(const Duration(milliseconds: 100), () {
        jumpToPage(initialIndex);
      });
      //上传记录
      uploadHistory();
    } catch (e) {
      pageError.value = true;
      errorMsg.value = e.toString();
      setShowControls();
    } finally {
      pageLoadding.value = false;
    }
  }

  /// 加载吐槽、观点
  void loadViewPoints() async {
    try {
      viewPoints.clear();
      var result = await request.viewPoints(
        comicId: comicId,
        chapterId: chapters[chapterIndex.value].chapterId,
      );
      result.sort((a, b) => b.num.value.compareTo(a.num.value));
      viewPoints.value = result;
    } catch (e) {
      //SmartDialog.showToast("读取吐槽失败");
      Log.logPrint(e.toString());
    }
  }

  /// 设置显示/隐藏控制按钮
  void setShowControls() {
    if (settings.comicReaderFullScreen.value) {
      if (showControls.value) {
        setFull();
      } else {
        setFullEdge();
      }
    }
    Future.delayed(const Duration(milliseconds: 100), () {
      showControls.value = !showControls.value;
    });
  }

  /// 显示目录
  void showMenu() async {
    setShowControls();
    showModalBottomSheet(
      context: Get.context!,
      shape: const RoundedRectangleBorder(
        borderRadius: BorderRadius.only(
          topLeft: Radius.circular(16),
          topRight: Radius.circular(16),
        ),
      ),
      constraints: const BoxConstraints(
        maxWidth: 500,
      ),
      builder: (context) => Column(
        children: [
          ListTile(
            title: Text("目录(${chapters.length})"),
            trailing: IconButton(
              onPressed: Get.back,
              icon: const Icon(Icons.close),
            ),
            contentPadding: AppStyle.edgeInsetsL12,
          ),
          Divider(
            height: 1.0,
            color: Theme.of(context).dividerColor.withOpacity(.2),
          ),
          Expanded(
            child: ScrollablePositionedList.separated(
              initialScrollIndex: chapterIndex.value,
              itemCount: chapters.length,
              separatorBuilder: (_, i) => Divider(
                indent: 12,
                endIndent: 12,
                height: 1.0,
                color: Theme.of(context).dividerColor.withOpacity(.2),
              ),
              itemBuilder: (_, i) {
                var item = chapters[i];
                return ListTile(
                  selected: i == chapterIndex.value,
                  selectedTileColor:
                      Theme.of(context).colorScheme.secondaryContainer,
                  selectedColor:
                      Theme.of(context).colorScheme.onSecondaryContainer,
                  title: Text(item.chapterTitle),
                  subtitle: item.updateTime != 0
                      ? Text(
                          "更新于${Utils.formatTimestampToDate(item.updateTime)}")
                      : null,
                  onTap: () {
                    chapterIndex.value = i;
                    loadDetail();
                    Get.back();
                  },
                );
              },
            ),
          ),
        ],
      ),
      routeSettings: const RouteSettings(name: "/modalBottomSheet"),
    );
  }

  /// 下一章
  void nextChapter() {
    if (chapterIndex.value == chapters.length - 1) {
      SmartDialog.showToast("后面没有了");
      return;
    }

    chapterIndex.value += 1;
    loadDetail();
  }

  /// 上一章
  void forwardChapter() {
    if (chapterIndex.value == 0) {
      SmartDialog.showToast("前面没有了");
      return;
    }

    chapterIndex.value -= 1;
    loadDetail();
  }

  /// 下一页
  void nextPage() {
    var value = currentIndex.value;
    Log.w("下一页$value");
    var max = detail.value.pageUrls.length;
    if (value >= max - 1) {
      nextChapter();
    } else {
      jumpToPage(value + 1, anime: true);
    }
  }

  /// 上一页
  void forwardPage() {
    var value = currentIndex.value;
    Log.w("上一页$value");
    if (value == 0) {
      forwardChapter();
    } else {
      jumpToPage(value - 1, anime: true);
    }
  }

  /// 跳转页数
  void jumpToPage(int page, {bool anime = false}) {
    //竖向
    if (direction.value == ReaderDirection.kUpToDown) {
      itemScrollController.jumpTo(index: page);
    } else {
      anime && pageAnimation
          ? preloadPageController.animateToPage(page,
              duration: const Duration(milliseconds: 200), curve: Curves.linear)
          : preloadPageController.jumpToPage(page);
    }
  }

  /// 查看吐槽
  void showComment() {
    setShowControls();
    TextEditingController tucaoController = TextEditingController();
    showModalBottomSheet(
      context: Get.context!,
      shape: const RoundedRectangleBorder(
        borderRadius: BorderRadius.only(
          topLeft: Radius.circular(16),
          topRight: Radius.circular(16),
        ),
      ),
      constraints: const BoxConstraints(
        maxWidth: 500,
      ),
      isScrollControlled: true,
      useSafeArea: true,
      builder: (context) => Column(
        children: [
          ListTile(
            title: Text("吐槽(${viewPoints.length})"),
            trailing: IconButton(
              onPressed: Get.back,
              icon: const Icon(Icons.close),
            ),
            contentPadding: AppStyle.edgeInsetsL12,
          ),
          Divider(
            height: 1.0,
            color: Theme.of(context).dividerColor.withOpacity(.2),
          ),
          Expanded(
            child: EasyRefresh(
              header: const MaterialHeader(),
              onRefresh: () async {
                loadViewPoints();
              },
              child: Obx(
                () => settings.comicReaderOldViewPoint.value
                    ? SingleChildScrollView(
                        child: Padding(
                          padding: AppStyle.edgeInsetsA12,
                          child: Wrap(
                            spacing: 8,
                            runSpacing: 8,
                            children: viewPoints.map<Widget>((item) {
                              return InkWell(
                                onTap: () {
                                  likeViewPoint(item);
                                },
                                child: Container(
                                  padding: const EdgeInsets.symmetric(
                                    horizontal: 12,
                                    vertical: 4,
                                  ),
                                  decoration: BoxDecoration(
                                    color:
                                        Theme.of(context).colorScheme.primary,
                                    borderRadius: AppStyle.radius8,
                                  ),
                                  child: Text(
                                    item.content,
                                    style: TextStyle(
                                        color: Theme.of(context)
                                            .colorScheme
                                            .onPrimary),
                                  ),
                                ),
                              );
                            }).toList(),
                          ),
                        ),
                      )
                    : ListView.separated(
                        padding: EdgeInsets.zero,
                        itemCount: viewPoints.length,
                        separatorBuilder: (_, i) => Divider(
                          indent: 12,
                          endIndent: 12,
                          height: 1.0,
                          color: Theme.of(context).dividerColor.withOpacity(.2),
                        ),
                        itemBuilder: (_, i) {
                          var item = viewPoints[i];
                          return Padding(
                            padding: AppStyle.edgeInsetsA12
                                .copyWith(top: 8, bottom: 8),
                            child: Row(
                              children: [
                                Expanded(
                                  child: Text(
                                    item.content,
                                    style: const TextStyle(
                                      fontSize: 15,
                                    ),
                                  ),
                                ),
                                AppStyle.hGap12,
                                TextButton.icon(
                                  style: TextButton.styleFrom(
                                    tapTargetSize:
                                        MaterialTapTargetSize.shrinkWrap,
                                  ),
                                  onPressed: () {
                                    likeViewPoint(item);
                                  },
                                  icon: const Icon(
                                    Remix.thumb_up_line,
                                    size: 16,
                                  ),
                                  label: Obx(() => Text("${item.num.value}")),
                                ),
                              ],
                            ),
                          );
                        },
                      ),
              ),
            ),
          ),
          Container(
            padding: AppStyle.edgeInsetsA8.copyWith(
              bottom: 8 + AppStyle.bottomBarHeight,
            ),
            child: TextField(
              controller: tucaoController,
              onSubmitted: (e) {
                sendViewPoint(e);
              },
              decoration: InputDecoration(
                hintText: "发表吐槽",
                contentPadding: AppStyle.edgeInsetsH12,
                border: const OutlineInputBorder(),
                suffixIcon: TextButton(
                  onPressed: () {
                    sendViewPoint(tucaoController.text);
                  },
                  child: const Text("发布"),
                ),
              ),
            ),
          ),
        ],
      ),
      routeSettings: const RouteSettings(name: "/modalBottomSheet"),
    );
  }

  /// 显示设置
  void showSettings() {
    setShowControls();

    showModalBottomSheet(
      context: Get.context!,
      shape: const RoundedRectangleBorder(
        borderRadius: BorderRadius.only(
          topLeft: Radius.circular(16),
          topRight: Radius.circular(16),
        ),
      ),
      constraints: const BoxConstraints(
        maxWidth: 500,
      ),
      builder: (context) => Column(
        children: [
          ListTile(
            title: const Text("设置"),
            trailing: IconButton(
              onPressed: Get.back,
              icon: const Icon(Icons.close),
            ),
            contentPadding: AppStyle.edgeInsetsL12,
          ),
          Expanded(
            child: Obx(
              () => ListView(
                padding: AppStyle.edgeInsetsA12,
                children: [
                  buildBGItem(
                    context,
                    child: SwitchListTile(
                      value: settings.comicReaderHD.value,
                      onChanged: (e) {
                        settings.setComicReaderHD(e);
                        loadDetail();
                      },
                      title: const Text("优先加载高清图"),
                      subtitle: const Text("部分单行本可能未分页"),
                    ),
                  ),
                  //AppStyle.vGap12,
                  Visibility(
                    //条漫不允许修改阅读方向
                    visible: !isLongComic,
                    child: Padding(
                      padding: AppStyle.edgeInsetsT12,
                      child: buildBGItem(
                        context,
                        child: ListTile(
                          title: const Text("阅读方向"),
                          trailing: Row(
                            mainAxisSize: MainAxisSize.min,
                            children: [
                              buildSelectedButton(
                                onTap: () {
                                  setDirection(ReaderDirection.kLeftToRight);
                                },
                                selected: settings.comicReaderDirection.value ==
                                    ReaderDirection.kLeftToRight,
                                child: const Icon(Remix.arrow_right_line),
                              ),
                              AppStyle.hGap8,
                              buildSelectedButton(
                                onTap: () {
                                  setDirection(ReaderDirection.kRightToLeft);
                                },
                                selected: settings.comicReaderDirection.value ==
                                    ReaderDirection.kRightToLeft,
                                child: const Icon(Remix.arrow_left_line),
                              ),
                              AppStyle.hGap8,
                              buildSelectedButton(
                                onTap: () {
                                  setDirection(ReaderDirection.kUpToDown);
                                },
                                selected: settings.comicReaderDirection.value ==
                                    ReaderDirection.kUpToDown,
                                child: const Icon(Remix.arrow_down_line),
                              )
                            ],
                          ),
                        ),
                      ),
                    ),
                  ),
                  AppStyle.vGap12,
                  buildBGItem(
                    context,
                    child: SwitchListTile(
                      value: settings.comicReaderLeftHandMode.value,
                      onChanged: (e) {
                        settings.setComicReaderLeftHandMode(e);
                      },
                      title: const Text("操作反转"),
                      subtitle: const Text("点击左侧下一页，右侧上一页"),
                    ),
                  ),
                  AppStyle.vGap12,
                  buildBGItem(
                    context,
                    child: SwitchListTile(
                      value: settings.comicReaderFullScreen.value,
                      onChanged: (e) {
                        settings.setComicReaderFullScreen(e);
                        if (e) {
                          setFull();
                        } else {
                          exitFull();
                        }
                      },
                      title: const Text("全屏阅读"),
                    ),
                  ),
                  AppStyle.vGap12,
                  buildBGItem(
                    context,
                    child: SwitchListTile(
                      value: settings.comicReaderShowStatus.value,
                      onChanged: (e) {
                        settings.setComicReaderShowStatus(e);
                      },
                      title: const Text("显示状态信息"),
                    ),
                  ),
                  AppStyle.vGap12,
                  buildBGItem(
                    context,
                    child: SwitchListTile(
                      value: settings.comicReaderPageAnimation.value,
                      onChanged: (e) {
                        settings.setComicReaderPageAnimation(e);
                      },
                      title: const Text("翻页动画"),
                    ),
                  ),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }

  Widget buildBGItem(BuildContext context, {required Widget child}) {
    return Container(
      decoration: BoxDecoration(
        borderRadius: AppStyle.radius8,
        color: Theme.of(context).colorScheme.surfaceContainerHighest,
      ),
      child: child,
    );
  }

  Widget buildSelectedButton(
      {required Widget child, bool selected = false, Function()? onTap}) {
    return Builder(builder: (context) {
      return OutlinedButton(
        style: OutlinedButton.styleFrom(
          foregroundColor:
              selected ? Theme.of(context).colorScheme.primary : Colors.grey,
          side: BorderSide(
            color:
                selected ? Theme.of(context).colorScheme.primary : Colors.grey,
          ),
        ),
        onPressed: onTap,
        child: child,
      );
    });
  }

  void setDirection(int value) {
    initialIndex = currentIndex.value;
    settings.setComicReaderDirection(value);
    direction.value = value;
    if (initialIndex != 0) {
      Future.delayed(const Duration(milliseconds: 200), () {
        jumpToPage(initialIndex);
      });
    }
  }

  void setShowViewPoint(bool value) {
    if (value) {
      if (!detail.value.pageUrls.contains("TC")) {
        detail.update((val) {
          val!.pageUrls.add("TC");
        });
      }
    } else {
      if (detail.value.pageUrls.contains("TC")) {
        detail.update((val) {
          val!.pageUrls.remove("TC");
        });
      }
    }
  }

  void uploadHistory() {
    var chapter = chapters[chapterIndex.value];
    UserService.instance.updateComicHistory(
      comicId: comicId,
      chapterId: chapter.chapterId,
      page: currentIndex.value + 1,
      comicName: comicTitle,
      comicCover: comicCover,
      chapterName: chapter.chapterTitle,
    );
  }

  /// 进入全屏
  void setFull() {
    SystemChrome.setEnabledSystemUIMode(
      SystemUiMode.manual,
      overlays: [],
    );
  }

  /// 进入全屏edgeToEdge模式
  void setFullEdge() {
    SystemChrome.setEnabledSystemUIMode(
      SystemUiMode.edgeToEdge,
      overlays: SystemUiOverlay.values,
    );
    SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
      statusBarColor: Colors.transparent,
      statusBarIconBrightness: Brightness.light,
      systemNavigationBarColor: Colors.transparent,
      systemNavigationBarIconBrightness: Brightness.light,
    ));
  }

  /// 退出全屏
  void exitFull() {
    SystemChrome.setEnabledSystemUIMode(
      SystemUiMode.edgeToEdge,
      overlays: SystemUiOverlay.values,
    );
  }

  void likeViewPoint(ComicViewPointModel item) async {
    try {
      await request.likeViewPoint(comicId: comicId, id: item.id);

      item.num.value += 1;
    } catch (e) {
      SmartDialog.showToast(e.toString());
    }
  }

  void sendViewPoint(String content) async {
    if (!await UserService.instance.login()) {
      SmartDialog.showToast("请先登录");
      return;
    }
    if (content.isEmpty) {
      SmartDialog.showToast("内容不能为空");
      return;
    }
    Get.back();
    try {
      SmartDialog.showLoading();
      await request.sendViewPoint(
        comicId: comicId,
        chapterId: chapters[chapterIndex.value].chapterId,
        content: content,
        page: currentIndex.value + 1,
      );
      loadViewPoints();
    } catch (e) {
      SmartDialog.showToast(e.toString());
    } finally {
      SmartDialog.dismiss(status: SmartStatus.loading);
    }
  }

  void keyDown(LogicalKeyboardKey key) {
    if (key == LogicalKeyboardKey.arrowLeft ||
        key == LogicalKeyboardKey.pageUp) {
      if (leftHandMode) {
        nextPage();
      } else {
        forwardPage();
      }
    } else if (key == LogicalKeyboardKey.arrowRight ||
        key == LogicalKeyboardKey.pageDown) {
      if (leftHandMode) {
        forwardPage();
      } else {
        nextPage();
      }
    }
  }
}
