import 'dart:io';

import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';

import '../controls/audio_video/av_control.dart';
import '../controls/login_aware_cached_network_image.dart';
import '../friendica_client/friendica_client.dart';
import '../globals.dart';
import '../models/attachment_media_type_enum.dart';
import '../models/media_attachment.dart';
import '../services/auth_service.dart';
import '../utils/snackbar_builder.dart';

class MediaViewerScreen extends StatefulWidget {
  final List<MediaAttachment> attachments;
  final int initialIndex;

  const MediaViewerScreen({
    super.key,
    required this.attachments,
    this.initialIndex = 0,
  });

  @override
  State<MediaViewerScreen> createState() => _MediaViewerScreenState();
}

class _MediaViewerScreenState extends State<MediaViewerScreen> {
  var currentIndex = 0;

  @override
  void initState() {
    super.initState();
    currentIndex = widget.initialIndex;
  }

  void nextAttachment() {
    if (currentIndex >= widget.attachments.length - 1) {
      return;
    }

    setState(() {
      currentIndex++;
    });
  }

  void previousAttachment() {
    if (currentIndex < 1) {
      return;
    }
    setState(() {
      currentIndex--;
    });
  }

  Future<void> saveImage(
    BuildContext context,
    MediaAttachment attachment,
  ) async {
    buildSnackbar(context, 'Downloading full image to save locally');
    final appsDir = await getApplicationDocumentsDirectory();
    final filename = p.basename(attachment.fullFileUri.path);
    final bytesResult =
        await RemoteFileClient(getIt<AccountsService>().currentProfile)
            .getFileBytes(attachment.uri);
    if (bytesResult.isFailure && mounted) {
      buildSnackbar(context,
          'Error getting full size version of file: ${bytesResult.error}');
      return;
    }

    if (Platform.isAndroid || Platform.isIOS) {
      final saveResult = await ImageGallerySaver.saveImage(bytesResult.value);
      if (saveResult['isSuccess']) {
        buildSnackbar(context, 'Image saved to gallery');
      } else {
        buildSnackbar(context, 'Unable to save to gallery, check permissions');
      }
    } else {
      final location = await FilePicker.platform.saveFile(
        dialogTitle: 'Save Image',
        fileName: filename,
        initialDirectory: appsDir.path,
      );
      if (location != null) {
        await File(location).writeAsBytes(bytesResult.value);
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    final currentAttachment = widget.attachments[currentIndex];
    final width = MediaQuery.of(context).size.width;
    final height = MediaQuery.of(context).size.height * 1.0;
    final mediaHeight = height;

    late final bool canSave;
    late final Widget mediaViewer;
    switch (currentAttachment.explicitType) {
      case AttachmentMediaType.image:
        canSave = true;
        mediaViewer = InteractiveViewer(
          maxScale: 10.0,
          scaleFactor: 400,
          child: LoginAwareCachedNetworkImage(
              imageUrl: currentAttachment.mainUri.toString()),
        );
        break;
      case AttachmentMediaType.unknown:
      case AttachmentMediaType.video:
        canSave = false;
        if (Platform.isLinux) {
          mediaViewer = Text(
              'No media viewer for ${currentAttachment.explicitType.name} type for link ${currentAttachment.fullFileUri}');
        } else {
          mediaViewer = SizedBox(
            width: width,
            height: mediaHeight,
            child: AVControl(
              videoUrl: currentAttachment.fullFileUri.toString(),
              description: currentAttachment.description,
            ),
          );
        }
        break;
    }

    return Scaffold(
      appBar: AppBar(
        actions: [
          if (canSave)
            IconButton(
                onPressed: () => saveImage(context, currentAttachment),
                icon: const Icon(Icons.download))
        ],
      ),
      body: SafeArea(
        child: Stack(
          children: [
            SizedBox(
              height: height,
              width: width,
              child: mediaViewer,
            ),
            if (widget.attachments.length > 1) ...[
              Positioned(
                bottom: mediaHeight * 0.5,
                child: Opacity(
                  opacity: 0.8,
                  child: currentIndex < 1
                      ? null
                      : Container(
                          color: Colors.black,
                          child: IconButton(
                            color: Colors.white,
                            onPressed: previousAttachment,
                            icon: const Icon(Icons.chevron_left),
                          ),
                        ),
                ),
              ),
              Positioned(
                bottom: mediaHeight * 0.5,
                right: 0.0,
                child: Opacity(
                  opacity: 0.8,
                  child: currentIndex >= widget.attachments.length - 1
                      ? null
                      : Container(
                          color: Colors.black,
                          child: IconButton(
                            color: Colors.white,
                            onPressed: nextAttachment,
                            icon: const Icon(Icons.chevron_right),
                          ),
                        ),
                ),
              ),
              if (currentAttachment.description.isNotEmpty)
                Positioned(
                  bottom: 5.0,
                  left: 5.0,
                  child: ElevatedButton(
                    onPressed: () async => await showConfirmDialog(
                      context,
                      currentAttachment.description,
                    ),
                    style: ElevatedButton.styleFrom(
                        backgroundColor: Theme.of(context)
                            .scaffoldBackgroundColor
                            .withOpacity(0.7)),
                    child: const Text('ALT'),
                  ),
                ),
            ]
          ],
        ),
      ),
    );
  }
}
