import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:shadcn_ui/shadcn_ui.dart';
import 'app_colors.dart';

const _pickerItemStyle = TextStyle(fontSize: 22, fontWeight: FontWeight.w500);
const _lineColor = Color(0xFFCBD5E1);

Widget _wrapPicker(Widget picker) {
  return Stack(
    children: [
      picker,
      Positioned(
        top: 0,
        bottom: 0,
        left: 0,
        right: 0,
        child: IgnorePointer(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Container(height: 1, color: _lineColor),
              const SizedBox(height: 38),
              Container(height: 1, color: _lineColor),
            ],
          ),
        ),
      ),
    ],
  );
}

Future<DateTime?> showAppDatePicker(
  BuildContext context, {
  required DateTime initialDate,
  DateTime? firstDate,
  DateTime? lastDate,
}) {
  final minDate = firstDate ?? DateTime(1900);
  final maxDate = lastDate ?? DateTime(2100);
  var y = initialDate.year.clamp(minDate.year, maxDate.year);
  var m = initialDate.month;
  var d = initialDate.day;
  final yearCtrl = FixedExtentScrollController(initialItem: y - minDate.year);
  final monthCtrl = FixedExtentScrollController(initialItem: m - 1);
  final dayCtrl = FixedExtentScrollController(initialItem: d - 1);

  int daysInMonth(int year, int month) =>
      DateTime(year, month + 1, 0).day;

  void clampDay() {
    final maxDay = daysInMonth(y, m);
    if (d > maxDay) d = maxDay;
  }

  return showCupertinoModalPopup<DateTime>(
    context: context,
    builder: (ctx) => Container(
      height: 320,
      decoration: const BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
      ),
      child: Column(
        children: [
          Container(
            padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                CupertinoButton(
                  padding: EdgeInsets.zero,
                  child: const Text('取消', style: TextStyle(fontSize: 16, color: Color(0xFF94A3B8))),
                  onPressed: () => Navigator.pop(ctx),
                ),
                CupertinoButton(
                  padding: EdgeInsets.zero,
                  child: const Text('确定', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: AppColors.primary)),
                  onPressed: () {
                    clampDay();
                    Navigator.pop(ctx, DateTime(y, m, d));
                  },
                ),
              ],
            ),
          ),
          Expanded(
            child: Row(
              children: [
                Expanded(child: _wrapPicker(CupertinoPicker(
                  selectionOverlay: null,
              scrollController: yearCtrl,
                  itemExtent: 40,
                  onSelectedItemChanged: (i) {
                    y = minDate.year + i;
                    clampDay();
                    final maxDay = daysInMonth(y, m);
                    dayCtrl.jumpTo((d - 1).clamp(0, maxDay - 1).toDouble());
                  },
                  children: [for (var i = minDate.year; i <= maxDate.year; i++) Center(child: Text('$i', style: _pickerItemStyle))],
                ))),
                Expanded(child: _wrapPicker(CupertinoPicker(
                  selectionOverlay: null,
              scrollController: monthCtrl,
                  itemExtent: 40,
                  onSelectedItemChanged: (i) {
                    m = i + 1;
                    clampDay();
                    final maxDay = daysInMonth(y, m);
                    dayCtrl.jumpTo((d - 1).clamp(0, maxDay - 1).toDouble());
                  },
                  children: [for (var i = 1; i <= 12; i++) Center(child: Text(i.toString().padLeft(2, '0'), style: _pickerItemStyle))],
                ))),
                Expanded(child: _wrapPicker(CupertinoPicker(
                  selectionOverlay: null,
              scrollController: dayCtrl,
                  itemExtent: 40,
                  onSelectedItemChanged: (i) => d = i + 1,
                  children: [for (var i = 1; i <= daysInMonth(y, m); i++) Center(child: Text(i.toString().padLeft(2, '0'), style: _pickerItemStyle))],
                ))),
              ],
            ),
          ),
        ],
      ),
    ),
  );
}

Future<TimeOfDay?> showAppTimePicker(
  BuildContext context, {
  required TimeOfDay initialTime,
}) {
  var hour = initialTime.hour;
  var minute = initialTime.minute;
  final hourCtrl = FixedExtentScrollController(initialItem: hour);
  final minuteCtrl = FixedExtentScrollController(initialItem: minute);

  return showCupertinoModalPopup<TimeOfDay>(
    context: context,
    builder: (ctx) => Container(
      height: 320,
      decoration: const BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
      ),
      child: Column(
        children: [
          Container(
            padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                CupertinoButton(
                  padding: EdgeInsets.zero,
                  child: const Text('取消', style: TextStyle(fontSize: 16, color: Color(0xFF94A3B8))),
                  onPressed: () => Navigator.pop(ctx),
                ),
                CupertinoButton(
                  padding: EdgeInsets.zero,
                  child: const Text('确定', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: AppColors.primary)),
                  onPressed: () => Navigator.pop(ctx, TimeOfDay(hour: hour, minute: minute)),
                ),
              ],
            ),
          ),
          Expanded(
            child: Row(
              children: [
                const Spacer(flex: 1),
                Expanded(flex: 2, child: _wrapPicker(CupertinoPicker(
                  selectionOverlay: null,
              scrollController: hourCtrl,
                  itemExtent: 40,
                  onSelectedItemChanged: (i) => hour = i,
                  children: [for (var i = 0; i <= 23; i++) Center(child: Text(i.toString().padLeft(2, '0'), style: _pickerItemStyle))],
                ))),
                Expanded(flex: 2, child: _wrapPicker(CupertinoPicker(
                  selectionOverlay: null,
              scrollController: minuteCtrl,
                  itemExtent: 40,
                  onSelectedItemChanged: (i) => minute = i,
                  children: [for (var i = 0; i <= 59; i++) Center(child: Text(i.toString().padLeft(2, '0'), style: _pickerItemStyle))],
                ))),
                const Spacer(flex: 1),
              ],
            ),
          ),
        ],
      ),
    ),
  );
}

Future<DateTime?> showAppDateTimePicker(
  BuildContext context, {
  required DateTime initialDate,
  DateTime? firstDate,
  DateTime? lastDate,
}) {
  final minDate = firstDate ?? DateTime(1900);
  final maxDate = lastDate ?? DateTime(2100);
  var y = initialDate.year.clamp(minDate.year, maxDate.year);
  var m = initialDate.month;
  var d = initialDate.day;
  var h = initialDate.hour;
  var min = initialDate.minute;
  final yearCtrl = FixedExtentScrollController(initialItem: y - minDate.year);
  final monthCtrl = FixedExtentScrollController(initialItem: m - 1);
  final dayCtrl = FixedExtentScrollController(initialItem: d - 1);
  final hourCtrl = FixedExtentScrollController(initialItem: h);
  final minuteCtrl = FixedExtentScrollController(initialItem: min);

  int daysInMonth(int year, int month) =>
      DateTime(year, month + 1, 0).day;

  void clampDay() {
    final maxDay = daysInMonth(y, m);
    if (d > maxDay) d = maxDay;
  }

  return showCupertinoModalPopup<DateTime>(
    context: context,
    builder: (ctx) => Container(
      height: 320,
      decoration: const BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
      ),
      child: Column(
        children: [
          Container(
            padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                CupertinoButton(
                  padding: EdgeInsets.zero,
                  child: const Text('取消', style: TextStyle(fontSize: 16, color: Color(0xFF94A3B8))),
                  onPressed: () => Navigator.pop(ctx),
                ),
                CupertinoButton(
                  padding: EdgeInsets.zero,
                  child: const Text('确定', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: AppColors.primary)),
                  onPressed: () {
                    clampDay();
                    Navigator.pop(ctx, DateTime(y, m, d, h, min));
                  },
                ),
              ],
            ),
          ),
          Expanded(
            child: Row(
              children: [
                Expanded(child: _wrapPicker(CupertinoPicker(
                  selectionOverlay: null,
              scrollController: yearCtrl,
                  itemExtent: 40,
                  onSelectedItemChanged: (i) { y = minDate.year + i; clampDay(); },
                  children: [for (var i = minDate.year; i <= maxDate.year; i++) Center(child: Text('$i', style: _pickerItemStyle))],
                ))),
                Expanded(child: _wrapPicker(CupertinoPicker(
                  selectionOverlay: null,
              scrollController: monthCtrl,
                  itemExtent: 40,
                  onSelectedItemChanged: (i) { m = i + 1; clampDay(); },
                  children: [for (var i = 1; i <= 12; i++) Center(child: Text(i.toString().padLeft(2, '0'), style: _pickerItemStyle))],
                ))),
                Expanded(child: _wrapPicker(CupertinoPicker(
                  selectionOverlay: null,
              scrollController: dayCtrl,
                  itemExtent: 40,
                  onSelectedItemChanged: (i) => d = i + 1,
                  children: [for (var i = 1; i <= daysInMonth(y, m); i++) Center(child: Text(i.toString().padLeft(2, '0'), style: _pickerItemStyle))],
                ))),
                Expanded(child: _wrapPicker(CupertinoPicker(
                  selectionOverlay: null,
              scrollController: hourCtrl,
                  itemExtent: 40,
                  onSelectedItemChanged: (i) => h = i,
                  children: [for (var i = 0; i <= 23; i++) Center(child: Text(i.toString().padLeft(2, '0'), style: _pickerItemStyle))],
                ))),
                Expanded(child: _wrapPicker(CupertinoPicker(
                  selectionOverlay: null,
              scrollController: minuteCtrl,
                  itemExtent: 40,
                  onSelectedItemChanged: (i) => min = i,
                  children: [for (var i = 0; i <= 59; i++) Center(child: Text(i.toString().padLeft(2, '0'), style: _pickerItemStyle))],
                ))),
              ],
            ),
          ),
        ],
      ),
    ),
  );
}

Future<int?> showAppCountPicker(
  BuildContext context, {
  required int initialValue,
  int min = 1,
  int max = 10,
  String label = '',
}) {
  var selected = initialValue;
  return showCupertinoModalPopup<int>(
    context: context,
    builder: (ctx) => Container(
      height: 320,
      decoration: const BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
      ),
      child: Column(
        children: [
          Container(
            padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                CupertinoButton(
                  padding: EdgeInsets.zero,
                  child: const Text('取消', style: TextStyle(fontSize: 16, color: Color(0xFF94A3B8))),
                  onPressed: () => Navigator.pop(ctx),
                ),
                CupertinoButton(
                  padding: EdgeInsets.zero,
                  child: const Text('确定', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: AppColors.primary)),
                  onPressed: () => Navigator.pop(ctx, selected),
                ),
              ],
            ),
          ),
          Expanded(
            child: _wrapPicker(CupertinoPicker(
              selectionOverlay: null,
              scrollController: FixedExtentScrollController(initialItem: selected - min),
              itemExtent: 40,
              onSelectedItemChanged: (i) => selected = i + min,
              children: [
                for (var i = min; i <= max; i++)
                  Center(child: Text(label.isEmpty ? '$i' : '$i$label', style: _pickerItemStyle)),
              ],
            )),
          ),
        ],
      ),
    ),
  );
}

class AppBackground extends StatelessWidget {
  final Widget child;
  final bool safeArea;

  const AppBackground({super.key, required this.child, this.safeArea = false});

  @override
  Widget build(BuildContext context) {
    final content = safeArea ? SafeArea(child: child) : child;

    return DecoratedBox(
      decoration: const BoxDecoration(gradient: AppColors.bgGradient),
      child: content,
    );
  }
}

class GradientScaffold extends StatelessWidget {
  final PreferredSizeWidget? appBar;
  final Widget? body;
  final Widget? floatingActionButton;
  final Widget? drawer;
  final Widget? bottomNavigationBar;
  final bool extendBody;

  const GradientScaffold({
    super.key,
    this.appBar,
    this.body,
    this.floatingActionButton,
    this.drawer,
    this.bottomNavigationBar,
    this.extendBody = false,
  });

  @override
  Widget build(BuildContext context) => AppBackground(
    child: Scaffold(
      backgroundColor: Colors.transparent,
      appBar: appBar,
      body: body,
      floatingActionButton: floatingActionButton,
      drawer: drawer,
      bottomNavigationBar: bottomNavigationBar,
      extendBody: extendBody,
    ),
  );
}

class AppTheme {
  AppTheme._();

  static const Color primary = AppColors.primary;
  static const Color primaryLight = AppColors.primaryLight;
  static const Color primaryDark = AppColors.primaryDark;
  static const Color primaryMid = AppColors.blueMeasure;
  static const Color accent = AppColors.success;
  static const Color info = AppColors.blueMeasure;

  static const Color bg = AppColors.background;
  static const Color bgSoft = AppColors.backgroundSoft;
  static const Color surface = AppColors.cardBackground;
  static const Color surfaceInner = AppColors.cardInner;
  static const Color text = AppColors.textPrimary;
  static const Color textSub = AppColors.textSecondary;
  static const Color textHint = AppColors.textHint;
  static const Color border = AppColors.border;
  static const Color divider = AppColors.divider;

  static const Color success = AppColors.success;
  static const Color successLight = AppColors.successLight;
  static const Color error = AppColors.error;
  static const Color errorLight = AppColors.errorLight;
  static const Color warning = AppColors.warning;
  static const Color warningLight = AppColors.warningLight;

  static const double rXs = 4;
  static const double rSm = 8;
  static const double rMd = 12;
  static const double rLg = 16;
  static const double rXl = 20;
  static const double rPill = 999;

  static const double sXs = 4;
  static const double sSm = 8;
  static const double sMd = 12;
  static const double sLg = 16;
  static const double sXl = 20;
  static const double sXxl = 24;

  static BoxShadow get shadowCard => BoxShadow(
    color: const Color(0xFF101828).withValues(alpha: 0.07),
    blurRadius: 22,
    offset: const Offset(0, 10),
  );

  static BoxShadow get shadowLight => BoxShadow(
    color: const Color(0xFF101828).withValues(alpha: 0.045),
    blurRadius: 14,
    offset: const Offset(0, 6),
  );

  static BoxShadow get shadowElevated => BoxShadow(
    color: primary.withValues(alpha: 0.12),
    blurRadius: 18,
    offset: const Offset(0, 8),
  );

  static BoxShadow get shadowButton => BoxShadow(
    color: primary.withValues(alpha: 0.22),
    blurRadius: 16,
    offset: const Offset(0, 8),
  );

  static const Map<String, Color> agentColors = {
    'default': Color(0xFFF3F0FF),
    'consultation': Color(0xFFEFF5FF),
    'health': Color(0xFFF3F0FF),
    'diet': Color(0xFFFFF7E6),
    'medication': Color(0xFFEFF5FF),
    'report': Color(0xFFF6F3FF),
    'exercise': Color(0xFFEFF8FF),
  };

  static Color agentLight(String? name) => agentColors[name] ?? primaryLight;

  static ThemeData get lightTheme => ThemeData(
    useMaterial3: true,
    colorScheme: ColorScheme.fromSeed(
      seedColor: primary,
      primary: primary,
      primaryContainer: primaryLight,
      onPrimary: Colors.white,
      secondary: AppColors.blueMeasure,
      surface: surface,
      brightness: Brightness.light,
    ),
    scaffoldBackgroundColor: Colors.transparent,
    splashColor: primary.withValues(alpha: 0.06),
    highlightColor: Colors.transparent,
    hoverColor: primaryLight.withValues(alpha: 0.55),
    fontFamily: null,

    appBarTheme: AppBarTheme(
      backgroundColor: Colors.white.withValues(alpha: 0.9),
      foregroundColor: text,
      elevation: 0,
      centerTitle: true,
      scrolledUnderElevation: 0,
      surfaceTintColor: Colors.transparent,
      titleTextStyle: const TextStyle(
        fontSize: 17,
        fontWeight: FontWeight.w700,
        color: text,
      ),
      toolbarHeight: 52,
    ),

    cardTheme: CardThemeData(
      color: Colors.white,
      elevation: 0,
      surfaceTintColor: Colors.transparent,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(rLg),
        side: const BorderSide(color: AppColors.borderLight),
      ),
      margin: EdgeInsets.zero,
    ),

    inputDecorationTheme: InputDecorationTheme(
      filled: true,
      fillColor: Colors.white,
      contentPadding: const EdgeInsets.symmetric(horizontal: sLg, vertical: 13),
      border: OutlineInputBorder(
        borderRadius: BorderRadius.circular(rMd),
        borderSide: const BorderSide(color: AppColors.borderLight),
      ),
      enabledBorder: OutlineInputBorder(
        borderRadius: BorderRadius.circular(rMd),
        borderSide: const BorderSide(color: AppColors.borderLight),
      ),
      focusedBorder: OutlineInputBorder(
        borderRadius: BorderRadius.circular(rMd),
        borderSide: const BorderSide(color: AppColors.auraIndigo, width: 1.3),
      ),
      errorBorder: OutlineInputBorder(
        borderRadius: BorderRadius.circular(rMd),
        borderSide: const BorderSide(color: error),
      ),
      hintStyle: const TextStyle(color: textHint, fontSize: 15),
    ),

    elevatedButtonTheme: ElevatedButtonThemeData(
      style: ElevatedButton.styleFrom(
        backgroundColor: primary,
        foregroundColor: Colors.white,
        minimumSize: const Size(double.infinity, 50),
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(rLg)),
        textStyle: const TextStyle(fontSize: 16, fontWeight: FontWeight.w700),
        elevation: 0,
      ),
    ),

    outlinedButtonTheme: OutlinedButtonThemeData(
      style: OutlinedButton.styleFrom(
        foregroundColor: text,
        side: const BorderSide(color: border),
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(rMd)),
        textStyle: const TextStyle(fontSize: 15, fontWeight: FontWeight.w600),
      ),
    ),

    dialogTheme: DialogThemeData(
      backgroundColor: surface,
      surfaceTintColor: Colors.transparent,
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(rLg)),
    ),

    textTheme: const TextTheme(
      headlineLarge: TextStyle(
        fontSize: 24,
        fontWeight: FontWeight.w800,
        color: text,
      ),
      titleLarge: TextStyle(
        fontSize: 18,
        fontWeight: FontWeight.w700,
        color: text,
      ),
      titleMedium: TextStyle(
        fontSize: 16,
        fontWeight: FontWeight.w600,
        color: text,
      ),
      bodyLarge: TextStyle(fontSize: 15, color: text, height: 1.5),
      bodyMedium: TextStyle(fontSize: 13, color: textSub, height: 1.4),
      labelMedium: TextStyle(fontSize: 13, color: textSub),
      labelSmall: TextStyle(fontSize: 12, color: textHint),
    ),
  );

  static ShadThemeData get shadTheme => ShadThemeData(
    brightness: Brightness.light,
    colorScheme: ShadVioletColorScheme.light(
      background: bg,
      foreground: text,
      card: surface,
      cardForeground: text,
      popover: surface,
      popoverForeground: text,
      primary: primary,
      primaryForeground: Colors.white,
      secondary: primaryLight,
      secondaryForeground: primaryDark,
      muted: bgSoft,
      mutedForeground: textSub,
      accent: AppColors.blueMeasure,
      accentForeground: Colors.white,
      destructive: error,
      destructiveForeground: Colors.white,
      border: border,
      input: border,
      ring: primary,
      selection: primaryLight,
    ),
    radius: BorderRadius.circular(rMd),
  );
}
