import 'dart:io';
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:go_router/go_router.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:path_provider/path_provider.dart';
import 'package:share_plus/share_plus.dart';

import 'package:f0ckapp/models/mediaitem_model.dart';
import 'package:f0ckapp/widgets/video_widget.dart';
import 'package:f0ckapp/utils/smartrefreshindicator_util.dart';
import 'package:f0ckapp/utils/pagetransformer_util.dart';
import 'package:f0ckapp/providers/media_provider.dart';

class DetailView extends ConsumerStatefulWidget {
  final int initialItemId;

  const DetailView({super.key, required this.initialItemId});

  @override
  ConsumerState<DetailView> createState() => _DetailViewState();
}

class _DetailViewState extends ConsumerState<DetailView> {
  PageController? _pageController;
  bool isLoading = false;
  int _currentIndex = 0;

  @override
  void initState() {
    super.initState();
  }

  void _preloadAdjacentMedia(int index) async {
    final mediaState = ref.read(mediaProvider);
    for (int offset in [-1, 1]) {
      final adjacentIndex = index + offset;
      if (adjacentIndex >= 0 && adjacentIndex < mediaState.mediaItems.length) {
        final url = mediaState.mediaItems[adjacentIndex].mediaUrl;
        if (await DefaultCacheManager().getFileFromCache(url) == null) {
          await DefaultCacheManager().downloadFile(url);
        }
      }
    }
  }

  Future<void> _loadMoreMedia() async {
    if (isLoading) return;
    setState(() => isLoading = true);

    try {
      await ref.read(mediaProvider.notifier).loadMedia();
    } catch (e) {
      _showMsg("Fehler beim Laden der Medien: $e");
    } finally {
      setState(() => isLoading = false);
    }
  }

  void _showMsg(String message) {
    if (!mounted) return;
    ScaffoldMessenger.of(context)
      ..removeCurrentSnackBar()
      ..showSnackBar(SnackBar(content: Text(message)));
  }

  Future<void> _downloadMedia() async {
    final MediaState mediaState = ref.read(mediaProvider);
    final MediaItem currentItem = mediaState.mediaItems[_currentIndex];

    if (Platform.isAndroid || Platform.isIOS) {
      PermissionStatus status = await Permission.storage.status;
      if (!status.isGranted) {
        status = await Permission.storage.request();
        if (!status.isGranted) {
          _showMsg("Speicherberechtigung wurde nicht erteilt.");
          return;
        }
      }
    }

    String localPath;
    if (Platform.isAndroid) {
      final Directory? directory = await getExternalStorageDirectory();
      localPath = "${directory!.path}/Download/fApp";
    } else if (Platform.isIOS) {
      final Directory directory = await getApplicationDocumentsDirectory();
      localPath = directory.path;
    } else {
      final Directory directory = await getTemporaryDirectory();
      localPath = directory.path;
    }

    final Directory savedDir = Directory(localPath);
    if (!await savedDir.exists()) {
      await savedDir.create(recursive: true);
    }

    try {
      await FlutterDownloader.enqueue(
        url: currentItem.mediaUrl,
        savedDir: localPath,
        fileName: currentItem.mediaUrl.split('/').last,
        showNotification: true,
        openFileFromNotification: true,
      );

      if (mounted) {
        _showMsg('Download gestartet: ${currentItem.mediaUrl}');
      }
    } catch (e) {
      _showMsg('Download fehlgeschlagen: $e');
    }
  }

  @override
  void dispose() {
    _pageController?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final MediaState mediaState = ref.watch(mediaProvider);
    final int itemIndex = mediaState.mediaItems.indexWhere(
      (item) => item.id == widget.initialItemId,
    );

    if (itemIndex == -1) {
      Future.microtask(() {
        ref
            .read(mediaProvider.notifier)
            .loadMedia(id: widget.initialItemId + 50);
      });
      return Scaffold(
        appBar: AppBar(),
        body: const Center(child: CircularProgressIndicator()),
      );
    }

    if (_pageController == null) {
      _pageController = PageController(initialPage: itemIndex);
      _currentIndex = itemIndex;
      _pageController!.addListener(() {
        setState(() => _currentIndex = _pageController!.page?.round() ?? 0);
      });
      _preloadAdjacentMedia(itemIndex);
    }

    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: Text('f0ck #${mediaState.mediaItems[_currentIndex].id}'),
        automaticallyImplyLeading: false,
        leading: IconButton(
          icon: const Icon(Icons.arrow_back),
          onPressed: () {
            context.canPop() ? context.pop() : context.go('/', extra: true);
          },
        ),
        actions: [
          IconButton(
            icon: const Icon(Icons.fullscreen),
            onPressed: () {
              _showMsg('fullscreen ist wip');
            },
          ),
          IconButton(
            icon: const Icon(Icons.download),
            onPressed: _downloadMedia,
          ),
          PopupMenuButton<String>(
            onSelected: (value) async {
              final item = mediaState.mediaItems[_currentIndex];
              switch (value) {
                case 'media':
                  File file = await DefaultCacheManager().getSingleFile(
                    item.mediaUrl,
                  );
                  Uint8List bytes = await file.readAsBytes();
                  final params = ShareParams(
                    files: [XFile.fromData(bytes, mimeType: item.mime)],
                  );
                  await SharePlus.instance.share(params);
                  break;
                case 'direct_link':
                  await SharePlus.instance.share(
                    ShareParams(text: item.mediaUrl),
                  );
                  break;
                case 'post_link':
                  await SharePlus.instance.share(
                    ShareParams(text: item.postUrl),
                  );
                  break;
              }
            },
            itemBuilder: (context) => [
              PopupMenuItem(
                value: 'media',
                child: ListTile(
                  leading: const Icon(Icons.image),
                  title: const Text('Als Datei'),
                ),
              ),
              PopupMenuItem(
                value: 'direct_link',
                child: ListTile(
                  leading: const Icon(Icons.link),
                  title: const Text('Link zur Datei'),
                ),
              ),
              PopupMenuItem(
                value: 'post_link',
                child: ListTile(
                  leading: const Icon(Icons.article),
                  title: const Text('Link zum f0ck'),
                ),
              ),
            ],
            icon: const Icon(Icons.share),
          ),
        ],
      ),
      body: Stack(
        children: [
          PageTransformer(
            controller: _pageController!,
            pages: mediaState.mediaItems.map((item) {
              int itemIndex = mediaState.mediaItems.indexOf(item);
              return SafeArea(
                child: SmartRefreshIndicator(
                  onRefresh: _loadMoreMedia,
                  child: _buildMediaItem(item, _currentIndex == itemIndex),
                ),
              );
            }).toList(),
          ),
        ],
      ),
      persistentFooterButtons: mediaState.tag != null
          ? [
              Center(
                child: InputChip(
                  label: Text(mediaState.tag!),
                  onDeleted: () {
                    ref.read(mediaProvider.notifier).setTag(null);
                    context.go('/', extra: true);
                  },
                ),
              ),
            ]
          : null,
    );
  }

  Widget _buildMediaItem(MediaItem item, bool isActive) {
    final MediaNotifier mediaNotifier = ref.read(mediaProvider.notifier);

    return SingleChildScrollView(
      child: Column(
        children: [
          if (item.mime.startsWith('image'))
            CachedNetworkImage(
              imageUrl: item.mediaUrl,
              fit: BoxFit.contain,
              placeholder: (context, url) => const CircularProgressIndicator(),
              errorWidget: (context, url, error) => const Icon(Icons.error),
            )
          else
            VideoWidget(details: item, isActive: isActive),
          const SizedBox(height: 10, width: double.infinity),
          Wrap(
            alignment: WrapAlignment.center,
            spacing: 5.0,
            children: item.tags.map((tag) {
              return ActionChip(
                onPressed: () {
                  if (tag.tag == 'sfw' || tag.tag == 'nsfw') return;
                  setState(() {
                    mediaNotifier.setTag(tag.tag);
                    context.go('/', extra: true);
                  });
                },
                label: Text(tag.tag),
                backgroundColor: switch (tag.id) {
                  1 => Colors.green,
                  2 => Colors.red,
                  _ => const Color(0xFF090909),
                },
                labelStyle: const TextStyle(color: Colors.white),
              );
            }).toList(),
          ),
          const SizedBox(height: 20),
        ],
      ),
    );
  }
}
