import 'dart:math' as math;

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

import '../../../core/utils/haptics.dart';
import '../../../models/story.dart';
import '../../widgets/komet_avatar.dart';
import 'story_owner_info.dart';

class StoryAvatarRing extends StatelessWidget {
  final double diameter;
  final int total;
  final int read;
  final double strokeWidth;
  final double ringGap;
  final double haloWidth;
  final Widget child;

  const StoryAvatarRing({
    super.key,
    required this.diameter,
    required this.child,
    this.total = 0,
    this.read = 0,
    this.strokeWidth = 2.8,
    this.ringGap = 6,
    this.haloWidth = 2,
  });

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    final outer = diameter + ringGap * 2;
    final visible = total > 0;
    return SizedBox(
      width: outer,
      height: outer,
      child: Stack(
        alignment: Alignment.center,
        children: [
          CustomPaint(
            size: Size.square(outer),
            painter: visible
                ? SegmentedRingPainter(
                    total: total,
                    read: read,
                    unreadColors: [cs.primary, cs.tertiary, cs.primary],
                    readColor: cs.outlineVariant,
                    strokeWidth: strokeWidth,
                  )
                : null,
          ),
          Container(
            width: diameter + haloWidth * 2,
            height: diameter + haloWidth * 2,
            decoration: BoxDecoration(
              shape: BoxShape.circle,
              color: visible ? cs.surface : Colors.transparent,
            ),
          ),
          child,
        ],
      ),
    );
  }
}

/// Кольцо-превью истории владельца в шапке списка чатов.
class StoryRing extends StatefulWidget {
  final StoryPreview preview;
  final StoryOwnerInfo? ownerOverride;
  final String? selfLabel;
  final void Function(Offset? center) onTap;
  final double avatarRadius;

  const StoryRing({
    super.key,
    required this.preview,
    required this.onTap,
    this.ownerOverride,
    this.selfLabel,
    this.avatarRadius = 26,
  });

  @override
  State<StoryRing> createState() => _StoryRingState();
}

class _StoryRingState extends State<StoryRing> {
  bool _pressed = false;

  void _handleTap() {
    Haptics.tap();
    Offset? center;
    final box = context.findRenderObject() as RenderBox?;
    if (box != null && box.hasSize) {
      center = box.localToGlobal(box.size.center(Offset.zero));
    }
    widget.onTap(center);
  }

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    final hasUnread = widget.preview.hasUnread;
    final diameter = widget.avatarRadius * 2;

    return StoryOwnerBuilder(
      owner: widget.preview.owner,
      overrideInfo: widget.ownerOverride,
      builder: (context, info) {
        final name = widget.selfLabel ??
            (info?.name.isNotEmpty == true ? info!.name : '…');
        return Padding(
          padding: const EdgeInsets.only(right: 16),
          child: SizedBox(
            width: 68,
            child: GestureDetector(
              behavior: HitTestBehavior.opaque,
              onTap: _handleTap,
              onTapDown: (_) => setState(() => _pressed = true),
              onTapUp: (_) => setState(() => _pressed = false),
              onTapCancel: () => setState(() => _pressed = false),
              child: AnimatedScale(
                scale: _pressed ? 0.9 : 1.0,
                duration: const Duration(milliseconds: 120),
                curve: Curves.easeOut,
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    StoryAvatarRing(
                      diameter: diameter,
                      total: widget.preview.totalCount,
                      read: widget.preview.readCount,
                      child: KometAvatar(
                        name: name == '…' ? '?' : name,
                        size: diameter,
                        imageUrl: info?.avatarUrl,
                      ),
                    ),
                    const SizedBox(height: 6),
                    Text(
                      name,
                      maxLines: 1,
                      overflow: TextOverflow.ellipsis,
                      style: TextStyle(
                        color: cs.onSurface,
                        fontSize: 11,
                        fontWeight: hasUnread
                            ? FontWeight.w600
                            : FontWeight.w500,
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        );
      },
    );
  }
}

/// Прерывистое кольцо: одна дуга на каждую историю; прочитанные приглушены.
class SegmentedRingPainter extends CustomPainter {
  final int total;
  final int read;
  final List<Color> unreadColors;
  final Color readColor;
  final double strokeWidth;

  SegmentedRingPainter({
    required this.total,
    required this.read,
    required this.unreadColors,
    required this.readColor,
    required this.strokeWidth,
  });

  @override
  void paint(Canvas canvas, Size size) {
    final n = total < 1 ? 1 : total;
    final rect = Rect.fromLTWH(
      strokeWidth / 2,
      strokeWidth / 2,
      size.width - strokeWidth,
      size.height - strokeWidth,
    );

    final segment = (2 * math.pi) / n;
    final gap = n == 1 ? 0.0 : math.min(0.16, segment * 0.30);
    final sweep = segment - gap;

    final unreadPaint = Paint()
      ..style = PaintingStyle.stroke
      ..strokeWidth = strokeWidth
      ..strokeCap = n == 1 ? StrokeCap.butt : StrokeCap.round
      ..shader = SweepGradient(
        startAngle: 0,
        endAngle: 2 * math.pi,
        colors: [...unreadColors, unreadColors.first],
        transform: const GradientRotation(-math.pi / 2),
      ).createShader(rect);

    final readPaint = Paint()
      ..style = PaintingStyle.stroke
      ..strokeWidth = strokeWidth
      ..strokeCap = n == 1 ? StrokeCap.butt : StrokeCap.round
      ..color = readColor;

    for (var i = 0; i < n; i++) {
      final start = -math.pi / 2 + gap / 2 + i * segment;
      canvas.drawArc(rect, start, sweep, false, i < read ? readPaint : unreadPaint);
    }
  }

  @override
  bool shouldRepaint(SegmentedRingPainter old) =>
      old.total != total ||
      old.read != read ||
      old.readColor != readColor ||
      old.strokeWidth != strokeWidth ||
      !listEquals(old.unreadColors, unreadColors);
}

/// Ведущая плитка «Ваша история»: показывает своё кольцо (если истории есть)
/// и всегда — бейдж «+» для публикации. Тап по кольцу открывает свои истории,
/// тап по «+» — композер. Если своих историй нет — вся плитка ведёт в композер.
class StorySelfTile extends StatefulWidget {
  final StoryPreview? preview;
  final StoryOwnerInfo? selfInfo;
  final void Function(Offset? center) onOpen;
  final VoidCallback onAdd;
  final double avatarRadius;

  const StorySelfTile({
    super.key,
    required this.onOpen,
    required this.onAdd,
    this.preview,
    this.selfInfo,
    this.avatarRadius = 26,
  });

  @override
  State<StorySelfTile> createState() => _StorySelfTileState();
}

class _StorySelfTileState extends State<StorySelfTile> {
  bool _pressed = false;

  bool get _hasStories => widget.preview != null;

  void _handleTap() {
    Haptics.tap();
    if (!_hasStories) {
      widget.onAdd();
      return;
    }
    Offset? center;
    final box = context.findRenderObject() as RenderBox?;
    if (box != null && box.hasSize) {
      center = box.localToGlobal(box.size.center(Offset.zero));
    }
    widget.onOpen(center);
  }

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    final diameter = widget.avatarRadius * 2;
    final preview = widget.preview;

    return Padding(
      padding: const EdgeInsets.only(right: 16),
      child: SizedBox(
        width: 68,
        child: GestureDetector(
          behavior: HitTestBehavior.opaque,
          onTap: _handleTap,
          onTapDown: (_) => setState(() => _pressed = true),
          onTapUp: (_) => setState(() => _pressed = false),
          onTapCancel: () => setState(() => _pressed = false),
          child: AnimatedScale(
            scale: _pressed ? 0.9 : 1.0,
            duration: const Duration(milliseconds: 120),
            curve: Curves.easeOut,
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                SizedBox(
                  width: diameter + 12,
                  height: diameter + 12,
                  child: Stack(
                    alignment: Alignment.center,
                    children: [
                      if (preview != null)
                        CustomPaint(
                          size: Size.square(diameter + 12),
                          painter: SegmentedRingPainter(
                            total: preview.totalCount,
                            read: preview.readCount,
                            unreadColors: [cs.primary, cs.tertiary, cs.primary],
                            readColor: cs.outlineVariant,
                            strokeWidth: 2.8,
                          ),
                        )
                      else
                        Container(
                          width: diameter + 6,
                          height: diameter + 6,
                          decoration: BoxDecoration(
                            shape: BoxShape.circle,
                            border: Border.all(
                              color: cs.outlineVariant,
                              width: 2,
                            ),
                          ),
                        ),
                      Container(
                        width: diameter + 4,
                        height: diameter + 4,
                        decoration: BoxDecoration(
                          shape: BoxShape.circle,
                          color: cs.surface,
                        ),
                      ),
                      KometAvatar(
                        name: widget.selfInfo?.name.isNotEmpty == true
                            ? widget.selfInfo!.name
                            : '+',
                        size: diameter,
                        imageUrl: widget.selfInfo?.avatarUrl,
                      ),
                      Positioned(
                        right: 1,
                        bottom: 1,
                        child: GestureDetector(
                          behavior: HitTestBehavior.opaque,
                          onTap: () {
                            Haptics.tap();
                            widget.onAdd();
                          },
                          child: Container(
                            padding: const EdgeInsets.all(2),
                            decoration: BoxDecoration(
                              shape: BoxShape.circle,
                              color: cs.surface,
                            ),
                            child: Container(
                              decoration: BoxDecoration(
                                shape: BoxShape.circle,
                                color: cs.primary,
                              ),
                              child: Icon(
                                Icons.add,
                                size: 14,
                                color: cs.onPrimary,
                              ),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
                const SizedBox(height: 6),
                Text(
                  'Ваша история',
                  maxLines: 1,
                  overflow: TextOverflow.ellipsis,
                  style: TextStyle(
                    color: cs.onSurface,
                    fontSize: 11,
                    fontWeight: FontWeight.w500,
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

/// Свёрнутая мини-стопка колец, показывается в заголовке при закрытом доке.
class FoldedStoryStack extends StatelessWidget {
  static const int maxShown = 3;
  static const double avatarSize = 28;
  static const double _rim = 1.5;
  static const double _gap = 1.5;
  static const double step = 14;

  static const double outerSize = avatarSize + (_rim + _gap) * 2;

  static double widthFor(int count) {
    final shown = count > maxShown ? maxShown : (count < 1 ? 1 : count);
    return outerSize + step * (shown - 1);
  }

  final List<StoryPreview> previews;
  final double opacity;

  const FoldedStoryStack({
    super.key,
    required this.previews,
    this.opacity = 1.0,
  });

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    final shown = previews.take(maxShown).toList();
    return Opacity(
      opacity: opacity.clamp(0.0, 1.0),
      child: SizedBox(
        height: outerSize,
        width: widthFor(shown.length),
        child: Stack(
          clipBehavior: Clip.none,
          children: [
            for (var i = 0; i < shown.length; i++)
              Positioned(
                left: i * step,
                top: 0,
                child: StoryOwnerBuilder(
                  owner: shown[i].owner,
                  builder: (context, info) => Container(
                    padding: const EdgeInsets.all(_gap),
                    decoration: BoxDecoration(
                      shape: BoxShape.circle,
                      color: cs.surface,
                      border: Border.all(
                        color: shown[i].hasUnread
                            ? cs.primary
                            : cs.outlineVariant,
                        width: _rim,
                      ),
                    ),
                    child: KometAvatar(
                      name: info?.name.isNotEmpty == true ? info!.name : '?',
                      size: avatarSize,
                      imageUrl: info?.avatarUrl,
                    ),
                  ),
                ),
              ),
          ],
        ),
      ),
    );
  }
}
