import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:matrix/matrix.dart';
import 'package:pyramid/core/theme.dart';
import 'package:pyramid/utils/gif_favorite_service.dart';

const _giphyApiKey = 'QtEyHWSKVIZJersKNBbJGYIgOhwawjkk';
const _stickerServerUrl = 'https://stickers.steggi-matrix.work';

class GifStickerPicker extends StatefulWidget {
  final Room room;
  final VoidCallback onClose;

  const GifStickerPicker({
    super.key,
    required this.room,
    required this.onClose,
  });

  @override
  State<GifStickerPicker> createState() => _GifStickerPickerState();
}

class _GifStickerPickerState extends State<GifStickerPicker>
    with SingleTickerProviderStateMixin {
  late TabController _tabController;
  final _searchController = TextEditingController();
  final _customUrlController = TextEditingController();
  final _gifScrollController = ScrollController();
  final _packSelectorScroll = ScrollController();

  List<dynamic> _gifs = [];
  bool _gifLoading = false;
  int _gifOffset = 0;
  int _gifTotal = 0;
  String _gifQuery = '';
  int? _hoveredGifIndex;
  int? _hoveredFavIndex;

  static const _kFavsPack = '__favs__';
  static const _kMyPack = '__my__';

  List<String> _packs = [];
  final Map<String, dynamic> _packData = {};
  String? _selectedPack;
  bool _stickerLoading = false;
  bool _packLoading = false;
  PyramidTheme? _pt;

  List<String> get _allPackTabs {
    final tabs = <String>[];
    if (GifFavoriteService.stickerFavoritesItems.isNotEmpty) tabs.add(_kFavsPack);
    if (GifFavoriteService.userStickerItems.isNotEmpty) tabs.add(_kMyPack);
    tabs.addAll(_packs);
    return tabs;
  }

  void _selectDefaultTab() {
    final tabs = _allPackTabs;
    if (tabs.isNotEmpty && (_selectedPack == null || !tabs.contains(_selectedPack))) {
      setState(() => _selectedPack = tabs.first);
    }
  }

  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: 2, vsync: this);
    _gifScrollController.addListener(_onGifScroll);
    _loadTrendingGifs();
    GifFavoriteService.load().then((_) => setState(() {}));
    GifFavoriteService.loadStickers().then((_) {
      _selectDefaultTab();
      setState(() {});
    });
    _loadStickerPacks();
  }

  @override
  void dispose() {
    _tabController.dispose();
    _searchController.dispose();
    _customUrlController.dispose();
    _gifScrollController.dispose();
    _packSelectorScroll.dispose();
    super.dispose();
  }

  void _onGifScroll() {
    if (_gifScrollController.position.pixels >=
        _gifScrollController.position.maxScrollExtent - 300) {
      if (!_gifLoading && _gifOffset < _gifTotal) _loadMoreGifs();
    }
  }

  Future<void> _loadTrendingGifs() async {
    setState(() { _gifLoading = true; _gifs = []; _gifOffset = 0; _gifQuery = ''; });
    try {
      final res = await http.get(Uri.parse(
        'https://api.giphy.com/v1/gifs/trending?api_key=$_giphyApiKey&limit=24&offset=0',
      ));
      final data = jsonDecode(res.body);
      setState(() {
        _gifs = data['data'] ?? [];
        _gifTotal = data['pagination']?['total_count'] ?? 0;
        _gifOffset = _gifs.length;
        _gifLoading = false;
      });
    } catch (_) {
      setState(() => _gifLoading = false);
    }
  }

  Future<void> _searchGifs(String query) async {
    if (query.isEmpty) { _loadTrendingGifs(); return; }
    setState(() { _gifLoading = true; _gifs = []; _gifOffset = 0; _gifQuery = query; });
    try {
      final res = await http.get(Uri.parse(
        'https://api.giphy.com/v1/gifs/search?api_key=$_giphyApiKey&q=${Uri.encodeComponent(query)}&limit=24&offset=0',
      ));
      final data = jsonDecode(res.body);
      setState(() {
        _gifs = data['data'] ?? [];
        _gifTotal = data['pagination']?['total_count'] ?? 0;
        _gifOffset = _gifs.length;
        _gifLoading = false;
      });
    } catch (_) {
      setState(() => _gifLoading = false);
    }
  }

  Future<void> _loadMoreGifs() async {
    if (_gifLoading) return;
    setState(() => _gifLoading = true);
    try {
      final url = _gifQuery.isEmpty
          ? 'https://api.giphy.com/v1/gifs/trending?api_key=$_giphyApiKey&limit=24&offset=$_gifOffset'
          : 'https://api.giphy.com/v1/gifs/search?api_key=$_giphyApiKey&q=${Uri.encodeComponent(_gifQuery)}&limit=24&offset=$_gifOffset';
      final res = await http.get(Uri.parse(url));
      final data = jsonDecode(res.body);
      setState(() {
        _gifs.addAll(data['data'] ?? []);
        _gifOffset = _gifs.length;
        _gifLoading = false;
      });
    } catch (_) {
      setState(() => _gifLoading = false);
    }
  }

  Future<void> _toggleGifFav(String url, String previewUrl, String title) async {
    await GifFavoriteService.toggle(url, previewUrl, title);
    setState(() {});
  }

  Future<void> _loadStickerPacks() async {
    setState(() => _stickerLoading = true);
    try {
      final userId = widget.room.client.userID ?? '';
      final res = await http.get(Uri.parse(
        '$_stickerServerUrl/packs/index.json?userId=${Uri.encodeComponent(userId)}',
      ));
      final data = jsonDecode(res.body);
      final packs = List<String>.from(data['packs'] ?? [])
          .where((p) => !p.startsWith('__'))
          .toList();
      setState(() { _packs = packs; _stickerLoading = false; });
      _selectDefaultTab();
      if (_selectedPack != null && _selectedPack != _kFavsPack && _selectedPack != _kMyPack) {
        await _loadPack(_selectedPack!);
      }
    } catch (_) {
      setState(() => _stickerLoading = false);
    }
  }

  Future<void> _loadPack(String packId) async {
    if (_packData.containsKey(packId)) return;
    setState(() => _packLoading = true);
    try {
      final res = await http.get(Uri.parse('$_stickerServerUrl/packs/$packId/pack.json'));
      setState(() { _packData[packId] = jsonDecode(res.body); _packLoading = false; });
    } catch (_) {
      setState(() => _packLoading = false);
    }
  }

  Future<void> _sendGif(String url, String title) async {
    widget.onClose();
    await widget.room.sendEvent({
      'msgtype': 'm.image',
      'body': title.isNotEmpty ? title : 'GIF',
      'url': url,
      'info': {'mimetype': 'image/gif'},
    });
  }

  Future<void> _sendSticker(String mxcUrl, String body, Map<String, dynamic> info) async {
    widget.onClose();
    await widget.room.sendEvent(
      {'body': body, 'url': mxcUrl, 'info': info},
      type: EventTypes.Sticker,
    );
  }

  @override
  Widget build(BuildContext context) {
    final pt = PyramidTheme.of(context);
    _pt = pt;
    return Container(
      width: 380,
      height: 460,
      decoration: BoxDecoration(
        color: pt.bg1,
        borderRadius: BorderRadius.circular(12),
        border: Border.all(color: pt.border),
        boxShadow: const [
          BoxShadow(color: Color(0x50000000), blurRadius: 24, offset: Offset(0, 8))
        ],
      ),
      child: ClipRRect(
        borderRadius: BorderRadius.circular(12),
        child: Column(
          children: [
            // Header with tabs
            Container(
              decoration: BoxDecoration(
                border: Border(bottom: BorderSide(color: pt.border)),
              ),
              child: TabBar(
                controller: _tabController,
                indicatorColor: pt.accent,
                labelColor: pt.accent,
                unselectedLabelColor: pt.fgMuted,
                tabs: const [
                  Tab(icon: Icon(Icons.gif_box_outlined, size: 20)),
                  Tab(icon: Icon(Icons.sticky_note_2_outlined, size: 20)),
                ],
              ),
            ),
            Expanded(
              child: TabBarView(
                controller: _tabController,
                children: [_buildGifTab(), _buildStickerTab()],
              ),
            ),
          ],
        ),
      ),
    );
  }

  // ── GIF Tab ──────────────────────────────────────────────────────────────

  Widget _buildGifTab() {
    final favorites = GifFavoriteService.cache;
    final isSearching = _gifQuery.isNotEmpty;

    return Column(
      children: [
        Padding(
          padding: const EdgeInsets.fromLTRB(8, 8, 8, 4),
          child: TextField(
            controller: _searchController,
            style: TextStyle(color: _pt!.fg, fontSize: 13),
            decoration: InputDecoration(
              hintText: 'GIFs suchen…',
              hintStyle: TextStyle(color: _pt!.fgDim, fontSize: 13),
              prefixIcon: Icon(Icons.search, size: 16, color: _pt!.fgDim),
              isDense: true,
              suffixIcon: _searchController.text.isNotEmpty
                  ? IconButton(
                      icon: Icon(Icons.clear, size: 16, color: _pt!.fgDim),
                      onPressed: () {
                        _searchController.clear();
                        setState(() {});
                        _loadTrendingGifs();
                      },
                    )
                  : null,
              contentPadding: const EdgeInsets.symmetric(vertical: 8),
              filled: true,
              fillColor: _pt!.bg2,
              border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(8),
                  borderSide: BorderSide(color: _pt!.border)),
              enabledBorder: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(8),
                  borderSide: BorderSide(color: _pt!.border)),
              focusedBorder: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(8),
                  borderSide: BorderSide(color: _pt!.accent)),
            ),
            onChanged: (v) => setState(() {}),
            onSubmitted: _searchGifs,
          ),
        ),
        Expanded(
          child: _gifLoading && _gifs.isEmpty
              ? Center(child: CircularProgressIndicator(color: _pt!.accent))
              : CustomScrollView(
                  controller: _gifScrollController,
                  slivers: [
                    if (!isSearching && favorites.isNotEmpty) ...[
                      SliverToBoxAdapter(child: _SectionLabel('❤ Favoriten')),
                      _gifGrid(
                        count: favorites.length,
                        builder: (i) {
                          final fav = favorites[i];
                          final url = fav['url'] ?? '';
                          final preview = fav['preview_url'] ?? url;
                          final title = fav['title'] ?? 'GIF';
                          return _GifCell(
                            imageUrl: preview,
                            isFavorite: true,
                            isHovered: _hoveredFavIndex == i,
                            onHoverChanged: (h) => setState(() => _hoveredFavIndex = h ? i : null),
                            onTap: () => _sendGif(url, title),
                            onFavToggle: () => _toggleGifFav(url, preview, title),
                          );
                        },
                      ),
                      SliverToBoxAdapter(child: _SectionLabel('Trending')),
                    ],
                    _gifGrid(
                      count: _gifs.length,
                      builder: (i) {
                        final gif = _gifs[i];
                        final preview = gif['images']?['fixed_height_small']?['url'] ?? gif['images']?['fixed_height']?['url'] ?? '';
                        final full = gif['images']?['fixed_height']?['url'] ?? '';
                        final title = gif['title'] ?? 'GIF';
                        final fav = GifFavoriteService.isFavorite(full);
                        return _GifCell(
                          imageUrl: preview,
                          isFavorite: fav,
                          isHovered: _hoveredGifIndex == i,
                          onHoverChanged: (h) => setState(() => _hoveredGifIndex = h ? i : null),
                          onTap: () => _sendGif(full, title),
                          onFavToggle: () => _toggleGifFav(full, preview, title),
                        );
                      },
                    ),
                    if (_gifLoading)
                      SliverToBoxAdapter(
                        child: Padding(
                          padding: const EdgeInsets.all(12),
                          child: Center(child: CircularProgressIndicator(
                              strokeWidth: 2, color: _pt!.accent)),
                        ),
                      ),
                  ],
                ),
        ),
      ],
    );
  }

  SliverGrid _gifGrid({required int count, required Widget Function(int) builder}) =>
      SliverGrid(
        delegate: SliverChildBuilderDelegate((ctx, i) => builder(i), childCount: count),
        gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 3, crossAxisSpacing: 2, mainAxisSpacing: 2, childAspectRatio: 1,
        ),
      );

  // ── Sticker Tab ──────────────────────────────────────────────────────────

  Widget _buildStickerTab() {
    final allTabs = _allPackTabs;
    if (_stickerLoading) {
      return Center(child: CircularProgressIndicator(color: _pt!.accent));
    }
    if (allTabs.isEmpty) {
      return Center(child: Text('Keine Sticker verfügbar', style: TextStyle(color: _pt!.fgMuted)));
    }
    final selected = (allTabs.contains(_selectedPack) ? _selectedPack : allTabs.first)!;

    return Column(
      children: [
        SizedBox(
          height: 38,
          child: ListView.builder(
            controller: _packSelectorScroll,
            scrollDirection: Axis.horizontal,
            padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 4),
            itemCount: allTabs.length,
            itemBuilder: (context, index) {
              final tab = allTabs[index];
              final isSelected = tab == selected;
              String label = tab == _kFavsPack ? '⭐ Favoriten' : tab == _kMyPack ? '🎨 Meine' : (_packData[tab]?['title'] as String? ?? tab);
              return Padding(
                padding: const EdgeInsets.only(right: 6),
                child: GestureDetector(
                  onTap: () async {
                    setState(() => _selectedPack = tab);
                    if (tab != _kFavsPack && tab != _kMyPack) await _loadPack(tab);
                  },
                  child: Container(
                    padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 2),
                    decoration: BoxDecoration(
                      color: isSelected ? _pt!.accentSoft : Colors.transparent,
                      borderRadius: BorderRadius.circular(14),
                      border: Border.all(
                        color: isSelected ? _pt!.accent : _pt!.border,
                      ),
                    ),
                    child: Text(label,
                        style: TextStyle(
                          fontSize: 11,
                          color: isSelected ? _pt!.accent : _pt!.fgMuted,
                        )),
                  ),
                ),
              );
            },
          ),
        ),
        Container(height: 1, color: _pt!.border),
        Expanded(
          child: selected == _kFavsPack
              ? _buildStickerGrid(GifFavoriteService.stickerFavoritesItems)
              : selected == _kMyPack
                  ? _buildStickerGrid(GifFavoriteService.userStickerItems, isMyStickers: true)
                  : _buildPackGrid(selected),
        ),
      ],
    );
  }

  Widget _buildStickerGrid(List<Map<String, dynamic>> items, {bool isMyStickers = false}) {
    if (items.isEmpty) {
      return Center(child: Text('Keine Sticker', style: TextStyle(color: _pt!.fgMuted)));
    }
    return GridView.builder(
      padding: const EdgeInsets.all(4),
      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 4, crossAxisSpacing: 3, mainAxisSpacing: 3,
      ),
      itemCount: items.length,
      itemBuilder: (ctx, i) {
        final s = items[i];
        final piUrl = s['url'] as String? ?? '';
        final sendMxc = (s['mxc'] as String?)?.isNotEmpty == true
            ? s['mxc'] as String
            : (s['mxc_source'] as String? ?? '');
        final mxcSource = s['mxc_source'] as String? ?? '';
        final title = s['title'] as String? ?? 'Sticker';
        final info = {'mimetype': s['mimetype'] ?? 'image/webp'};
        final isUserSticker = s['user_sticker'] == true;

        return _StickerCell(
          piUrl: piUrl,
          isFavorited: s['favorited'] == true,
          showHeart: isMyStickers && isUserSticker,
          onTap: () => _sendSticker(sendMxc, title, info),
          onToggleFavorite: (isMyStickers && isUserSticker)
              ? () async {
                  final newFav = !(s['favorited'] == true);
                  await GifFavoriteService.setUserStickerFavorited(mxcSource, newFav);
                  if (mounted) setState(() {});
                }
              : null,
        );
      },
    );
  }

  Widget _buildPackGrid(String packId) {
    if (_packLoading) {
      return Center(child: CircularProgressIndicator(color: _pt!.accent));
    }
    final stickers = (_packData[packId]?['stickers'] as List<dynamic>?) ?? [];
    if (stickers.isEmpty) {
      return Center(child: Text('Leer', style: TextStyle(color: _pt!.fgMuted)));
    }
    return GridView.builder(
      padding: const EdgeInsets.all(4),
      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 4, crossAxisSpacing: 3, mainAxisSpacing: 3,
      ),
      itemCount: stickers.length,
      itemBuilder: (ctx, i) {
        final s = stickers[i];
        final id = s['id']?.toString() ?? '';
        final thumbUrl = '$_stickerServerUrl/packs/$packId/${id}_thumb.png';
        final mxcUrl = (s['url'] as String?) ?? '';
        final body = (s['body'] as String?) ?? '';
        final mimetype = (s['info']?['mimetype'] as String?) ?? 'image/webp';
        final info = Map<String, dynamic>.from(s['info'] as Map? ?? {});

        final isFav = GifFavoriteService.isStickerFavorite(mxcUrl);

        return GestureDetector(
          onTap: () => _sendSticker(mxcUrl, body, info),
          onLongPressStart: (details) {
            final dx = details.globalPosition.dx;
            final dy = details.globalPosition.dy;
            final screen = MediaQuery.sizeOf(context);
            showMenu<String>(
              context: context,
              position: RelativeRect.fromLTRB(
                dx, dy, screen.width - dx, screen.height - dy,
              ),
              items: [
                PopupMenuItem(
                  value: 'fav',
                  child: Row(children: [
                    Icon(
                      isFav ? Icons.favorite_border : Icons.favorite,
                      size: 16,
                      color: isFav ? _pt!.fgMuted : Colors.red,
                    ),
                    const SizedBox(width: 8),
                    Text(
                      isFav ? 'Aus Favoriten entfernen' : 'Zu Favoriten hinzufügen',
                      style: TextStyle(color: _pt!.fg, fontSize: 14),
                    ),
                  ]),
                ),
              ],
            ).then((val) async {
              if (val == 'fav') {
                await GifFavoriteService.togglePackStickerFavorite(
                  mxcUrl: mxcUrl,
                  thumbUrl: thumbUrl,
                  title: body,
                  mimetype: mimetype,
                );
                if (mounted) setState(() {});
              }
            });
          },
          child: ClipRRect(
            borderRadius: BorderRadius.circular(6),
            child: Image.network(
              thumbUrl,
              fit: BoxFit.contain,
              errorBuilder: (_, _, _) => Container(color: _pt!.bg2),
            ),
          ),
        );
      },
    );
  }
}

class _StickerCell extends StatefulWidget {
  final String piUrl;
  final bool isFavorited;
  final bool showHeart;
  final VoidCallback onTap;
  final Future<void> Function()? onToggleFavorite;

  const _StickerCell({
    required this.piUrl,
    required this.isFavorited,
    required this.showHeart,
    required this.onTap,
    this.onToggleFavorite,
  });

  @override
  State<_StickerCell> createState() => _StickerCellState();
}

class _StickerCellState extends State<_StickerCell> {
  bool _hovered = false;

  @override
  Widget build(BuildContext context) {
    final pt = PyramidTheme.of(context);
    final showOverlay = widget.showHeart && (_hovered || widget.isFavorited);

    return MouseRegion(
      onEnter: (_) => setState(() => _hovered = true),
      onExit: (_) => setState(() => _hovered = false),
      child: GestureDetector(
        onTap: widget.onTap,
        child: ClipRRect(
          borderRadius: BorderRadius.circular(6),
          child: Stack(
            fit: StackFit.expand,
            children: [
              Image.network(
                widget.piUrl,
                fit: BoxFit.contain,
                errorBuilder: (_, _, _) => Container(color: pt.bg2),
              ),
              if (showOverlay)
                Positioned(
                  top: 4,
                  right: 4,
                  child: GestureDetector(
                    onTap: widget.onToggleFavorite,
                    behavior: HitTestBehavior.opaque,
                    child: Container(
                      width: 22,
                      height: 22,
                      decoration: BoxDecoration(
                        color: Colors.black.withValues(alpha: 0.5),
                        shape: BoxShape.circle,
                      ),
                      child: Icon(
                        widget.isFavorited ? Icons.favorite : Icons.favorite_border,
                        color: widget.isFavorited ? Colors.red : Colors.white,
                        size: 13,
                      ),
                    ),
                  ),
                ),
            ],
          ),
        ),
      ),
    );
  }
}

class _SectionLabel extends StatelessWidget {
  final String title;
  const _SectionLabel(this.title);

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.fromLTRB(8, 8, 8, 4),
      child: Text(title,
          style: TextStyle(color: PyramidColors.fgDim,
              fontSize: 10,
              fontWeight: FontWeight.w700,
              letterSpacing: 0.6)),
    );
  }
}

class _GifCell extends StatelessWidget {
  final String imageUrl;
  final bool isFavorite;
  final bool isHovered;
  final ValueChanged<bool> onHoverChanged;
  final VoidCallback onTap;
  final VoidCallback onFavToggle;

  const _GifCell({
    required this.imageUrl,
    required this.isFavorite,
    required this.isHovered,
    required this.onHoverChanged,
    required this.onTap,
    required this.onFavToggle,
  });

  @override
  Widget build(BuildContext context) {
    return MouseRegion(
      onEnter: (_) => onHoverChanged(true),
      onExit: (_) => onHoverChanged(false),
      child: GestureDetector(
        onTap: onTap,
        child: ClipRRect(
          borderRadius: BorderRadius.circular(4),
          child: Stack(
            fit: StackFit.expand,
            children: [
              Image.network(imageUrl, fit: BoxFit.cover,
                errorBuilder: (_, _, _) => Container(color: PyramidTheme.of(context).bg3)),
              if (isHovered || isFavorite)
                Positioned(
                  top: 4, right: 4,
                  child: GestureDetector(
                    onTap: onFavToggle,
                    behavior: HitTestBehavior.opaque,
                    child: Container(
                      width: 22, height: 22,
                      decoration: BoxDecoration(
                        color: Colors.black.withValues(alpha: 0.5),
                        shape: BoxShape.circle,
                      ),
                      child: Icon(
                        isFavorite ? Icons.favorite : Icons.favorite_border,
                        color: isFavorite ? Colors.red : Colors.white,
                        size: 13,
                      ),
                    ),
                  ),
                ),
            ],
          ),
        ),
      ),
    );
  }
}
