import 'package:flutter/material.dart';

import '../../../../app/theme/mapflow_theme.dart';
import '../../domain/place_models.dart';

class PlacePhotoCard extends StatelessWidget {
  const PlacePhotoCard({
    super.key,
    required this.place,
    required this.onTap,
    required this.onFavoriteToggle,
  });

  final PlaceRecommendation place;
  final VoidCallback onTap;
  final VoidCallback onFavoriteToggle;

  @override
  Widget build(BuildContext context) {
    final tokens = context.mapflowTokens;
    final photoUrls = place.photoUrls.take(3).toList();

    return GestureDetector(
      onTap: onTap,
      child: Container(
        width: 226,
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(tokens.panelRadius),
          border: Border.all(color: tokens.mapPanelBorder),
          boxShadow: [
            BoxShadow(
              color: tokens.mapShadow,
              blurRadius: 16,
              offset: const Offset(0, 8),
            ),
          ],
        ),
        clipBehavior: Clip.antiAlias,
        child: Stack(
          fit: StackFit.expand,
          children: [
            if (photoUrls.isEmpty)
              ColoredBox(
                color: tokens.mapPanelBorder,
                child: Icon(Icons.place_outlined, color: tokens.onDark),
              )
            else
              _PhotoTriptych(
                photoUrls: photoUrls,
                fallbackColor: tokens.mapPanelBorder,
              ),
            DecoratedBox(
              decoration: BoxDecoration(
                gradient: LinearGradient(
                  begin: Alignment.topCenter,
                  end: Alignment.bottomCenter,
                  colors: [Colors.transparent, tokens.imageScrim],
                ),
              ),
            ),
            Positioned(
              top: 8,
              right: 8,
              child: IconButton.filledTonal(
                onPressed: onFavoriteToggle,
                icon: Icon(
                  place.isFavorite ? Icons.favorite : Icons.favorite_border,
                  size: 18,
                ),
                style: IconButton.styleFrom(
                  fixedSize: const Size.square(36),
                  minimumSize: const Size.square(36),
                  padding: EdgeInsets.zero,
                ),
                tooltip: 'Избранное',
              ),
            ),
            Positioned(
              left: 10,
              right: 10,
              bottom: 12,
              child: Text(
                place.name,
                maxLines: 2,
                overflow: TextOverflow.ellipsis,
                style: TextStyle(
                  color: tokens.onDark,
                  fontWeight: FontWeight.w900,
                  height: 1.05,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class _PhotoTriptych extends StatelessWidget {
  const _PhotoTriptych({required this.photoUrls, required this.fallbackColor});

  final List<String> photoUrls;
  final Color fallbackColor;

  @override
  Widget build(BuildContext context) {
    if (photoUrls.length == 1) {
      return _PhotoTile(url: photoUrls.first, fallbackColor: fallbackColor);
    }

    return Row(
      children: [
        Expanded(
          flex: 3,
          child: _PhotoTile(url: photoUrls[0], fallbackColor: fallbackColor),
        ),
        const SizedBox(width: 2),
        Expanded(
          flex: 2,
          child: Column(
            children: [
              Expanded(
                child: _PhotoTile(
                  url: photoUrls[1],
                  fallbackColor: fallbackColor,
                ),
              ),
              if (photoUrls.length > 2) ...[
                const SizedBox(height: 2),
                Expanded(
                  child: _PhotoTile(
                    url: photoUrls[2],
                    fallbackColor: fallbackColor,
                  ),
                ),
              ],
            ],
          ),
        ),
      ],
    );
  }
}

class _PhotoTile extends StatelessWidget {
  const _PhotoTile({required this.url, required this.fallbackColor});

  final String url;
  final Color fallbackColor;

  @override
  Widget build(BuildContext context) {
    final colorScheme = Theme.of(context).colorScheme;
    return Image.network(
      _photoUrlForSize(url, maxWidth: 512),
      fit: BoxFit.cover,
      gaplessPlayback: true,
      loadingBuilder: (context, child, loadingProgress) {
        if (loadingProgress == null) {
          return child;
        }

        return ColoredBox(
          color: fallbackColor,
          child: Center(
            child: SizedBox.square(
              dimension: 22,
              child: CircularProgressIndicator(
                strokeWidth: 2,
                color: colorScheme.primary,
              ),
            ),
          ),
        );
      },
      errorBuilder: (_, _, _) => ColoredBox(
        color: fallbackColor,
        child: Icon(Icons.broken_image_outlined, color: colorScheme.outline),
      ),
    );
  }
}

String _photoUrlForSize(String url, {required int maxWidth}) {
  final uri = Uri.tryParse(url);
  if (uri == null || !uri.hasScheme) {
    return url;
  }

  final params = Map<String, String>.from(uri.queryParameters);
  if (params.containsKey('maxWidthPx') || params.containsKey('maxHeightPx')) {
    params
      ..update('maxWidthPx', (_) => '$maxWidth', ifAbsent: () => '$maxWidth')
      ..remove('maxHeightPx');
    return uri.replace(queryParameters: params).toString();
  }

  if (params.containsKey('maxwidth') || params.containsKey('maxheight')) {
    params
      ..update('maxwidth', (_) => '$maxWidth', ifAbsent: () => '$maxWidth')
      ..remove('maxheight');
    return uri.replace(queryParameters: params).toString();
  }

  if (uri.host.contains('places.googleapis.com')) {
    params['maxWidthPx'] = '$maxWidth';
    return uri.replace(queryParameters: params).toString();
  }

  if (uri.host.contains('googleapis.com')) {
    params['maxwidth'] = '$maxWidth';
    return uri.replace(queryParameters: params).toString();
  }

  return url;
}
