import 'dart:io';

import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hbb/common.dart';
import 'package:flutter_hbb/desktop/widgets/tabbar_widget.dart';
import 'package:flutter_hbb/models/platform_model.dart';
import 'package:flutter_hbb/models/state_model.dart';
import 'package:get/get.dart';
import 'package:url_launcher/url_launcher_string.dart';
import 'package:window_manager/window_manager.dart';

class InstallPage extends StatefulWidget {
  const InstallPage({Key? key}) : super(key: key);

  @override
  State<InstallPage> createState() => _InstallPageState();
}

class _InstallPageState extends State<InstallPage> {
  final tabController = DesktopTabController(tabType: DesktopTabType.main);

  @override
  void initState() {
    super.initState();
    Get.put<DesktopTabController>(tabController);
    const lable = "install";
    tabController.add(TabInfo(
        key: lable,
        label: lable,
        closable: false,
        page: _InstallPageBody(
          key: const ValueKey(lable),
        )));
  }

  @override
  void dispose() {
    super.dispose();
    Get.delete<DesktopTabController>();
  }

  @override
  Widget build(BuildContext context) {
    return DragToResizeArea(
      resizeEdgeSize: stateGlobal.resizeEdgeSize.value,
      child: Container(
        child: Scaffold(
            backgroundColor: Theme.of(context).colorScheme.background,
            body: DesktopTab(controller: tabController)),
      ),
    );
  }
}

class _InstallPageBody extends StatefulWidget {
  const _InstallPageBody({Key? key}) : super(key: key);

  @override
  State<_InstallPageBody> createState() => _InstallPageBodyState();
}

class _InstallPageBodyState extends State<_InstallPageBody>
    with WindowListener {
  late final TextEditingController controller;
  final RxBool startmenu = true.obs;
  final RxBool desktopicon = true.obs;
  final RxBool driverCert = true.obs;
  final RxBool showProgress = false.obs;
  final RxBool btnEnabled = true.obs;

  @override
  void initState() {
    windowManager.addListener(this);
    controller = TextEditingController(text: bind.installInstallPath());
    super.initState();
  }

  @override
  void dispose() {
    windowManager.removeListener(this);
    super.dispose();
  }

  @override
  void onWindowClose() {
    gFFI.close();
    super.onWindowClose();
    windowManager.setPreventClose(false);
    windowManager.close();
  }

  @override
  Widget build(BuildContext context) {
    final double em = 13;
    final btnFontSize = 0.9 * em;
    final double button_radius = 6;
    final isDarkTheme = MyTheme.currentThemeMode() == ThemeMode.dark;
    final buttonStyle = OutlinedButton.styleFrom(
        shape: RoundedRectangleBorder(
      borderRadius: BorderRadius.all(Radius.circular(button_radius)),
    ));
    final inputBorder = OutlineInputBorder(
        borderRadius: BorderRadius.zero,
        borderSide:
            BorderSide(color: isDarkTheme ? Colors.white70 : Colors.black12));
    final textColor = isDarkTheme ? null : Colors.black87;
    final dividerColor = isDarkTheme ? Colors.white70 : Colors.black87;
    return Scaffold(
        backgroundColor: null,
        body: SingleChildScrollView(
          child: Column(
            children: [
              Row(
                children: [
                  Text(
                    translate('Installation'),
                    style: TextStyle(
                        fontSize: 2 * em, fontWeight: FontWeight.w500),
                  ),
                ],
              ),
              Row(
                children: [
                  Text('${translate('Installation Path')}: '),
                  Expanded(
                      child: TextField(
                    controller: controller,
                    readOnly: true,
                    style: TextStyle(
                        fontSize: 1.5 * em, fontWeight: FontWeight.w400),
                    decoration: InputDecoration(
                      isDense: true,
                      contentPadding: EdgeInsets.all(0.75 * em),
                      enabledBorder: inputBorder,
                      border: inputBorder,
                      focusedBorder: inputBorder,
                      constraints: BoxConstraints(maxHeight: 3 * em),
                    ),
                  )),
                  Obx(() => OutlinedButton(
                          onPressed:
                              btnEnabled.value ? selectInstallPath : null,
                          style: buttonStyle,
                          child: Text(translate('Change Path'),
                              style: TextStyle(
                                  color: textColor, fontSize: btnFontSize)))
                      .marginOnly(left: em))
                ],
              ).marginSymmetric(vertical: 2 * em),
              TextButton(
                onPressed: () => startmenu.value = !startmenu.value,
                child: Row(
                  children: [
                    Obx(() => Checkbox(
                        value: startmenu.value,
                        onChanged: (b) {
                          if (b != null) startmenu.value = b;
                        })),
                    RichText(
                      text: TextSpan(
                        text: translate('Create start menu shortcuts'),
                        style: DefaultTextStyle.of(context).style,
                      ),
                    ),
                  ],
                ),
              ),
              TextButton(
                onPressed: () => desktopicon.value = !desktopicon.value,
                child: Row(
                  children: [
                    Obx(() => Checkbox(
                        value: desktopicon.value,
                        onChanged: (b) {
                          if (b != null) desktopicon.value = b;
                        })),
                    RichText(
                      text: TextSpan(
                        text: translate('Create desktop icon'),
                        style: DefaultTextStyle.of(context).style,
                      ),
                    ),
                  ],
                ),
              ),
              Offstage(
                offstage: !Platform.isWindows,
                child: TextButton(
                  onPressed: () => driverCert.value = !driverCert.value,
                  child: Row(
                    children: [
                      Obx(() => Checkbox(
                          value: driverCert.value,
                          onChanged: (b) {
                            if (b != null) driverCert.value = b;
                          })),
                      RichText(
                        text: TextSpan(
                          text: translate('idd_driver_tip'),
                          style: DefaultTextStyle.of(context).style,
                        ),
                      ),
                    ],
                  ),
                ),
              ),
              GestureDetector(
                  onTap: () => launchUrlString('http://rustdesk.com/privacy'),
                  child: Row(
                    children: [
                      Text(translate('End-user license agreement'),
                          style: const TextStyle(
                              decoration: TextDecoration.underline))
                    ],
                  )).marginOnly(top: 2 * em),
              Row(children: [Text(translate('agreement_tip'))])
                  .marginOnly(top: em),
              Divider(color: dividerColor).marginSymmetric(vertical: 0.5 * em),
              Row(
                children: [
                  Expanded(
                      child: Obx(() => Offstage(
                            offstage: !showProgress.value,
                            child: LinearProgressIndicator(),
                          ))),
                  Obx(() => OutlinedButton(
                          onPressed: btnEnabled.value
                              ? () => windowManager.close()
                              : null,
                          style: buttonStyle,
                          child: Text(translate('Cancel'),
                              style: TextStyle(
                                  color: textColor, fontSize: btnFontSize)))
                      .marginOnly(right: 2 * em)),
                  Obx(() => ElevatedButton(
                      onPressed: btnEnabled.value ? install : null,
                      style: ElevatedButton.styleFrom(
                          primary: MyTheme.button,
                          shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.all(
                                Radius.circular(button_radius)),
                          )),
                      child: Text(
                        translate('Accept and Install'),
                        style: TextStyle(fontSize: btnFontSize),
                      ))),
                  Offstage(
                    offstage: bind.installShowRunWithoutInstall(),
                    child: Obx(() => OutlinedButton(
                            onPressed: btnEnabled.value
                                ? () => bind.installRunWithoutInstall()
                                : null,
                            style: buttonStyle,
                            child: Text(translate('Run without install'),
                                style: TextStyle(
                                    color: textColor, fontSize: btnFontSize)))
                        .marginOnly(left: 2 * em)),
                  ),
                ],
              )
            ],
          ).paddingSymmetric(horizontal: 8 * em, vertical: 2 * em),
        ));
  }

  void install() {
    do_install() {
      btnEnabled.value = false;
      showProgress.value = true;
      String args = '';
      if (startmenu.value) args += ' startmenu';
      if (desktopicon.value) args += ' desktopicon';
      if (driverCert.value) args += ' driverCert';
      bind.installInstallMe(options: args, path: controller.text);
    }

    if (driverCert.isTrue) {
      final tag = 'install-info-install-cert-confirm';
      final btns = [
        dialogButton(
          'Cancel',
          onPressed: () => gFFI.dialogManager.dismissByTag(tag),
          isOutline: true,
        ),
        dialogButton(
          'OK',
          onPressed: () {
            gFFI.dialogManager.dismissByTag(tag);
            do_install();
          },
          isOutline: false,
        ),
      ];
      gFFI.dialogManager.show(
        (setState, close) => CustomAlertDialog(
          title: null,
          content: SelectionArea(
              child:
                  msgboxContent('info', 'Warning', 'confirm_idd_driver_tip')),
          actions: btns,
          onCancel: close,
        ),
        tag: tag,
      );
    } else {
      do_install();
    }
  }

  void selectInstallPath() async {
    String? install_path = await FilePicker.platform
        .getDirectoryPath(initialDirectory: controller.text);
    if (install_path != null) {
      install_path = '$install_path\\${await bind.mainGetAppName()}';
      controller.text = install_path;
    }
  }
}