import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:logging/logging.dart';
import 'package:provider/provider.dart';
import 'package:result_monad/result_monad.dart';

import '../controls/login_aware_cached_network_image.dart';
import '../controls/standard_appbar.dart';
import '../controls/status_and_refresh_button.dart';
import '../globals.dart';
import '../models/visibility.dart';
import '../serializers/friendica/image_entry_friendica_extensions.dart';
import '../services/gallery_service.dart';
import '../services/network_status_service.dart';
import '../utils/active_profile_selector.dart';
import '../utils/snackbar_builder.dart';
import 'media_viewer_screen.dart';

class GalleryScreen extends StatelessWidget {
  static final _logger = Logger('$GalleryScreen');
  final String galleryName;

  const GalleryScreen({super.key, required this.galleryName});

  @override
  Widget build(BuildContext context) {
    _logger.finer('Building $galleryName');
    final nss = getIt<NetworkStatusService>();
    return Scaffold(
      appBar: StandardAppBar.build(context, galleryName, actions: [
        StatusAndRefreshButton(
          valueListenable: nss.imageGalleryLoadingStatus,
          refreshFunction: () async => context
              .read<ActiveProfileSelector<GalleryService>>()
              .activeEntry
              .withResultAsync(
                (gs) async => gs.updateGalleryImageList(
                  galleryName: galleryName,
                  withNextPage: false,
                  nextPageOnly: false,
                ),
              ),
          busyColor: Theme.of(context).appBarTheme.foregroundColor,
        ),
      ]),
      body: _GalleryScreenBody(
        galleryName: galleryName,
      ),
    );
  }
}

class _GalleryScreenBody extends StatelessWidget {
  static const thumbnailDimension = 350.0;
  static final _logger = Logger('$_GalleryScreenBody');
  final String galleryName;

  const _GalleryScreenBody({required this.galleryName});

  @override
  Widget build(BuildContext context) {
    _logger.finer('Building');
    final service = context
        .watch<ActiveProfileSelector<GalleryService>>()
        .activeEntry
        .value;
    return service.getGallery(galleryName).fold(
          onSuccess: (galleryData) =>
              buildBody(context, service, galleryData.count),
          onError: (error) => buildErrorBody(error.message),
        );
  }

  Widget buildErrorBody(String error) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          Text('Error getting images for gallery: $error'),
        ],
      ),
    );
  }

  Widget buildBody(
    BuildContext context,
    GalleryService service,
    int expectedPhotoCount,
  ) {
    final imageResult = service.getGalleryImageList(galleryName);
    if (imageResult.isFailure) {
      return buildErrorBody(imageResult.error.message);
    }

    final images = imageResult.value;
    final attachments = images.map((i) => i.toMediaAttachment()).toList();
    if (images.isEmpty && service.loaded) {
      return const Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Text('No images'),
          ],
        ),
      );
    }

    if (images.isEmpty) {
      return const Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Text('Loading images'),
          ],
        ),
      );
    }

    return GridView.builder(
        itemCount: images.length,
        padding: const EdgeInsets.all(5.0),
        gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
            maxCrossAxisExtent: thumbnailDimension),
        itemBuilder: (context, index) {
          final image = images[index];
          if (images.length < expectedPhotoCount &&
              index == images.length - 1) {
            service.updateGalleryImageList(
              galleryName: galleryName,
              withNextPage: true,
              nextPageOnly: true,
            );
          }
          return Padding(
            padding: const EdgeInsets.all(2.0),
            child: GestureDetector(
              onTap: () {
                Navigator.push(context, MaterialPageRoute(builder: (context) {
                  return MediaViewerScreen(
                    attachments: attachments,
                    initialIndex: index,
                  );
                }));
              },
              child: Card(
                child: Stack(
                  children: [
                    LoginAwareCachedNetworkImage(
                      width: thumbnailDimension,
                      height: thumbnailDimension,
                      imageUrl: image.thumbnailUrl,
                    ),
                    Positioned(
                      top: 5.0,
                      right: 5.0,
                      child: Row(
                        children: [
                          Card(
                            color: Theme.of(context)
                                .scaffoldBackgroundColor
                                .withOpacity(0.7),
                            child: IconButton(
                              onPressed: () => context.push(
                                '/gallery/edit/$galleryName/image/${image.id}',
                              ),
                              icon: const Icon(Icons.edit),
                            ),
                          ),
                          Card(
                            color: Theme.of(context)
                                .scaffoldBackgroundColor
                                .withOpacity(0.7),
                            child: IconButton(
                              onPressed: () async {
                                final confirm = await showYesNoDialog(
                                    context, 'Delete image?');
                                if (confirm != true) {
                                  return;
                                }
                                await service
                                    .deleteImage(image)
                                    .withError((error) {
                                  if (context.mounted) {
                                    buildSnackbar(context,
                                        'Error deleting image: $error');
                                  }
                                });
                              },
                              icon: const Icon(Icons.delete),
                            ),
                          ),
                        ],
                      ),
                    ),
                    if (image.description.isNotEmpty)
                      Positioned(
                        bottom: 5.0,
                        left: 5.0,
                        child: ElevatedButton(
                          onPressed: () async => await showImageCaption(
                            context,
                            image.description,
                          ),
                          style: ElevatedButton.styleFrom(
                              backgroundColor: Theme.of(context)
                                  .scaffoldBackgroundColor
                                  .withOpacity(0.7)),
                          child: const Text('ALT'),
                        ),
                      ),
                    Positioned(
                      bottom: 5.0,
                      right: 5.0,
                      child: Card(
                        color: Theme.of(context)
                            .scaffoldBackgroundColor
                            .withOpacity(0.7),
                        child: Icon(
                            image.visibility.type == VisibilityType.public
                                ? Icons.public
                                : Icons.lock),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          );
        });
  }

  Future<void> showImageCaption(BuildContext context, String text) async {
    await showDialog<bool>(
      context: context,
      barrierDismissible: true,
      builder: (BuildContext context) {
        return AlertDialog(
          content: Text(
            text,
            softWrap: true,
          ),
          actions: <Widget>[
            ElevatedButton(
              child: const Text('Dismiss'),
              onPressed: () {
                Navigator.pop(context, true); // showDialog() returns true
              },
            ),
          ],
        );
      },
    );
  }
}
