import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:pyramid/core/theme.dart';
import 'package:pyramid/widgets/mxc_image.dart';

class ProfilePopover extends StatefulWidget {
  final String userId;
  final Room room;
  final Offset globalPos;
  final VoidCallback onClose;

  const ProfilePopover({
    super.key,
    required this.userId,
    required this.room,
    required this.globalPos,
    required this.onClose,
  });

  @override
  State<ProfilePopover> createState() => _ProfilePopoverState();
}

class _ProfilePopoverState extends State<ProfilePopover> {
  Profile? _profile;
  PresenceType? _presence;
  String? _bannerMxcUri;

  @override
  void initState() {
    super.initState();
    _load();
  }

  Future<void> _load() async {
    try {
      final p = await widget.room.client.getProfileFromUserId(widget.userId);
      if (mounted) setState(() => _profile = p);
    } catch (_) {}
    try {
      final p = await widget.room.client.fetchCurrentPresence(widget.userId);
      // Veraltete "online"-Presence herabstufen, wenn die letzte Aktivität
      // nicht frisch ist (Server meldet sonst dauerhaft online).
      final last = p.lastActiveTimestamp;
      final fresh = p.currentlyActive == true ||
          (last != null &&
              DateTime.now().difference(last) < const Duration(minutes: 5));
      final effective = (p.presence == PresenceType.online && !fresh)
          ? PresenceType.offline
          : p.presence;
      if (mounted) setState(() => _presence = effective);
    } catch (_) {}
    // Load banner from Matrix profile custom field (works for any user)
    try {
      final client = widget.room.client;
      final apiUri = client.homeserver!.replace(
        path: '/_matrix/client/v3/profile/${Uri.encodeComponent(widget.userId)}',
      );
      final resp = await client.httpClient.get(
        apiUri,
        headers: {'Authorization': 'Bearer ${client.accessToken}'},
      );
      if (resp.statusCode == 200) {
        final data = jsonDecode(resp.body) as Map<String, dynamic>;
        final url = data['io.pyramid.profile.banner_url'] as String?;
        if (url != null && mounted) setState(() => _bannerMxcUri = url);
      }
    } catch (_) {}
    // Legacy fallback: account data (only own user)
    if (_bannerMxcUri == null && widget.userId == widget.room.client.userID) {
      try {
        final bannerData =
            widget.room.client.accountData['com.pyramid.profile.banner'];
        final url = bannerData?.content['url'] as String?;
        if (url != null && mounted) setState(() => _bannerMxcUri = url);
      } catch (_) {}
    }
  }

  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.sizeOf(context);
    final member = widget.room.unsafeGetUserFromMemoryOrFallback(widget.userId);
    final displayName = _profile?.displayName ?? member.displayName ?? widget.userId.split(':').first.replaceAll('@', '');
    final avatarUrl = _profile?.avatarUrl ?? member.avatarUrl;
    final handle = widget.userId;
    final initials = displayName.isNotEmpty ? displayName[0].toUpperCase() : '?';
    final color = _colorForName(displayName);
    final powerLevel = widget.room.getPowerLevelByUserId(widget.userId);
    final joinDate = _formatJoinDate(widget.room, widget.userId);

    const popoverW = 300.0;
    const popoverH = 380.0;
    final left = (widget.globalPos.dx + 16).clamp(8.0, size.width - popoverW - 8);
    final top = (widget.globalPos.dy - 80).clamp(8.0, size.height - popoverH - 8);

    return Positioned(
      left: left,
      top: top,
      child: Material(
        color: Colors.transparent,
        child: Container(
          width: popoverW,
          decoration: BoxDecoration(
            color: PyramidColors.bg0,
            borderRadius: BorderRadius.circular(12),
            border: Border.all(color: PyramidColors.border),
            boxShadow: const [
              BoxShadow(color: Color(0x60000000), blurRadius: 24, offset: Offset(0, 8))
            ],
          ),
          child: ClipRRect(
            borderRadius: BorderRadius.circular(12),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                // Banner — real image for own profile, color gradient for others
                SizedBox(
                  height: 64,
                  child: _bannerMxcUri != null
                      ? MxcImage(
                          mxcUri: _bannerMxcUri!,
                          client: widget.room.client,
                          fit: BoxFit.cover,
                          width: double.infinity,
                          height: 64,
                          placeholder: Container(
                            decoration: BoxDecoration(
                              gradient: LinearGradient(
                                colors: [
                                  color.withValues(alpha: 0.6),
                                  color.withValues(alpha: 0.3)
                                ],
                                begin: Alignment.topLeft,
                                end: Alignment.bottomRight,
                              ),
                            ),
                          ),
                        )
                      : Container(
                          decoration: BoxDecoration(
                            gradient: LinearGradient(
                              colors: [
                                color.withValues(alpha: 0.6),
                                color.withValues(alpha: 0.3)
                              ],
                              begin: Alignment.topLeft,
                              end: Alignment.bottomRight,
                            ),
                          ),
                        ),
                ),
                Padding(
                  padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      // Avatar row
                      Transform.translate(
                        offset: const Offset(0, -28),
                        child: Row(
                          children: [
                            Stack(
                              clipBehavior: Clip.none,
                              children: [
                                Container(
                                  width: 56,
                                  height: 56,
                                  decoration: BoxDecoration(
                                    color: color,
                                    borderRadius: BorderRadius.circular(16),
                                    border: Border.all(color: PyramidColors.bg0, width: 3),
                                  ),
                                  clipBehavior: Clip.antiAlias,
                                  child: avatarUrl != null
                                      ? MxcImage(
                                          mxcUri: avatarUrl.toString(),
                                          client: widget.room.client,
                                          width: 56,
                                          height: 56,
                                          placeholder: Center(
                                            child: Text(initials,
                                                style: const TextStyle(
                                                    color: Colors.white,
                                                    fontSize: 22,
                                                    fontWeight: FontWeight.w700)),
                                          ),
                                        )
                                      : Center(
                                          child: Text(initials,
                                              style: const TextStyle(
                                                  color: Colors.white,
                                                  fontSize: 22,
                                                  fontWeight: FontWeight.w700))),
                                ),
                                Positioned(
                                  right: -2,
                                  bottom: -2,
                                  child: _PresenceDot(presence: _presence, size: 14),
                                ),
                              ],
                            ),
                          ],
                        ),
                      ),
                      Transform.translate(
                        offset: const Offset(0, -20),
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            Text(displayName,
                                style: const TextStyle(
                                    color: PyramidColors.fg,
                                    fontSize: 17,
                                    fontWeight: FontWeight.w700)),
                            const SizedBox(height: 2),
                            Text(handle,
                                style: const TextStyle(
                                    color: PyramidColors.fgMuted, fontSize: 12)),
                            const SizedBox(height: 12),
                            // Action buttons
                            Row(
                              children: [
                                _ProfileBtn(
                                  label: 'Nachricht',
                                  icon: Icons.send_outlined,
                                  primary: true,
                                  onTap: () {
                                    widget.onClose();
                                    // TODO: open DM
                                  },
                                ),
                                const SizedBox(width: 8),
                                _ProfileBtn(
                                  label: 'Anrufen',
                                  icon: Icons.call_outlined,
                                  onTap: () {},
                                ),
                                const SizedBox(width: 8),
                                _ProfileBtn(
                                  icon: Icons.more_vert,
                                  onTap: () {},
                                ),
                              ],
                            ),
                            if (powerLevel > 0) ...[
                              const SizedBox(height: 14),
                              const Text('Rollen',
                                  style: TextStyle(
                                      color: PyramidColors.fgDim,
                                      fontSize: 10,
                                      fontWeight: FontWeight.w700,
                                      letterSpacing: 0.8)),
                              const SizedBox(height: 6),
                              Wrap(
                                spacing: 6,
                                runSpacing: 4,
                                children: [
                                  _RoleBadge(
                                    label: powerLevel >= 100 ? 'Admin' : 'Moderator',
                                    color: powerLevel >= 100
                                        ? const Color(0xFFF59E0B)
                                        : const Color(0xFF06B6D4),
                                  ),
                                ],
                              ),
                            ],
                            if (joinDate != null) ...[
                              const SizedBox(height: 14),
                              const Text('Mitglied seit',
                                  style: TextStyle(
                                      color: PyramidColors.fgDim,
                                      fontSize: 10,
                                      fontWeight: FontWeight.w700,
                                      letterSpacing: 0.8)),
                              const SizedBox(height: 4),
                              Text(joinDate,
                                  style: const TextStyle(
                                      color: PyramidColors.fgMuted, fontSize: 12)),
                            ],
                          ],
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  String? _formatJoinDate(Room room, String userId) {
    try {
      final member = room.unsafeGetUserFromMemoryOrFallback(userId);
      // User joined if membership is join
      if (member.membership != Membership.join) return null;
      // No timestamp available from StrippedStateEvent; show server domain hint
      final server = userId.contains(':') ? userId.split(':').last : null;
      return server != null ? 'via $server' : null;
    } catch (_) {
      return null;
    }
  }

  Color _colorForName(String name) {
    const colors = [
      Color(0xFF06B6D4), Color(0xFFA855F7), Color(0xFFFF6B9D),
      Color(0xFF10B981), Color(0xFFF59E0B), Color(0xFF3B82F6),
      Color(0xFFF43F5E),
    ];
    final hash = name.codeUnits.fold(0, (a, b) => a + b);
    return colors[hash % colors.length];
  }
}

class _PresenceDot extends StatelessWidget {
  final PresenceType? presence;
  final double size;
  const _PresenceDot({required this.presence, required this.size});

  @override
  Widget build(BuildContext context) {
    final color = switch (presence) {
      PresenceType.online => const Color(0xFF23A55A),
      PresenceType.unavailable => const Color(0xFFF0B232),
      _ => const Color(0xFF7C7C8A),
    };
    return Container(
      width: size,
      height: size,
      decoration: BoxDecoration(
        color: color,
        shape: BoxShape.circle,
        border: Border.all(color: PyramidColors.bg0, width: 2),
      ),
    );
  }
}

class _ProfileBtn extends StatefulWidget {
  final String? label;
  final IconData icon;
  final bool primary;
  final VoidCallback onTap;

  const _ProfileBtn({
    required this.icon,
    required this.onTap,
    this.label,
    this.primary = false,
  });

  @override
  State<_ProfileBtn> createState() => _ProfileBtnState();
}

class _ProfileBtnState extends State<_ProfileBtn> {
  bool _hover = false;

  @override
  Widget build(BuildContext context) {
    final hasLabel = widget.label != null;
    return MouseRegion(
      onEnter: (_) => setState(() => _hover = true),
      onExit: (_) => setState(() => _hover = false),
      child: GestureDetector(
        onTap: widget.onTap,
        child: AnimatedContainer(
          duration: const Duration(milliseconds: 120),
          padding: EdgeInsets.symmetric(
              horizontal: hasLabel ? 12 : 9, vertical: 7),
          decoration: BoxDecoration(
            color: widget.primary
                ? (_hover
                    ? PyramidTheme.of(context).accent.withAlpha(200)
                    : PyramidTheme.of(context).accent)
                : (_hover ? PyramidColors.bgHover : PyramidColors.bg2),
            borderRadius: BorderRadius.circular(8),
            border: Border.all(
              color: widget.primary ? Colors.transparent : PyramidColors.border,
            ),
          ),
          child: Row(
            mainAxisSize: MainAxisSize.min,
            children: [
              Icon(widget.icon,
                  size: 14,
                  color: widget.primary
                      ? PyramidColors.accentFg
                      : PyramidColors.fg),
              if (hasLabel) ...[
                const SizedBox(width: 6),
                Text(widget.label!,
                    style: TextStyle(
                        color: widget.primary
                            ? PyramidColors.accentFg
                            : PyramidColors.fg,
                        fontSize: 13,
                        fontWeight: FontWeight.w500)),
              ],
            ],
          ),
        ),
      ),
    );
  }
}

class _RoleBadge extends StatelessWidget {
  final String label;
  final Color color;
  const _RoleBadge({required this.label, required this.color});

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3),
      decoration: BoxDecoration(
        color: color.withValues(alpha: 0.15),
        borderRadius: BorderRadius.circular(999),
        border: Border.all(color: color.withValues(alpha: 0.4)),
      ),
      child: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          Container(
              width: 6, height: 6,
              decoration: BoxDecoration(color: color, shape: BoxShape.circle)),
          const SizedBox(width: 5),
          Text(label,
              style: TextStyle(color: color, fontSize: 11, fontWeight: FontWeight.w500)),
        ],
      ),
    );
  }
}
