// Skeleton placeholder widgets for the per-item rendering architecture
// (see docs/superpowers/specs/2026-05-13-per-item-rendering-design.md).
//
// Each skeleton matches the exact dimensions of its corresponding real
// card so the layout doesn't shift when content lands. A subtle
// shimmer sweep makes the page feel alive while individual tiles
// hydrate against drift / REST in the background.
//
// Self-contained shimmer (no `shimmer` package dep) so we can keep
// pubspec lean and tune the sweep colors against FabledSword tokens.

import 'package:flutter/material.dart';

import '../../theme/theme_extension.dart';

/// Period of one full shimmer sweep across the skeleton.
const Duration _shimmerPeriod = Duration(milliseconds: 1200);

/// Wraps a child with a slow-moving highlight band on top of the
/// skeleton's base color. Cheap — uses a single AnimationController
/// per surface and a LinearGradient shader.
class _Shimmer extends StatefulWidget {
  const _Shimmer({required this.child});
  final Widget child;

  @override
  State<_Shimmer> createState() => _ShimmerState();
}

class _ShimmerState extends State<_Shimmer>
    with SingleTickerProviderStateMixin {
  late final AnimationController _ctrl = AnimationController(
    vsync: this,
    duration: _shimmerPeriod,
  )..repeat();

  @override
  void dispose() {
    _ctrl.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final fs = Theme.of(context).extension<FabledSwordTheme>()!;
    return AnimatedBuilder(
      animation: _ctrl,
      builder: (context, child) {
        return ShaderMask(
          blendMode: BlendMode.srcATop,
          shaderCallback: (rect) {
            // Sweep starts off-screen left, ends off-screen right.
            final dx = (_ctrl.value * 2 - 1) * rect.width;
            return LinearGradient(
              begin: Alignment.centerLeft,
              end: Alignment.centerRight,
              colors: [
                fs.slate,
                fs.iron,
                fs.slate,
              ],
              stops: const [0.0, 0.5, 1.0],
              transform: _SlideGradient(dx),
            ).createShader(rect);
          },
          child: child,
        );
      },
      child: widget.child,
    );
  }
}

/// Helper for translating a gradient horizontally inside its rect.
class _SlideGradient extends GradientTransform {
  const _SlideGradient(this.dx);
  final double dx;

  @override
  Matrix4 transform(Rect bounds, {TextDirection? textDirection}) {
    return Matrix4.translationValues(dx, 0, 0);
  }
}

/// Skeleton matched to AlbumCard's 140px outer width / 124px cover /
/// title + artist text rows. Used in horizontal carousels where the
/// real card lives.
class SkeletonAlbumTile extends StatelessWidget {
  const SkeletonAlbumTile({super.key, this.width = 140});
  final double width;

  @override
  Widget build(BuildContext context) {
    final fs = Theme.of(context).extension<FabledSwordTheme>()!;
    final coverSize = width - 16;
    return _Shimmer(
      child: SizedBox(
        width: width,
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 8),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            mainAxisSize: MainAxisSize.min,
            children: [
              ClipRRect(
                borderRadius: BorderRadius.circular(6),
                child: Container(
                  width: coverSize,
                  height: coverSize,
                  color: fs.slate,
                ),
              ),
              const SizedBox(height: 8),
              Container(width: coverSize * 0.8, height: 14, color: fs.slate),
              const SizedBox(height: 4),
              Container(width: coverSize * 0.6, height: 12, color: fs.slate),
            ],
          ),
        ),
      ),
    );
  }
}

/// Skeleton matched to ArtistCard's 140px / 124px round-thumb shape.
class SkeletonArtistTile extends StatelessWidget {
  const SkeletonArtistTile({super.key, this.width = 140});
  final double width;

  @override
  Widget build(BuildContext context) {
    final fs = Theme.of(context).extension<FabledSwordTheme>()!;
    final coverSize = width - 16;
    return _Shimmer(
      child: SizedBox(
        width: width,
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 8),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            mainAxisSize: MainAxisSize.min,
            children: [
              Container(
                width: coverSize,
                height: coverSize,
                decoration: BoxDecoration(
                  color: fs.slate,
                  shape: BoxShape.circle,
                ),
              ),
              const SizedBox(height: 8),
              Container(width: coverSize * 0.7, height: 14, color: fs.slate),
            ],
          ),
        ),
      ),
    );
  }
}

/// Skeleton matched to TrackRow's vertical-list layout. 56dp cover +
/// title + artist line, similar to the real row.
class SkeletonTrackRow extends StatelessWidget {
  const SkeletonTrackRow({super.key});

  @override
  Widget build(BuildContext context) {
    final fs = Theme.of(context).extension<FabledSwordTheme>()!;
    return _Shimmer(
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
        child: Row(
          children: [
            Container(
              width: 56,
              height: 56,
              decoration: BoxDecoration(
                color: fs.slate,
                borderRadius: BorderRadius.circular(6),
              ),
            ),
            const SizedBox(width: 12),
            Expanded(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                mainAxisSize: MainAxisSize.min,
                children: [
                  Container(width: 180, height: 14, color: fs.slate),
                  const SizedBox(height: 6),
                  Container(width: 120, height: 12, color: fs.slate),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}
