import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flyinsono/lab/pages/lab_empty/index.dart';
import 'package:flyinsono/lab/pages/lab_setting/lab_setting.dart';
import 'package:flyinsono/lab/router/lab_route_names.dart';
import 'package:flyinsono/lab/router/lab_router.dart';
import 'package:fis_common/event/event_type.dart';
import 'package:flyinsono/lab/pages/lab_data/view.dart';
import 'package:flyinsono/lab/pages/lab_image/view.dart';
import 'package:flyinsono/lab/pages/lab_project/view.dart';
import 'package:flyinsono/architecture/utils/prompt_box.dart';

class PageManager {
  PageManager._();

  static PageManager? _instance;

  static PageManager get ins {
    if (_instance == null) {
      throw UnimplementedError("Must call PageManager.init() before.");
    }
    return _instance!;
  }

  static PageManager init() {
    if (_instance == null) {
      _instance = PageManager._();
    }
    return _instance!;
  }

  int activeTabHash = 0;

  // 页面映射 tabHash: pageWidget ，这是存在内存中的页面集合，不是实际可访问的页面集合，0 为 404 页面
  Map<int, Widget> tabViews = {};

  // 可公开访问的页面集合
  List<TabTitle> tabTitles = [];

  // 此处防止切换 Tab 时，跳入 -1，若找不到则默认为 0，0 为 404 页面
  int get activeTabIndex =>
      max(tabViews.keys.toList().indexOf(activeTabHash), 0);

  List<int> fixedTabs = []; // 前三个 Tab 不允许关闭

  // Tab 栏最大标签数限制
  final int maxTabCount = 20;

  // 最后访问的 Tab 页面的 hash
  int lastTabHash = 0;

  final tabChangeEvent = FEventHandler<TabChangeRequest>();

  final updateLeftRightMoreIconEvent = FEventHandler<bool>();

  // 状态重置
  void reset() {
    tabViews.clear();
    tabTitles.clear();
    fixedTabs.clear();
    activeTabHash = 0;
    lastTabHash = 0;
  }

  // 初始化默认标签页（项目、数据、图像）
  void initDefaultTabs() {
    tabViews.clear();
    final settingPage = LabSetting();
    tabViews[settingPage.hashCode] = settingPage;
    final emptyPage = LabEmptyPage();
    tabViews[emptyPage.hashCode] = emptyPage;
    final projectPage = LabProjectPage();
    tabViews[projectPage.hashCode] = projectPage;
    final dataPage = LabDataPage();
    tabViews[dataPage.hashCode] = dataPage;
    final imagePage = LabImagePage();
    tabViews[imagePage.hashCode] = imagePage;
    tabTitles = [
      TabTitle("", LabRouteNames.Setting, settingPage.hashCode),
      TabTitle("项目", LabRouteNames.Project, projectPage.hashCode),
      TabTitle("数据", LabRouteNames.Data, dataPage.hashCode),
      TabTitle("图像", LabRouteNames.Image, imagePage.hashCode),
    ];
    fixedTabs = [projectPage.hashCode, dataPage.hashCode, imagePage.hashCode];
    activeTabHash = projectPage.hashCode;
  }

  /// 查询是否为固定标签页
  bool isFixedTab(int tabHash) {
    return fixedTabs.contains(tabHash);
  }

  // 切换 tab
  void changeTabByHash(int tabHash, {dynamic args}) {
    if (tabHash == activeTabHash) {
      return;
    }
    lastTabHash = activeTabHash;
    activeTabHash = tabHash;
    tabChangeEvent.emit(this, TabChangeRequest(tabHash, args));
  }

  void openTab(String routeName, {dynamic args}) {
    for (var i = 0; i < tabTitles.length; i++) {
      if (tabTitles[i].routeName == routeName) {
        changeTabByHash(tabTitles[i].tabHash, args: args);
        return;
      }
    }
    print("未找到指定的 Tab 页面");
  }

  // 打开新标签页，立即跳转
  void openNewTab(String routeName, String title,
      {bool redirect = true, bool multiple = true, dynamic args}) {
    if (maxTabCount <= tabTitles.length) {
      PromptBox.toast('标签页数量已达上限');
      return;
    }
    if (!multiple) {
      // 如果不允许多个相同标签页，则查找是否已经存在
      for (var i = 0; i < tabTitles.length; i++) {
        if (tabTitles[i].routeName == routeName) {
          changeTabByHash(tabTitles[i].tabHash, args: args);
          return;
        }
      }
    }

    final Widget newPage = LabRouter.createSubPageByRouteName(
      routeName,
      initArguments: args,
    );
    final int newPageHash = newPage.hashCode;
    tabViews[newPageHash] = newPage;
    tabTitles = [
      ...tabTitles,
      TabTitle(title, routeName, newPageHash),
    ];
    if (redirect) {
      lastTabHash = activeTabHash;
      activeTabHash = newPageHash;
    }
    tabChangeEvent.emit(this, TabChangeRequest(activeTabHash, args));
    updateLeftRightMoreIconEvent.emit(this, true);
  }

  /// 关闭标签页
  void closeTab(int tabHash) {
    int indexOfTab = getIndexOfTabInTabTitles(tabHash);
    tabTitles = tabTitles..removeAt(indexOfTab);
    tabViews.remove(tabHash);
    if (activeTabHash == tabHash) {
      if (lastTabHash > -1 && tabViews.containsKey(lastTabHash)) {
        activeTabHash = lastTabHash;
      } else {
        activeTabHash = tabViews.keys.toList().last;
      }
      lastTabHash = -1;
    }
    tabChangeEvent.emit(this, TabChangeRequest(activeTabHash, null));
    updateLeftRightMoreIconEvent.emit(this, false);
  }

  int getIndexOfTabInTabTitles(int tabHash) {
    return tabTitles.indexWhere((element) => element.tabHash == tabHash);
  }

  // TODO 如果关闭 Tab 最好指定优先返回至哪个 Tab
}

class TabChangeRequest {
  final int tabHash;
  final dynamic arguments;

  TabChangeRequest(this.tabHash, this.arguments);
}

class TabTitle {
  final String title;
  final String routeName;
  final int tabHash;

  TabTitle(this.title, this.routeName, this.tabHash);
}
