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 '../../../widget/infoDialog.dart';
import 'package:nextcloud/nextcloud.dart';
import 'package:path_provider/path_provider.dart';

import '../../../api/marianumcloud/webdav/queries/listFiles/cacheableFile.dart';
import '../../../api/marianumcloud/webdav/webdavApi.dart';
import '../../../model/endpointData.dart';
import '../../../widget/centeredLeading.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, {super.key});

  static Future<DownloaderCore> download(BuildContext context, String remotePath, String name, Function(double) onProgress, Function(OpenResult) onDone) async {
    var paths = await getTemporaryDirectory();
    
    var encodedPath = Uri.encodeComponent(remotePath);
    encodedPath = encodedPath.replaceAll('%2F', '/');

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

    var 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}$encodedPath',
      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('geändert ${Jiffy.parseFromDateTime(widget.file.modifiedAt ?? DateTime.now()).fromNow()}')
        : Text('${filesize(widget.file.size)}, ${Jiffy.parseFromDateTime(widget.file.modifiedAt ?? DateTime.now()).fromNow()}');
  }

  @override
  Widget build(BuildContext context) => ListTile(
      leading: CenteredLeading(
          Icon(widget.file.isDirectory ? Icons.folder : Icons.description_outlined)
      ),
      title: Text(widget.file.name, maxLines: 2, overflow: TextOverflow.ellipsis),
      subtitle: getSubtitle(),
      trailing: Icon(widget.file.isDirectory ? Icons.arrow_right : null),
      onTap: () {
        if(widget.file.isDirectory) {
          Navigator.of(context).push(MaterialPageRoute(
            builder: (context) => Files(path: widget.path.toList()..add(widget.file.name)),
          ));
        } else {
          if(EndpointData().getEndpointMode() == EndpointMode.stage) {
            InfoDialog.show(context, 'Virtuelle Dateien im Staging Prozess können nicht heruntergeladen werden!');
            return;
          }
          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) => AlertDialog(
                  title: const Text('Download'),
                  content: Text(result.message),
                ));
            }

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

        }
      },
      onLongPress: () {
        showDialog(context: context, builder: (context) => 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(PathUri.parse(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);
                  },
                ),
              ),
            ],
          ));
      },
    );
}