import 'dart:ui';

import 'package:aves/image_providers/app_icon_image_provider.dart';
import 'package:aves/model/entry.dart';
import 'package:aves/theme/icons.dart';
import 'package:aves/utils/android_file_utils.dart';
import 'package:aves/utils/constants.dart';
import 'package:aves/widgets/common/grid/theme.dart';
import 'package:decorated_icon/decorated_icon.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class VideoIcon extends StatelessWidget {
  final AvesEntry entry;

  const VideoIcon({
    Key? key,
    required this.entry,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final gridTheme = context.watch<GridThemeData>();
    final showDuration = gridTheme.showVideoDuration;
    Widget child = OverlayIcon(
      icon: entry.is360 ? AIcons.threeSixty : AIcons.videoThumb,
      text: showDuration ? entry.durationText : null,
      iconScale: entry.is360 && showDuration ? .9 : 1,
    );
    if (showDuration) {
      child = DefaultTextStyle(
        style: TextStyle(
          color: Colors.grey.shade200,
          fontSize: gridTheme.fontSize,
        ),
        child: child,
      );
    }
    return child;
  }
}

class AnimatedImageIcon extends StatelessWidget {
  const AnimatedImageIcon({Key? key}) : super(key: key);

  static const scale = .8;

  @override
  Widget build(BuildContext context) {
    return const OverlayIcon(
      icon: AIcons.animated,
      iconScale: scale,
    );
  }
}

class GeotiffIcon extends StatelessWidget {
  const GeotiffIcon({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const OverlayIcon(
      icon: AIcons.geo,
    );
  }
}

class SphericalImageIcon extends StatelessWidget {
  const SphericalImageIcon({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const OverlayIcon(
      icon: AIcons.threeSixty,
    );
  }
}

class GpsIcon extends StatelessWidget {
  const GpsIcon({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const OverlayIcon(
      icon: AIcons.location,
    );
  }
}

class RawIcon extends StatelessWidget {
  const RawIcon({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const OverlayIcon(
      icon: AIcons.raw,
    );
  }
}

class MotionPhotoIcon extends StatelessWidget {
  const MotionPhotoIcon({Key? key}) : super(key: key);

  static const scale = .8;

  @override
  Widget build(BuildContext context) {
    return const OverlayIcon(
      icon: AIcons.motionPhoto,
      iconScale: scale,
    );
  }
}

class MultiPageIcon extends StatelessWidget {
  final AvesEntry entry;

  static const scale = .8;

  const MultiPageIcon({
    Key? key,
    required this.entry,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    String? text;
    if (entry.isBurst) {
      text = '${entry.burstEntries?.length}';
    }
    final child = OverlayIcon(
      icon: AIcons.multiPage,
      iconScale: scale,
      text: text,
    );
    return DefaultTextStyle(
      style: TextStyle(
        color: Colors.grey.shade200,
        fontSize: context.select<GridThemeData, double>((t) => t.fontSize),
      ),
      child: child,
    );
  }
}

class OverlayIcon extends StatelessWidget {
  final IconData icon;
  final String? text;
  final double iconScale;

  const OverlayIcon({
    Key? key,
    required this.icon,
    this.iconScale = 1,
    this.text,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final size = context.select<GridThemeData, double>((t) => t.iconSize);
    final iconChild = Icon(
      icon,
      size: size,
      // consistent with the color used for the text next to it
      color: DefaultTextStyle.of(context).style.color,
    );
    final iconBox = SizedBox(
      width: size,
      height: size,
      // using a transform is better than modifying the icon size to properly center the scaled icon
      child: iconScale != 1
          ? Transform.scale(
              scale: iconScale,
              child: iconChild,
            )
          : iconChild,
    );

    return Container(
      margin: const EdgeInsets.only(left: 1, right: 1, bottom: 1),
      padding: text != null ? EdgeInsets.only(right: size / 4) : null,
      decoration: BoxDecoration(
        color: const Color(0xBB000000),
        borderRadius: BorderRadius.all(Radius.circular(size)),
      ),
      child: text == null
          ? iconBox
          : Row(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                iconBox,
                const SizedBox(width: 2),
                Text(text!),
              ],
            ),
    );
  }
}

class IconUtils {
  static Widget? getAlbumIcon({
    required BuildContext context,
    required String albumPath,
    double? size,
    bool embossed = false,
  }) {
    size ??= IconTheme.of(context).size;
    Widget buildIcon(IconData icon) => embossed
        ? MediaQuery(
            // `DecoratedIcon` internally uses `Text`,
            // which size depends on the ambient `textScaleFactor`
            // but we already accommodate for it upstream
            data: context.read<MediaQueryData>().copyWith(textScaleFactor: 1.0),
            child: DecoratedIcon(
              icon,
              shadows: Constants.embossShadows,
              size: size,
            ),
          )
        : Icon(
            icon,
            size: size,
          );
    switch (androidFileUtils.getAlbumType(albumPath)) {
      case AlbumType.camera:
        return buildIcon(AIcons.cameraAlbum);
      case AlbumType.screenshots:
      case AlbumType.videoCaptures:
        return buildIcon(AIcons.screenshotAlbum);
      case AlbumType.screenRecordings:
        return buildIcon(AIcons.recordingAlbum);
      case AlbumType.download:
        return buildIcon(AIcons.downloadAlbum);
      case AlbumType.app:
        return Image(
          image: AppIconImage(
            packageName: androidFileUtils.getAlbumAppPackageName(albumPath)!,
            size: size!,
          ),
          width: size,
          height: size,
        );
      case AlbumType.regular:
      default:
        return null;
    }
  }
}
