import 'dart:io';

import 'package:flutter/material.dart';
import 'package:loader_overlay/loader_overlay.dart';
import 'package:nextcloud/nextcloud.dart';
import 'package:persistent_bottom_nav_bar_v2/persistent_bottom_nav_bar_v2.dart';
import 'package:provider/provider.dart';

import '../../../api/marianumcloud/webdav/queries/listFiles/cacheableFile.dart';
import '../../../api/marianumcloud/webdav/queries/listFiles/listFilesCache.dart';
import '../../../api/marianumcloud/webdav/queries/listFiles/listFilesResponse.dart';
import '../../../api/marianumcloud/webdav/webdavApi.dart';
import '../../../model/files/filesProps.dart';
import '../../../storage/base/settingsProvider.dart';
import '../../../widget/loadingSpinner.dart';
import '../../../widget/placeholderView.dart';
import '../../../widget/filePick.dart';
import 'fileElement.dart';
import 'filesUploadDialog.dart';

class Files extends StatefulWidget {
  final List<String> path;
  Files({List<String>? path, super.key}) : path = path ?? [];

  @override
  State<Files> createState() => _FilesState();
}

class BetterSortOption {
  String displayName;
  int Function(CacheableFile, CacheableFile) compare;
  IconData icon;

  BetterSortOption({required this.displayName, required this.icon, required this.compare});
}

enum SortOption {
  name,
  date,
  size
}

class SortOptions {
  static Map<SortOption, BetterSortOption> options = {
    SortOption.name: BetterSortOption(
      displayName: 'Name',
      icon: Icons.sort_by_alpha_outlined,
      compare: (CacheableFile a, CacheableFile b) => a.name.compareTo(b.name)
    ),
    SortOption.date: BetterSortOption(
      displayName: 'Datum',
      icon: Icons.history_outlined,
      compare: (CacheableFile a, CacheableFile b) => a.modifiedAt!.compareTo(b.modifiedAt!)
    ),
    SortOption.size: BetterSortOption(
      displayName: 'Größe',
      icon: Icons.sd_card_outlined,
      compare: (CacheableFile a, CacheableFile b) {
        if(a.isDirectory || b.isDirectory) return a.isDirectory ? 1 : 0;
        if(a.size == null) return 0;
        if(b.size == null) return 1;
        return a.size!.compareTo(b.size!);
      }
    )
  };

  static BetterSortOption getOption(SortOption option) => options[option]!;
}

class _FilesState extends State<Files> {
  FilesProps props = FilesProps();
  ListFilesResponse? data;

  late SettingsProvider settings = Provider.of<SettingsProvider>(context, listen: false);

  SortOption currentSort = SortOption.name;
  bool currentSortDirection = true;

  @override
  void initState() {
    super.initState();
    currentSort = settings.val().fileSettings.sortBy;
    currentSortDirection = settings.val().fileSettings.ascending;
    _query();
  }

  void _query() {
    ListFilesCache(
        path: widget.path.isEmpty ? '/' : widget.path.join('/'),
        onUpdate: (ListFilesResponse d) {
          d.files.removeWhere((element) => element.name.isEmpty || element.name == widget.path.lastOrNull());
          setState(() {
            data = d;
          });
        }
    );
  }

  Future<void> mediaUpload(List<String>? paths) async {
    if(paths == null) return;

    pushScreen(
      context,
      withNavBar: false,
      screen: FilesUploadDialog(filePaths: paths, remotePath: widget.path.join('/'), onUploadFinished: (uploadedFilePaths) => _query()),
    );

    return;
  }

  @override
  Widget build(BuildContext context) {
    var files = data?.sortBy(
      sortOption: currentSort,
      foldersToTop: Provider.of<SettingsProvider>(context).val().fileSettings.sortFoldersToTop,
      reversed: currentSortDirection
    ) ?? List<CacheableFile>.empty();

    return Scaffold(
      appBar: AppBar(
        title: Text(widget.path.isNotEmpty ? widget.path.last : 'Dateien'),
        actions: [
          // IconButton(
          //   icon: const Icon(Icons.search),
          //   onPressed: () => {
          //     // TODO implement search
          //   },
          // ),
          PopupMenuButton<bool>(
            icon: Icon(currentSortDirection ? Icons.text_rotate_up : Icons.text_rotation_down),
            itemBuilder: (context) => [true, false].map((e) => PopupMenuItem<bool>(
                  value: e,
                  enabled: e != currentSortDirection,
                  child: Row(
                    children: [
                      Icon(e ? Icons.text_rotate_up : Icons.text_rotation_down, color: Theme.of(context).colorScheme.onSurface),
                      const SizedBox(width: 15),
                      Text(e ? 'Aufsteigend' : 'Absteigend')
                    ],
                  )
              )).toList(),
            onSelected: (e) {
              setState(() {
                currentSortDirection = e;
                settings.val(write: true).fileSettings.ascending = e;
              });
            },
          ),
          PopupMenuButton<SortOption>(
            icon: const Icon(Icons.sort),
            itemBuilder: (context) => SortOptions.options.keys.map((key) => PopupMenuItem<SortOption>(
                  value: key,
                  enabled: key != currentSort,
                  child: Row(
                    children: [
                      Icon(SortOptions.getOption(key).icon, color: Theme.of(context).colorScheme.onSurface),
                      const SizedBox(width: 15),
                      Text(SortOptions.getOption(key).displayName),
                    ],
                  )
              )).toList(),
            onSelected: (e) {
              setState(() {
                currentSort = e;
                settings.val(write: true).fileSettings.sortBy = e;
              });
            },
          ),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        heroTag: 'uploadFile',
        backgroundColor: Theme.of(context).primaryColor,
        onPressed: () {
          showDialog(context: context, builder: (context) => SimpleDialog(
              children: [
                ListTile(
                  leading: const Icon(Icons.create_new_folder_outlined),
                  title: const Text('Ordner erstellen'),
                  onTap: () {
                    Navigator.of(context).pop();
                    showDialog(context: context, builder: (context) {
                      var inputController = TextEditingController();
                      return AlertDialog(
                        title: const Text('Neuer Ordner'),
                        content: TextField(
                          controller: inputController,
                          decoration: const InputDecoration(
                            labelText: 'Name',
                          ),
                        ),
                        actions: [
                          TextButton(onPressed: () {
                            Navigator.of(context).pop();
                          }, child: const Text('Abbrechen')),
                          TextButton(onPressed: () {
                            WebdavApi.webdav.then((webdav) {
                              webdav.mkcol(PathUri.parse("${widget.path.join("/")}/${inputController.text}")).then((value) => _query());
                            });
                            Navigator.of(context).pop();
                          }, child: const Text('Ordner erstellen')),
                        ],
                      );
                    });
                  },
                ),
                ListTile(
                  leading: const Icon(Icons.upload_file),
                  title: const Text('Aus Dateien hochladen'),
                  onTap: () {
                    FilePick.documentPick().then(mediaUpload);
                    Navigator.of(context).pop();
                  },
                ),
                Visibility(
                  visible: !Platform.isIOS,
                  child: ListTile(
                    leading: const Icon(Icons.add_a_photo_outlined),
                    title: const Text('Aus Gallerie hochladen'),
                    onTap: () {
                      FilePick.multipleGalleryPick().then((value) {
                        if(value != null) mediaUpload(value.map((e) => e.path).toList());
                      });
                      Navigator.of(context).pop();
                    },
                  ),
                ),
              ],
            ));
        },
        child: const Icon(Icons.add),
      ),
      body: data == null ? const LoadingSpinner() : data!.files.isEmpty ? const PlaceholderView(icon: Icons.folder_off_rounded, text: 'Der Ordner ist leer') : LoaderOverlay(
        child: RefreshIndicator(
          onRefresh: () {
            _query();
            return Future.delayed(const Duration(seconds: 3));
          },
          child: ListView.builder(
            padding: EdgeInsets.zero,
            itemCount: files.length,
            itemBuilder: (context, index) {
              var file = files.toList()[index];
              return FileElement(file, widget.path, _query);
            },
          ),
        )
      )
    );
  }
}