import 'package:flutter/material.dart';
import 'package:shadcn_ui/shadcn_ui.dart';
import 'package:shimmer/shimmer.dart';

import '../theme/spacing.dart';

class SkeletonLineCard extends StatelessWidget {
  const SkeletonLineCard({
    super.key,
    this.lineWidths = const [0.4, 1, 0.8, 0.6],
    this.height,
  });

  final List<double> lineWidths;
  final double? height;

  @override
  Widget build(BuildContext context) {
    final cs = ShadTheme.of(context).colorScheme;
    return Container(
      height: height,
      width: double.infinity,
      padding: const EdgeInsets.all(Spacing.cardPadding),
      decoration: BoxDecoration(
        color: cs.card,
        border: Border.all(color: cs.border, width: 1),
        borderRadius: BorderRadius.circular(Spacing.radiusCard),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          for (var i = 0; i < lineWidths.length; i++) ...[
            _SkeletonLine(widthFactor: lineWidths[i]),
            if (i != lineWidths.length - 1) const SizedBox(height: 10),
          ],
        ],
      ),
    );
  }
}

class SkeletonInstitutionCard extends StatelessWidget {
  const SkeletonInstitutionCard({super.key});

  @override
  Widget build(BuildContext context) {
    return const SkeletonLineCard(lineWidths: [0.4, 1, 0.6]);
  }
}

class SkeletonListenCard extends StatelessWidget {
  const SkeletonListenCard({super.key});

  @override
  Widget build(BuildContext context) {
    return const SkeletonLineCard(lineWidths: [0.4, 1, 0.6]);
  }
}

class SkeletonSectionCard extends StatelessWidget {
  const SkeletonSectionCard({
    super.key,
    required this.roman,
    required this.lineWidths,
    this.baseColor,
    this.highlightColor,
  });

  final String roman;
  final List<double> lineWidths;
  final Color? baseColor;
  final Color? highlightColor;

  @override
  Widget build(BuildContext context) {
    final cs = ShadTheme.of(context).colorScheme;
    final brightness = ShadTheme.of(context).brightness;
    final resolvedBaseColor =
        baseColor ??
        (brightness == Brightness.dark
            ? cs.secondary
            : cs.border.withValues(alpha: 0.95));
    final resolvedHighlightColor =
        highlightColor ??
        (brightness == Brightness.dark
            ? cs.card
            : cs.secondary.withValues(alpha: 0.95));
    return Container(
      width: double.infinity,
      padding: const EdgeInsets.symmetric(
        horizontal: Spacing.cardPadding,
        vertical: 16,
      ),
      decoration: BoxDecoration(
        color: cs.card,
        border: Border.all(color: cs.border, width: 1),
        borderRadius: BorderRadius.circular(Spacing.radiusCard),
      ),
      child: Shimmer.fromColors(
        baseColor: resolvedBaseColor,
        highlightColor: resolvedHighlightColor,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            for (var i = 0; i < lineWidths.length; i++) ...[
              _SkeletonLine(
                widthFactor: lineWidths[i],
                height: i == 0 ? 14 : 12,
              ),
              if (i != lineWidths.length - 1) const SizedBox(height: 10),
            ],
            const SizedBox(height: 2),
          ],
        ),
      ),
    );
  }
}

class _SkeletonLine extends StatelessWidget {
  const _SkeletonLine({required this.widthFactor, this.height = 12});

  final double widthFactor;
  final double height;

  @override
  Widget build(BuildContext context) {
    final cs = ShadTheme.of(context).colorScheme;
    return FractionallySizedBox(
      widthFactor: widthFactor,
      child: Shimmer.fromColors(
        baseColor: cs.secondary,
        highlightColor: cs.muted,
        child: Container(
          height: height,
          decoration: BoxDecoration(
            color: cs.secondary,
            borderRadius: BorderRadius.circular(6),
          ),
        ),
      ),
    );
  }
}

class SectionSkeletonList extends StatelessWidget {
  const SectionSkeletonList({
    super.key,
    required this.count,
    required this.lineWidthsForIndex,
    this.romanLabels,
  });

  final int count;
  final List<double> Function(int index) lineWidthsForIndex;
  final List<String>? romanLabels;

  @override
  Widget build(BuildContext context) {
    final labels =
        romanLabels ??
        List<String>.generate(count, (index) => _roman(index + 1));
    return SliverPadding(
      padding: const EdgeInsets.fromLTRB(Spacing.page, 4, Spacing.page, 24),
      sliver: SliverList.separated(
        itemCount: count,
        separatorBuilder: (_, _) => const SizedBox(height: Spacing.cardGap),
        itemBuilder: (context, index) => SkeletonSectionCard(
          roman: labels[index],
          lineWidths: lineWidthsForIndex(index),
        ),
      ),
    );
  }
}

class SectionSkeletonListView extends StatelessWidget {
  const SectionSkeletonListView({
    super.key,
    required this.count,
    required this.lineWidthsForIndex,
    this.romanLabels,
  });

  final int count;
  final List<double> Function(int index) lineWidthsForIndex;
  final List<String>? romanLabels;

  @override
  Widget build(BuildContext context) {
    final labels =
        romanLabels ??
        List<String>.generate(count, (index) => _roman(index + 1));
    return ListView.separated(
      padding: const EdgeInsets.only(bottom: 72),
      itemCount: count,
      separatorBuilder: (_, _) => const SizedBox(height: Spacing.cardGap),
      itemBuilder: (context, index) => SkeletonSectionCard(
        roman: labels[index],
        lineWidths: lineWidthsForIndex(index),
      ),
    );
  }
}

String _roman(int value) {
  const numerals = ['I.', 'II.', 'III.', 'IV.', 'V.', 'VI.', 'VII.', 'VIII.'];
  if (value <= 0 || value > numerals.length) return '$value.';
  return numerals[value - 1];
}
