import 'dart:io';

import 'package:better_open_file/better_open_file.dart';
import 'package:filesize/filesize.dart';
import 'package:flowder/flowder.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:jiffy/jiffy.dart';
import 'package:path_provider/path_provider.dart';

import '../../../api/marianumcloud/webdav/queries/listFiles/cacheableFile.dart';
import '../../../api/marianumcloud/webdav/webdavApi.dart';
import '../../../widget/confirmDialog.dart';
import '../../../widget/fileViewer.dart';
import '../../../widget/unimplementedDialog.dart';
import 'files.dart';

class FileElement extends StatefulWidget {
  final CacheableFile file;
  final List<String> path;
  final void Function() refetch;
  const FileElement(this.file, this.path, this.refetch, {Key? key}) : super(key: key);

  static Future<DownloaderCore> download(BuildContext context, String remotePath, String name, Function(double) onProgress, Function(OpenResult) onDone) async {
    Directory paths = await getTemporaryDirectory();

    String local = paths.path + Platform.pathSeparator + name;

    DownloaderUtils options = DownloaderUtils(
      progressCallback: (current, total) {
        final progress = (current / total) * 100;
        onProgress(progress);
      },
      file: File(local),
      progress: ProgressImplementation(),
      deleteOnCancel: true,
      onDone: () {
        //Future<OpenResult> result = OpenFile.open(local); // TODO legacy - refactor: remove onDone parameter
        Navigator.of(context).push(MaterialPageRoute(builder: (context) => FileViewer(path: local)));
        onDone(OpenResult(message: "File viewer opened", type: ResultType.done));
        // result.then((value) => {
        //   onDone(value)
        // });
      },
    );

    return await Flowder.download(
      "${await WebdavApi.webdavConnectString}$remotePath",
      options,
    );
  }

  @override
  State<FileElement> createState() => _FileElementState();
}

class _FileElementState extends State<FileElement> {
  double percent = 0;
  Future<DownloaderCore>? downloadCore;

  Widget getSubtitle() {
    if(widget.file.currentlyDownloading) {
      return Row(
        children: [
          Container(
            margin: const EdgeInsets.only(right: 10),
            child: const Text("Download:"),
          ),
          Expanded(
            child: LinearProgressIndicator(value: percent/100),
          ),
          Container(
            margin: const EdgeInsets.only(left: 10),
            child: Text("${percent.round()}%"),
          ),
        ],
      );
    }
    return widget.file.isDirectory
        ? Text("${widget.file.sort} geändert ${Jiffy.parseFromDateTime(widget.file.modifiedAt ?? DateTime.now()).fromNow()}")
        : Text("${widget.file.sort} ${filesize(widget.file.size)}, ${Jiffy.parseFromDateTime(widget.file.modifiedAt ?? DateTime.now()).fromNow()}");
  }

  @override
  Widget build(BuildContext context) {
    return ListTile(
      leading: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [Icon(widget.file.isDirectory ? Icons.folder_outlined : Icons.description_outlined)],
      ),
      title: Text(widget.file.name),
      subtitle: getSubtitle(),
      trailing: Icon(widget.file.isDirectory ? Icons.arrow_right : null),
      onTap: () {
        if(widget.file.isDirectory) {
          Navigator.of(context).push(MaterialPageRoute(
            builder: (context) {
              return Files(widget.path.toList()..add(widget.file.name));
            },
          ));
        } else {
          if(widget.file.currentlyDownloading) {
            showDialog(
              context: context,
              builder: (context) => ConfirmDialog(
                title: "Download abbrechen?",
                content: "Möchtest du den Download abbrechen?",
                cancelButton: "Nein",
                confirmButton: "Ja, Abbrechen",
                onConfirm: () {
                  downloadCore?.then((value) {
                    if(!value.isCancelled) value.cancel();
                  });
                  setState(() {
                    widget.file.currentlyDownloading = false;
                    percent = 0;
                    downloadCore = null;
                  });
                },
              ),
            );

            return;
          }

          setState(() {
            widget.file.currentlyDownloading = true;
          });

          downloadCore = FileElement.download(context, widget.file.path, widget.file.name, (progress) {
            setState(() => percent = progress);
          }, (result) {
            if(result.type != ResultType.done) {
              showDialog(context: context, builder: (context) {
                return AlertDialog(
                  title: const Text("Download"),
                  content: Text(result.message),
                );
              });
            }

            setState(() {
              widget.file.currentlyDownloading = false;
              percent = 0;
            });
          });

        }
      },
      onLongPress: () {
        showDialog(context: context, builder: (context) {
          return SimpleDialog(
            children: [
              ListTile(
                leading: const Icon(Icons.delete_outline),
                title: const Text("Löschen"),
                onTap: () {
                  Navigator.of(context).pop();
                  showDialog(context: context, builder: (context) => ConfirmDialog(
                    title: "Element löschen?",
                    content: "Das Element wird unwiederruflich gelöscht.",
                    onConfirm: () {
                      WebdavApi.webdav
                          .then((value) => value.delete(widget.file.path))
                          .then((value) => widget.refetch());
                    }
                  ));
                },
              ),
              Visibility(
                visible: kReleaseMode,
                child: ListTile(
                  leading: const Icon(Icons.share_outlined),
                  title: const Text("Teilen"),
                  onTap: () {
                    Navigator.of(context).pop();
                    UnimplementedDialog.show(context);
                  },
                ),
              ),
            ],
          );
        });
      },
    );
  }
}