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

import 'package:battery_plus/battery_plus.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_dmzj/app/app_color.dart';
import 'package:flutter_dmzj/app/app_constant.dart';
import 'package:flutter_dmzj/app/app_style.dart';
import 'package:flutter_dmzj/models/db/download_status.dart';
import 'package:flutter_dmzj/models/db/novel_download_info.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/novel/novel_detail_model.dart';
import 'package:flutter_dmzj/requests/novel_request.dart';
import 'package:flutter_dmzj/services/novel_download_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:html_unescape/html_unescape.dart';
import 'package:remixicon/remixicon.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';

// ignore: depend_on_referenced_packages
import 'package:path/path.dart' as p;

class NovelReaderController extends BaseController {
  final int novelId;
  final String novelTitle;
  final String novelCover;
  final List<NovelDetailChapter> chapters;
  final FocusNode focusNode = FocusNode();
  NovelDetailChapter chapter;
  NovelReaderController({
    required this.novelId,
    required this.novelTitle,
    required this.novelCover,
    required this.chapters,
    required this.chapter,
  }) {
    chapterIndex.value = chapters.indexOf(chapter);
  }

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

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

  /// 最大页面
  var maxPage = 0.obs;

  /// 阅读进度，百分比
  var progress = 0.0.obs;

  final AppSettingsService settings = AppSettingsService.instance;
  final NovelRequest request = NovelRequest();

  final PageController pageController = PageController();
  final ScrollController scrollController = ScrollController();

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

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

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

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

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

  /// 文本内容
  var content = "".obs;

  /// 是否是图片
  var isPicture = false.obs;

  /// 是否为本地缓存
  var isLocal = false;

  /// 图片列表
  RxList<String> pictures = RxList<String>();

  var contentLength = 0;

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

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

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

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

  @override
  void onInit() {
    initConnectivity();
    initBattery();
    direction.value = settings.novelReaderDirection.value;

    scrollController.addListener(listenVertical);
    setFull();

    loadContent();
    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();
  }

  /// 监听竖向模式时滚动百分比
  void listenVertical() {
    if (scrollController.position.maxScrollExtent > 0) {
      progress.value = scrollController.position.pixels /
          scrollController.position.maxScrollExtent;
    }
  }

  @override
  void onClose() {
    scrollController.removeListener(listenVertical);
    connectivitySubscription?.cancel();
    batterySubscription?.cancel();
    exitFull();
    uploadHistory();
    super.onClose();
  }

  /// 加载内容
  Future loadContent() async {
    try {
      pageLoadding.value = true;
      pageError.value = false;
      content.value = "";
      currentIndex.value = 0;
      isLocal = false;
      chapter = chapters[chapterIndex.value];

      //查询本地是否存在
      var localInfo = NovelDownloadService.instance.box
          .get("${novelId}_${chapter.volumeId}_${chapter.chapterId}");
      if (localInfo != null && localInfo.status == DownloadStatus.complete) {
        return await loadFromLocal(localInfo);
      }

      var text = await request.novelContent(
        volumeId: chapter.volumeId,
        chapterId: chapter.chapterId,
      );

      contentLength = text.length;

      var subStr = text.substring(0, text.length < 200 ? text.length : 200);
      //检查是否是插画
      if (subStr.contains(RegExp('<img.*?>'))) {
        List<String> imgs = [];
        for (var item
            in RegExp(r'<img.*?src=[' '""](.*?)[' '""].*?>').allMatches(text)) {
          var src = item.group(1);
          if (src != null && src.isNotEmpty) {
            imgs.add(src);
          }
        }
        isPicture.value = true;

        pictures.value = imgs;

        content.value = text;
        maxPage.value = pictures.length;

        SmartDialog.showToast("双击插画可放大、保存哦~");
      } else {
        isPicture.value = false;

        text = HtmlUnescape().convert(text);
        text = text
            .replaceAll('\r\n', '\n')
            .replaceAll("<br/>", "\n")
            .replaceAll('<br />', "\n")
            .replaceAll('\n\n\n', "\n")
            .replaceAll('\n\n', "\n")
            .replaceAll('\n', "\n　　")
            .replaceAll(RegExp(r"　　\s+"), "　　");

        content.value = text;
      }
      if (scrollController.hasClients) {
        scrollController.jumpTo(0);
        progress.value = 0.0;
      }
      preloadContent();
      //TODO 阅读记录跳转
      //上传记录
      uploadHistory();
    } catch (e) {
      pageError.value = true;
      errorMsg.value = e.toString();
    } finally {
      pageLoadding.value = false;
    }

    //SmartDialog.dismiss(status: SmartStatus.loading);
  }

  Future loadFromLocal(NovelDownloadInfo local) async {
    try {
      isLocal = true;
      var file = File(p.join(NovelDownloadService.instance.savePath,
          local.taskId, local.fileName));

      var text = await file.readAsString();

      //检查是否是插画
      if (local.isImage) {
        List<String> imgs = local.imageFiles
            .map((e) =>
                p.join(NovelDownloadService.instance.savePath, local.taskId, e))
            .toList();

        isPicture.value = true;

        pictures.value = imgs;

        content.value = text;
        maxPage.value = pictures.length;

        SmartDialog.showToast("双击插画可放大、保存哦~");
      } else {
        isPicture.value = false;

        text = HtmlUnescape().convert(text);
        text = text
            .replaceAll('\r\n', '\n')
            .replaceAll("<br/>", "\n")
            .replaceAll('<br />', "\n")
            .replaceAll('\n\n\n', "\n")
            .replaceAll('\n\n', "\n")
            .replaceAll('\n', "\n　　")
            .replaceAll(RegExp(r"　　\s+"), "　　");

        content.value = text;
      }
      if (scrollController.hasClients) {
        scrollController.jumpTo(0);
        progress.value = 0.0;
      }
      preloadContent();
      //TODO 阅读记录跳转
      //上传记录
      uploadHistory();
    } catch (e) {
      pageError.value = true;
      errorMsg.value = e.toString();
    } finally {
      pageLoadding.value = false;
    }
  }

  /// 预加载下一话
  void preloadContent() async {
    try {
      if (chapterIndex.value == chapters.length - 1) {
        return;
      }
      var nextChapter = chapters[chapterIndex.value + 1];
      await request.novelContent(
        volumeId: nextChapter.volumeId,
        chapterId: nextChapter.chapterId,
      );
    } catch (e) {
      Log.logPrint(e);
    }
  }

  /// 上传历史记录
  void uploadHistory() {
    var chapter = chapters[chapterIndex.value];
    UserService.instance.updateNovelHistory(
      novelId: novelId,
      chapterId: chapter.chapterId,
      //TODO 已读位置计算
      index: 0,
      total: contentLength,
      novelCover: novelCover,
      novelName: novelTitle,
      chapterName: chapter.chapterName,
      volumeId: chapter.volumeId,
      volumeName: chapter.volumeName,
    );
  }

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

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

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

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

  /// 下一页
  void nextPage() {
    if (direction.value == ReaderDirection.kUpToDown) {
      return;
    }
    var value = currentIndex.value;
    var max = maxPage.value;
    if (value >= max - 1) {
      nextChapter();
    } else {
      jumpToPage(value + 1, anime: true);
    }
  }

  /// 上一页
  void forwardPage() {
    if (direction.value == ReaderDirection.kUpToDown) {
      return;
    }
    var value = currentIndex.value;

    if (value == 0) {
      forwardChapter();
    } else {
      jumpToPage(value - 1, anime: true);
    }
  }

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

  /// 显示设置
  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: ListTile(
                      title: const Text("阅读方向"),
                      trailing: Row(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          buildSelectedButton(
                            onTap: () {
                              setDirection(ReaderDirection.kLeftToRight);
                            },
                            selected: settings.novelReaderDirection.value ==
                                ReaderDirection.kLeftToRight,
                            child: const Icon(Remix.arrow_right_line),
                          ),
                          AppStyle.hGap8,
                          buildSelectedButton(
                            onTap: () {
                              setDirection(ReaderDirection.kRightToLeft);
                            },
                            selected: settings.novelReaderDirection.value ==
                                ReaderDirection.kRightToLeft,
                            child: const Icon(Remix.arrow_left_line),
                          ),
                          AppStyle.hGap8,
                          buildSelectedButton(
                            onTap: () {
                              setDirection(ReaderDirection.kUpToDown);
                            },
                            selected: settings.novelReaderDirection.value ==
                                ReaderDirection.kUpToDown,
                            child: const Icon(Remix.arrow_down_line),
                          )
                        ],
                      ),
                    ),
                  ),
                  AppStyle.vGap12,
                  buildBGItem(
                    context,
                    child: ListTile(
                      title: const Text("阅读主题"),
                      trailing: Row(
                        mainAxisSize: MainAxisSize.min,
                        children: AppColor.novelThemes.keys
                            .map(
                              (e) => GestureDetector(
                                onTap: () {
                                  settings.setNovelReaderTheme(e);
                                },
                                child: Container(
                                  margin: AppStyle.edgeInsetsL8,
                                  height: 36,
                                  width: 36,
                                  decoration: BoxDecoration(
                                    color: AppColor.novelThemes[e]!.first,
                                    borderRadius: AppStyle.radius24,
                                    border: Border.all(
                                      color: Colors.grey.withOpacity(.2),
                                    ),
                                  ),
                                  child: Visibility(
                                    visible: AppColor.novelThemes.keys
                                            .toList()
                                            .indexOf(e) ==
                                        settings.novelReaderTheme.value,
                                    child: Icon(
                                      Icons.check,
                                      color: AppColor.novelThemes[e]!.last,
                                    ),
                                  ),
                                ),
                              ),
                            )
                            .toList(),
                      ),
                    ),
                  ),
                  AppStyle.vGap12,
                  buildBGItem(
                    context,
                    child: SwitchListTile(
                      value: settings.novelReaderLeftHandMode.value,
                      onChanged: (e) {
                        settings.setNovelReaderLeftHandMode(e);
                      },
                      title: const Text("操作反转"),
                      subtitle: const Text("点击左侧下一页，右侧上一页"),
                    ),
                  ),
                  AppStyle.vGap12,
                  buildBGItem(
                    context,
                    child: SwitchListTile(
                      value: settings.novelReaderShowStatus.value,
                      onChanged: (e) {
                        settings.setNovelReaderShowStatus(e);
                      },
                      title: const Text("显示状态信息"),
                    ),
                  ),
                  AppStyle.vGap12,
                  buildBGItem(
                    context,
                    child: SwitchListTile(
                      value: settings.novelReaderPageAnimation.value,
                      onChanged: (e) {
                        settings.setNovelReaderPageAnimation(e);
                      },
                      title: const Text("翻页动画"),
                    ),
                  ),
                  AppStyle.vGap12,
                  buildBGItem(
                    context,
                    child: ListTile(
                      title: const Text("字体大小"),
                      trailing: Row(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          OutlinedButton(
                            onPressed: () {
                              settings.setNovelReaderFontSize(
                                settings.novelReaderFontSize.value + 1,
                              );
                            },
                            child: const Icon(
                              Icons.add,
                              // color: Colors.grey,
                            ),
                          ),
                          AppStyle.hGap12,
                          Text("${settings.novelReaderFontSize.value}"),
                          AppStyle.hGap12,
                          OutlinedButton(
                            onPressed: () {
                              settings.setNovelReaderFontSize(
                                settings.novelReaderFontSize.value - 1,
                              );
                            },
                            child: const Icon(
                              Icons.remove,
                              // color: Colors.grey,
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
                  AppStyle.vGap12,
                  buildBGItem(
                    context,
                    child: ListTile(
                      title: const Text("行距"),
                      trailing: Row(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          OutlinedButton(
                            onPressed: () {
                              settings.setNovelReaderLineSpacing(
                                settings.novelReaderLineSpacing.value + 0.1,
                              );
                            },
                            child: const Icon(
                              Icons.add,
                              // color: Colors.grey,
                            ),
                          ),
                          AppStyle.hGap12,
                          Text((settings.novelReaderLineSpacing.value)
                              .toStringAsFixed(1)),
                          AppStyle.hGap12,
                          OutlinedButton(
                            onPressed: () {
                              settings.setNovelReaderLineSpacing(
                                settings.novelReaderLineSpacing.value - 0.1,
                              );
                            },
                            child: const Icon(
                              Icons.remove,
                              // color: Colors.grey,
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }

  /// 设置阅读方向
  void setDirection(int value) {
    settings.setNovelReaderDirection(value);
    direction.value = value;
  }

  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 showMenu() {
    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.chapterName),
                  subtitle: Text(item.volumeName),
                  onTap: () {
                    chapterIndex.value = i;
                    loadContent();
                    Get.back();
                  },
                );
              },
            ),
          ),
        ],
      ),
      routeSettings: const RouteSettings(name: "/modalBottomSheet"),
    );
  }

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

  /// 进入全屏
  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 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();
      }
    }
  }
}
