import 'package:cached_network_image/cached_network_image.dart';
import 'package:cached_network_image_platform_interface/cached_network_image_platform_interface.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/api/api.dart';
import 'package:nc_photos/app_localizations.dart';
import 'package:nc_photos/cache_manager_util.dart';
import 'package:nc_photos/theme.dart';

class PhotoListImage extends StatelessWidget {
  const PhotoListImage({
    Key? key,
    required this.account,
    required this.previewUrl,
    this.padding = const EdgeInsets.all(2),
    this.isGif = false,
    this.isFavorite = false,
  }) : super(key: key);

  @override
  build(BuildContext context) {
    return Padding(
      padding: padding,
      child: FittedBox(
        clipBehavior: Clip.hardEdge,
        fit: BoxFit.cover,
        child: Stack(
          children: [
            Container(
              // arbitrary size here
              constraints: BoxConstraints.tight(const Size(128, 128)),
              color: AppTheme.getListItemBackgroundColor(context),
              child: previewUrl == null
                  ? Center(
                      child: Icon(
                        Icons.image_not_supported,
                        size: 64,
                        color: Colors.white.withOpacity(.8),
                      ),
                    )
                  : CachedNetworkImage(
                      cacheManager: ThumbnailCacheManager.inst,
                      imageUrl: previewUrl!,
                      httpHeaders: {
                        "Authorization":
                            Api.getAuthorizationHeaderValue(account),
                      },
                      fadeInDuration: const Duration(),
                      filterQuality: FilterQuality.high,
                      errorWidget: (context, url, error) {
                        // won't work on web because the image is downloaded by
                        // the cache manager instead
                        // where's the preview???
                        return Center(
                          child: Icon(
                            Icons.image_not_supported,
                            size: 64,
                            color: Colors.white.withOpacity(.8),
                          ),
                        );
                      },
                      imageRenderMethodForWeb: ImageRenderMethodForWeb.HttpGet,
                    ),
            ),
            if (isGif)
              Container(
                // arbitrary size here
                constraints: BoxConstraints.tight(const Size(128, 128)),
                alignment: AlignmentDirectional.topEnd,
                padding: const EdgeInsets.symmetric(horizontal: 2),
                child: const Icon(
                  Icons.gif,
                  size: 36,
                  color: Colors.white,
                ),
              ),
            if (isFavorite)
              Container(
                // arbitrary size here
                constraints: BoxConstraints.tight(const Size(128, 128)),
                alignment: AlignmentDirectional.bottomStart,
                padding: const EdgeInsets.all(8),
                child: const Icon(
                  Icons.star,
                  size: 20,
                  color: Colors.white,
                ),
              ),
          ],
        ),
      ),
    );
  }

  final Account account;
  final String? previewUrl;
  final bool isGif;
  final EdgeInsetsGeometry padding;
  final bool isFavorite;
}

class PhotoListVideo extends StatelessWidget {
  const PhotoListVideo({
    Key? key,
    required this.account,
    required this.previewUrl,
    this.isFavorite = false,
  }) : super(key: key);

  @override
  build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(2),
      child: FittedBox(
        clipBehavior: Clip.hardEdge,
        fit: BoxFit.cover,
        child: Stack(
          children: [
            Container(
              // arbitrary size here
              constraints: BoxConstraints.tight(const Size(128, 128)),
              color: AppTheme.getListItemBackgroundColor(context),
              child: CachedNetworkImage(
                cacheManager: ThumbnailCacheManager.inst,
                imageUrl: previewUrl,
                httpHeaders: {
                  "Authorization": Api.getAuthorizationHeaderValue(account),
                },
                fadeInDuration: const Duration(),
                filterQuality: FilterQuality.high,
                errorWidget: (context, url, error) {
                  // no preview for this video. Normal since video preview is disabled
                  // by default
                  return Center(
                    child: Icon(
                      Icons.image_not_supported,
                      size: 64,
                      color: Colors.white.withOpacity(.8),
                    ),
                  );
                },
                imageRenderMethodForWeb: ImageRenderMethodForWeb.HttpGet,
              ),
            ),
            Container(
              // arbitrary size here
              constraints: BoxConstraints.tight(const Size(128, 128)),
              alignment: AlignmentDirectional.topEnd,
              padding: const EdgeInsets.all(8),
              child: const Icon(
                Icons.play_circle_outlined,
                size: 24,
                color: Colors.white,
              ),
            ),
            if (isFavorite)
              Container(
                // arbitrary size here
                constraints: BoxConstraints.tight(const Size(128, 128)),
                alignment: AlignmentDirectional.bottomStart,
                padding: const EdgeInsets.all(8),
                child: const Icon(
                  Icons.star,
                  size: 20,
                  color: Colors.white,
                ),
              ),
          ],
        ),
      ),
    );
  }

  final Account account;
  final String previewUrl;
  final bool isFavorite;
}

class PhotoListLabel extends StatelessWidget {
  const PhotoListLabel({
    Key? key,
    required this.text,
  }) : super(key: key);

  @override
  build(BuildContext context) {
    return Container(
      alignment: AlignmentDirectional.centerStart,
      padding: const EdgeInsets.symmetric(horizontal: 16),
      child: Text(
        text,
        style: Theme.of(context).textTheme.subtitle1,
        maxLines: 2,
        overflow: TextOverflow.ellipsis,
      ),
    );
  }

  final String text;
}

class PhotoListLabelEdit extends PhotoListLabel {
  const PhotoListLabelEdit({
    Key? key,
    required String text,
    required this.onEditPressed,
  }) : super(key: key, text: text);

  @override
  build(BuildContext context) {
    return Stack(
      children: [
        // needed to expand the touch sensitive area to the whole row
        Container(
          color: Colors.transparent,
        ),
        super.build(context),
        PositionedDirectional(
          top: 0,
          bottom: 0,
          end: 0,
          child: IconButton(
            icon: const Icon(Icons.edit),
            tooltip: L10n.global().editTooltip,
            onPressed: onEditPressed,
          ),
        ),
      ],
    );
  }

  final VoidCallback? onEditPressed;
}

class PhotoListDate extends StatelessWidget {
  const PhotoListDate({
    Key? key,
    required this.date,
    this.isMonthOnly = false,
  }) : super(key: key);

  @override
  build(BuildContext context) {
    final pattern =
        isMonthOnly ? DateFormat.YEAR_MONTH : DateFormat.YEAR_MONTH_DAY;
    final subtitle =
        DateFormat(pattern, Localizations.localeOf(context).languageCode)
            .format(date.toLocal());
    return Align(
      alignment: AlignmentDirectional.centerStart,
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 8),
        child: Text(
          subtitle,
          style: Theme.of(context).textTheme.caption!.copyWith(
                color: AppTheme.getPrimaryTextColor(context),
                fontWeight: FontWeight.bold,
              ),
        ),
      ),
    );
  }

  final DateTime date;
  final bool isMonthOnly;
}