import 'dart:async';
import 'dart:io' show Platform;
import 'dart:math' as math;
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_qiblah/flutter_qiblah.dart';
import 'package:geolocator/geolocator.dart';
import '../../../app/icons/app_icons.dart';
import '../../../app/theme/app_colors.dart';
import '../../../data/services/unsplash_service.dart';

class QiblaScreen extends ConsumerStatefulWidget {
  const QiblaScreen({super.key});

  @override
  ConsumerState<QiblaScreen> createState() => _QiblaScreenState();
}

class _QiblaScreenState extends ConsumerState<QiblaScreen> {
  static const _geomagneticChannel =
      MethodChannel('com.jamshalat.app/geomagnetic');
  static const double _alignmentThreshold = 3.0;

  // Fallback simulated data for environments without compass hardware (like macOS emulator)
  double _qiblaAngle = 295.0; // Default Jakarta to Mecca
  Map<String, String>? _unsplashPhoto;
  late Future<_QiblaBootstrapState> _bootstrapFuture;
  StreamSubscription<Position>? _positionSubscription;
  bool _isLiveTrackingActive = false;
  bool _isDeclinationSyncInProgress = false;
  double? _magneticDeclination;
  DateTime? _lastDeclinationSyncAt;
  Position? _lastDeclinationPosition;
  double? _lastHeading;
  double _smoothedHeadingDelta = 0;
  int _headingSamples = 0;

  Future<_QiblaBootstrapState> _checkDeviceSupport() async {
    final isMobile = Platform.isAndroid || Platform.isIOS;
    if (!isMobile) {
      return const _QiblaBootstrapState(_QiblaMode.simulated);
    }

    final hasSensorSupport = await FlutterQiblah.androidDeviceSensorSupport();
    if (hasSensorSupport != true) {
      return const _QiblaBootstrapState(_QiblaMode.simulated);
    }

    final locationStatus = await FlutterQiblah.checkLocationStatus();
    if (!locationStatus.enabled) {
      return const _QiblaBootstrapState(_QiblaMode.locationDisabled);
    }

    var permission = locationStatus.status;
    if (permission == LocationPermission.denied) {
      permission = await FlutterQiblah.requestPermissions();
    }

    if (permission == LocationPermission.denied) {
      return const _QiblaBootstrapState(_QiblaMode.permissionDenied);
    }
    if (permission == LocationPermission.deniedForever) {
      return const _QiblaBootstrapState(_QiblaMode.permissionDeniedForever);
    }

    return const _QiblaBootstrapState(_QiblaMode.live);
  }

  @override
  void initState() {
    super.initState();
    _bootstrapFuture = _checkDeviceSupport();
    // Pre-calculate static fallback
    _calculateStaticQibla();
    _loadUnsplashPhoto();
  }

  Future<void> _loadUnsplashPhoto() async {
    final photo = await UnsplashService.instance.getIslamicPhoto();
    if (!mounted || photo == null) return;
    setState(() => _unsplashPhoto = photo);
  }

  @override
  void dispose() {
    _stopLiveTracking();
    FlutterQiblah().dispose();
    super.dispose();
  }

  void _retryBootstrap() {
    _stopLiveTracking();
    _isLiveTrackingActive = false;
    _magneticDeclination = null;
    _lastDeclinationSyncAt = null;
    _lastDeclinationPosition = null;
    _isDeclinationSyncInProgress = false;
    _lastHeading = null;
    _smoothedHeadingDelta = 0;
    _headingSamples = 0;
    setState(() {
      _bootstrapFuture = _checkDeviceSupport();
    });
  }

  void _calculateStaticQibla() {
    // Default to Jakarta coordinates
    _qiblaAngle = _calculateQiblaBearing(
      latitude: -6.2088,
      longitude: 106.8456,
    );
  }

  double _normalizeAngle(double angle) => (angle % 360 + 360) % 360;

  double _alignmentDelta(double bearing) {
    return _shortestAngleDelta(_normalizeAngle(bearing), 0);
  }

  double _calculateQiblaBearing({
    required double latitude,
    required double longitude,
  }) {
    const meccaLat = 21.422487;
    const meccaLon = 39.826206;
    final lat1 = latitude * (math.pi / 180);
    const lat2 = meccaLat * (math.pi / 180);
    final dLon = (meccaLon - longitude) * (math.pi / 180);

    final y = math.sin(dLon) * math.cos(lat2);
    final x = math.cos(lat1) * math.sin(lat2) -
        math.sin(lat1) * math.cos(lat2) * math.cos(dLon);
    return _normalizeAngle(math.atan2(y, x) * (180 / math.pi));
  }

  void _ensureLiveTracking() {
    if (_isLiveTrackingActive) return;
    _isLiveTrackingActive = true;
    unawaited(_startLiveTracking());
  }

  void _stopLiveTracking() {
    _positionSubscription?.cancel();
    _positionSubscription = null;
  }

  Future<void> _startLiveTracking() async {
    try {
      final initialPosition = await Geolocator.getCurrentPosition(
        locationSettings: const LocationSettings(
          accuracy: LocationAccuracy.best,
        ),
      );
      await _processPositionUpdate(initialPosition);
    } catch (_) {
      // Keep existing fallback bearing when location isn't ready.
    }

    const settings = LocationSettings(
      accuracy: LocationAccuracy.bestForNavigation,
      distanceFilter: 10,
    );
    _positionSubscription = Geolocator.getPositionStream(
      locationSettings: settings,
    ).listen(
      (position) => unawaited(_processPositionUpdate(position)),
      onError: (_) {
        // Keep latest known values when location stream errors.
      },
    );
  }

  bool _shouldRefreshDeclination(Position position) {
    if (!Platform.isAndroid) return false;
    if (_lastDeclinationSyncAt == null || _lastDeclinationPosition == null) {
      return true;
    }

    final movedMeters = Geolocator.distanceBetween(
      _lastDeclinationPosition!.latitude,
      _lastDeclinationPosition!.longitude,
      position.latitude,
      position.longitude,
    );
    final minutesSinceLastSync =
        DateTime.now().difference(_lastDeclinationSyncAt!).inMinutes;
    return movedMeters >= 500 || minutesSinceLastSync >= 60;
  }

  Future<void> _processPositionUpdate(Position position) async {
    final nextBearing = _calculateQiblaBearing(
      latitude: position.latitude,
      longitude: position.longitude,
    );

    var shouldRebuild = false;
    if ((nextBearing - _qiblaAngle).abs() > 0.02) {
      _qiblaAngle = nextBearing;
      shouldRebuild = true;
    }

    if (_shouldRefreshDeclination(position) &&
        !_isDeclinationSyncInProgress &&
        mounted) {
      _isDeclinationSyncInProgress = true;
      try {
        final declination = await _geomagneticChannel.invokeMethod<double>(
          'getDeclination',
          <String, dynamic>{
            'latitude': position.latitude,
            'longitude': position.longitude,
            'altitude': position.altitude,
            'timestamp': DateTime.now().millisecondsSinceEpoch,
          },
        );
        if (declination != null) {
          _magneticDeclination = declination;
          _lastDeclinationSyncAt = DateTime.now();
          _lastDeclinationPosition = position;
          shouldRebuild = true;
        }
      } catch (_) {
        // Fall back to raw magnetic heading if declination API isn't available.
      } finally {
        _isDeclinationSyncInProgress = false;
      }
    }

    if (shouldRebuild && mounted) {
      setState(() {});
    }
  }

  String _directionForAngle(double angle) {
    final normalized = _normalizeAngle(angle);

    if (normalized >= 337.5 || normalized < 22.5) {
      return 'N';
    } else if (normalized < 67.5) {
      return 'NE';
    } else if (normalized < 112.5) {
      return 'E';
    } else if (normalized < 157.5) {
      return 'SE';
    } else if (normalized < 202.5) {
      return 'S';
    } else if (normalized < 247.5) {
      return 'SW';
    } else if (normalized < 292.5) {
      return 'W';
    } else {
      return 'NW';
    }
  }

  double _shortestAngleDelta(double a, double b) {
    final raw = (a - b).abs();
    return raw > 180 ? 360 - raw : raw;
  }

  _CalibrationQuality _assessCalibration(double heading) {
    if (_lastHeading == null) {
      _lastHeading = heading;
      _headingSamples = 1;
      return _CalibrationQuality.initializing;
    }

    final delta = _shortestAngleDelta(heading, _lastHeading!);
    _smoothedHeadingDelta = _headingSamples == 1
        ? delta
        : (_smoothedHeadingDelta * 0.8) + (delta * 0.2);
    _lastHeading = heading;
    _headingSamples += 1;

    if (_headingSamples < 8) return _CalibrationQuality.initializing;
    if (_smoothedHeadingDelta <= 1.2) return _CalibrationQuality.good;
    if (_smoothedHeadingDelta <= 3.0) return _CalibrationQuality.medium;
    return _CalibrationQuality.poor;
  }

  String _calibrationLabel(_CalibrationQuality quality) {
    switch (quality) {
      case _CalibrationQuality.initializing:
        return 'KALIBRASI: MEMBACA SENSOR';
      case _CalibrationQuality.good:
        return 'KALIBRASI: STABIL';
      case _CalibrationQuality.medium:
        return 'KALIBRASI: CUKUP';
      case _CalibrationQuality.poor:
        return 'KALIBRASI: PERLU PENYESUAIAN';
    }
  }

  String _calibrationHint(_CalibrationQuality quality) {
    switch (quality) {
      case _CalibrationQuality.initializing:
        return 'Tahan perangkat beberapa detik untuk akurasi awal.';
      case _CalibrationQuality.good:
        return 'Arah kompas stabil. Siap digunakan.';
      case _CalibrationQuality.medium:
        return 'Arah cukup stabil, jauhkan dari benda logam.';
      case _CalibrationQuality.poor:
        return 'Gerakkan perangkat membentuk angka 8 agar kompas lebih akurat.';
    }
  }

  Color _calibrationColor(_CalibrationQuality quality) {
    switch (quality) {
      case _CalibrationQuality.initializing:
        return Colors.amber;
      case _CalibrationQuality.good:
        return Colors.green;
      case _CalibrationQuality.medium:
        return Colors.orange;
      case _CalibrationQuality.poor:
        return Colors.redAccent;
    }
  }

  @override
  Widget build(BuildContext context) {
    final isDark = Theme.of(context).brightness == Brightness.dark;

    return FutureBuilder(
      future: _bootstrapFuture,
      builder: (_, AsyncSnapshot<_QiblaBootstrapState> snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return const Scaffold(
            body: SafeArea(
              top: false,
              bottom: true,
              child: Center(child: CircularProgressIndicator()),
            ),
          );
        }

        if (snapshot.hasError) {
          return _buildErrorLayout(
            context,
            isDark,
            title: 'Qibla belum siap',
            subtitle: 'Terjadi kendala saat menginisialisasi sensor.',
            actionLabel: 'Coba Lagi',
            onAction: _retryBootstrap,
          );
        }

        final bootstrap = snapshot.data;
        if (bootstrap == null) {
          return _buildErrorLayout(
            context,
            isDark,
            title: 'Qibla belum siap',
            subtitle: 'Status sensor belum tersedia.',
            actionLabel: 'Coba Lagi',
            onAction: _retryBootstrap,
          );
        }

        if (bootstrap.mode == _QiblaMode.live) {
          return _buildLiveQibla(context, isDark);
        }

        if (bootstrap.mode == _QiblaMode.simulated) {
          // Device lacks compass sensor (desktop/emulators)
          return _buildSimulatedQibla(context, isDark);
        }

        if (bootstrap.mode == _QiblaMode.locationDisabled) {
          return _buildErrorLayout(
            context,
            isDark,
            title: 'Aktifkan lokasi',
            subtitle:
                'Compass membutuhkan layanan lokasi agar arah kiblat bisa dihitung.',
            actionLabel: 'Buka Pengaturan Lokasi',
            onAction: () async {
              await Geolocator.openLocationSettings();
              _retryBootstrap();
            },
          );
        }

        if (bootstrap.mode == _QiblaMode.permissionDeniedForever) {
          return _buildErrorLayout(
            context,
            isDark,
            title: 'Izin lokasi diblokir',
            subtitle:
                'Aktifkan izin lokasi dari pengaturan aplikasi untuk memakai Compass.',
            actionLabel: 'Buka Pengaturan Aplikasi',
            onAction: () async {
              await Geolocator.openAppSettings();
              _retryBootstrap();
            },
          );
        }

        if (bootstrap.mode == _QiblaMode.permissionDenied) {
          return _buildErrorLayout(
            context,
            isDark,
            title: 'Izin lokasi diperlukan',
            subtitle:
                'Izinkan lokasi agar Compass bisa menentukan arah kiblat.',
            actionLabel: 'Izinkan Lokasi',
            onAction: _retryBootstrap,
          );
        }

        return _buildSimulatedQibla(context, isDark);
      },
    );
  }

  Widget _buildLiveQibla(BuildContext context, bool isDark) {
    _ensureLiveTracking();

    return StreamBuilder(
      stream: FlutterQiblah.qiblahStream,
      builder: (_, AsyncSnapshot<QiblahDirection> snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return const Scaffold(
            body: SafeArea(
              top: false,
              bottom: true,
              child: Center(child: CircularProgressIndicator()),
            ),
          );
        }

        if (snapshot.hasError) {
          return _buildErrorLayout(
            context,
            isDark,
            title: 'Sensor kompas belum stabil',
            subtitle: 'Gerakkan perangkat membentuk angka 8 lalu coba lagi.',
            actionLabel: 'Muat Ulang',
            onAction: _retryBootstrap,
          );
        }

        final qiblahDirection = snapshot.data;
        if (qiblahDirection == null) {
          return _buildErrorLayout(
            context,
            isDark,
            title: 'Menunggu sensor arah',
            subtitle: 'Pastikan perangkat memiliki akses sensor dan lokasi.',
            actionLabel: 'Coba Lagi',
            onAction: _retryBootstrap,
          );
        }

        final displayAngle = _normalizeAngle(_qiblaAngle);
        final rawHeading = _normalizeAngle(qiblahDirection.direction);
        final trueHeading = Platform.isAndroid
            ? _normalizeAngle(rawHeading + (_magneticDeclination ?? 0))
            : rawHeading;
        final needleBearing =
            _normalizeAngle(trueHeading + (360 - displayAngle));
        final needleAngle = -(needleBearing * (math.pi / 180));
        final qiblaDelta = _alignmentDelta(needleBearing);
        final isAligned = qiblaDelta <= _alignmentThreshold;
        final calibrationQuality = _assessCalibration(rawHeading);

        return _buildQiblaLayout(
          context: context,
          isDark: isDark,
          angleRad: needleAngle,
          displayAngle: displayAngle,
          directionLabel: _directionForAngle(displayAngle),
          isLive: true,
          isAligned: isAligned,
          qiblaDelta: qiblaDelta,
          calibrationQuality: calibrationQuality,
        );
      },
    );
  }

  Widget _buildSimulatedQibla(BuildContext context, bool isDark) {
    return _buildQiblaLayout(
      context: context,
      isDark: isDark,
      angleRad: _qiblaAngle * (math.pi / 180),
      displayAngle: _normalizeAngle(_qiblaAngle),
      directionLabel: _directionForAngle(_qiblaAngle),
      isLive: false,
      isAligned: false,
      qiblaDelta: null,
      calibrationQuality: null,
    );
  }

  Widget _buildErrorLayout(
    BuildContext context,
    bool isDark, {
    required String title,
    required String subtitle,
    required String actionLabel,
    required VoidCallback onAction,
  }) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Arah Kiblat'),
        leading: IconButton(
          icon: Container(
            padding: const EdgeInsets.all(6),
            decoration: BoxDecoration(
              shape: BoxShape.circle,
              color: isDark ? AppColors.surfaceDark : AppColors.surfaceLight,
              border: Border.all(color: AppColors.cream),
            ),
            child: const AppIcon(glyph: AppIcons.backArrow, size: 18),
          ),
          onPressed: () => Navigator.pop(context),
        ),
      ),
      body: SafeArea(
        top: false,
        bottom: true,
        child: Center(
          child: Padding(
            padding: const EdgeInsets.symmetric(horizontal: 24),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                AppIcon(
                  glyph: AppIcons.locationOffline,
                  size: 34,
                  color: isDark ? Colors.white70 : AppColors.textPrimaryLight,
                ),
                const SizedBox(height: 16),
                Text(
                  title,
                  textAlign: TextAlign.center,
                  style: const TextStyle(
                    fontSize: 22,
                    fontWeight: FontWeight.w800,
                  ),
                ),
                const SizedBox(height: 10),
                Text(
                  subtitle,
                  textAlign: TextAlign.center,
                  style: TextStyle(
                    fontSize: 14,
                    color: isDark
                        ? AppColors.textSecondaryDark
                        : AppColors.textSecondaryLight,
                  ),
                ),
                const SizedBox(height: 20),
                FilledButton(
                  onPressed: onAction,
                  child: Text(actionLabel),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  Widget _buildQiblaLayout({
    required BuildContext context,
    required bool isDark,
    required double angleRad,
    required double displayAngle,
    required String directionLabel,
    required bool isLive,
    required bool isAligned,
    required double? qiblaDelta,
    required _CalibrationQuality? calibrationQuality,
  }) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Arah Kiblat'),
        leading: IconButton(
          icon: Container(
            padding: const EdgeInsets.all(6),
            decoration: BoxDecoration(
              shape: BoxShape.circle,
              color: isDark ? AppColors.surfaceDark : AppColors.surfaceLight,
              border: Border.all(color: AppColors.cream),
            ),
            child: const AppIcon(glyph: AppIcons.backArrow, size: 18),
          ),
          onPressed: () => Navigator.pop(context),
        ),
        actions: [
          IconButton(
            icon: Container(
              padding: const EdgeInsets.all(6),
              decoration: BoxDecoration(
                shape: BoxShape.circle,
                color: isDark ? AppColors.surfaceDark : AppColors.surfaceLight,
                border: Border.all(color: AppColors.cream),
              ),
              child: AppIcon(
                glyph:
                    isLive ? AppIcons.locationActive : AppIcons.locationOffline,
                size: 18,
              ),
            ),
            onPressed: () {
              if (isLive) {
                ScaffoldMessenger.of(context).showSnackBar(
                  const SnackBar(
                    content: Text('Menggunakan sensor perangkat aktual'),
                  ),
                );
              } else {
                ScaffoldMessenger.of(context).showSnackBar(
                  const SnackBar(
                    content:
                        Text('Mode Simulasi: Hardware kompas tidak terdeteksi'),
                  ),
                );
              }
            },
          ),
        ],
      ),
      body: SafeArea(
        top: false,
        bottom: true,
        child: Container(
          width: double.infinity,
          clipBehavior: Clip.hardEdge,
          decoration: BoxDecoration(
            gradient: LinearGradient(
              begin: Alignment.topCenter,
              end: Alignment.bottomCenter,
              colors: isDark
                  ? [AppColors.backgroundDark, AppColors.surfaceDark]
                  : [
                      AppColors.backgroundLight,
                      AppColors.primary.withValues(alpha: 0.05),
                    ],
            ),
          ),
          child: Stack(
            fit: StackFit.expand,
            children: [
              if ((_unsplashPhoto?['imageUrl'] ?? '').isNotEmpty)
                Opacity(
                  opacity: isDark ? 0.2 : 0.12,
                  child: CachedNetworkImage(
                    imageUrl: _unsplashPhoto!['imageUrl']!,
                    fit: BoxFit.cover,
                  ),
                ),
              DecoratedBox(
                decoration: BoxDecoration(
                  gradient: LinearGradient(
                    begin: Alignment.topCenter,
                    end: Alignment.bottomCenter,
                    colors: isDark
                        ? [
                            AppColors.backgroundDark.withValues(alpha: 0.9),
                            AppColors.surfaceDark.withValues(alpha: 0.88),
                          ]
                        : [
                            AppColors.backgroundLight.withValues(alpha: 0.88),
                            AppColors.primary.withValues(alpha: 0.08),
                          ],
                  ),
                ),
              ),
              Column(
                children: [
                  const SizedBox(height: 32),
                  // Location label
                  Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      const AppIcon(
                          glyph: AppIcons.location,
                          size: 16,
                          color: AppColors.primary),
                      const SizedBox(width: 4),
                      Text(
                        'Ka\'bah, Makkah',
                        style: TextStyle(
                          fontSize: 14,
                          color: isDark
                              ? AppColors.textSecondaryDark
                              : AppColors.textSecondaryLight,
                        ),
                      ),
                    ],
                  ),
                  const SizedBox(height: 8),
                  // Degree + direction
                  Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Text(
                        '${displayAngle.round()}°',
                        style: const TextStyle(
                          fontSize: 48,
                          fontWeight: FontWeight.w800,
                        ),
                      ),
                      const SizedBox(width: 12),
                      Text(
                        directionLabel,
                        style: const TextStyle(
                          fontSize: 48,
                          fontWeight: FontWeight.w800,
                          color: AppColors.primary,
                        ),
                      ),
                    ],
                  ),
                  if (isLive && qiblaDelta != null) ...[
                    const SizedBox(height: 14),
                    AnimatedContainer(
                      duration: const Duration(milliseconds: 360),
                      curve: Curves.easeOutCubic,
                      padding: const EdgeInsets.symmetric(
                        horizontal: 16,
                        vertical: 10,
                      ),
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(999),
                        gradient: LinearGradient(
                          colors: isAligned
                              ? [
                                  AppColors.primary.withValues(alpha: 0.24),
                                  AppColors.primary.withValues(alpha: 0.14),
                                ]
                              : [
                                  Colors.white
                                      .withValues(alpha: isDark ? 0.1 : 0.65),
                                  Colors.white
                                      .withValues(alpha: isDark ? 0.06 : 0.4),
                                ],
                        ),
                        border: Border.all(
                          color: isAligned
                              ? AppColors.primary.withValues(alpha: 0.65)
                              : AppColors.cream.withValues(alpha: 0.45),
                        ),
                        boxShadow: [
                          if (isAligned)
                            BoxShadow(
                              color: AppColors.primary.withValues(alpha: 0.28),
                              blurRadius: 18,
                              spreadRadius: 0.5,
                            ),
                        ],
                      ),
                      child: Row(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          AppIcon(
                            glyph: isAligned
                                ? AppIcons.checkCircle
                                : AppIcons.qibla,
                            size: 18,
                            color: isAligned
                                ? AppColors.primary
                                : (isDark
                                    ? AppColors.textSecondaryDark
                                    : AppColors.textSecondaryLight),
                          ),
                          const SizedBox(width: 10),
                          Text(
                            isAligned
                                ? 'Sudah sejajar kiblat'
                                : 'Putar ${qiblaDelta.ceil()}° lagi',
                            style: TextStyle(
                              fontSize: 13,
                              fontWeight: FontWeight.w700,
                              color: isAligned
                                  ? AppColors.primary
                                  : (isDark
                                      ? AppColors.textSecondaryDark
                                      : AppColors.textSecondaryLight),
                            ),
                          ),
                        ],
                      ),
                    ),
                  ],
                  const SizedBox(height: 24),
                  // Compass
                  Expanded(
                    child: Center(
                      child: SizedBox(
                        width: 300,
                        height: 300,
                        child: CustomPaint(
                          painter: _CompassPainter(
                            qiblaAngle: angleRad,
                            isDark: isDark,
                            isAligned: isAligned,
                          ),
                        ),
                      ),
                    ),
                  ),
                  const SizedBox(height: 16),
                  // Calibration status
                  Container(
                    padding: const EdgeInsets.symmetric(
                        horizontal: 24, vertical: 10),
                    decoration: BoxDecoration(
                      color: isLive
                          ? AppColors.primary.withValues(alpha: 0.1)
                          : Colors.orange.withValues(alpha: 0.1),
                      borderRadius: BorderRadius.circular(50),
                    ),
                    child: Text(
                      isLive
                          ? 'SENSOR AKTIF'
                          : 'MODE SIMULASI (TIDAK ADA SENSOR)',
                      style: TextStyle(
                        fontSize: 11,
                        fontWeight: FontWeight.w700,
                        letterSpacing: 1.5,
                        color: isLive ? AppColors.primary : Colors.orange,
                      ),
                    ),
                  ),
                  if (isLive && calibrationQuality != null) ...[
                    const SizedBox(height: 10),
                    Container(
                      padding: const EdgeInsets.symmetric(
                          horizontal: 16, vertical: 8),
                      decoration: BoxDecoration(
                        color: _calibrationColor(calibrationQuality)
                            .withValues(alpha: 0.12),
                        borderRadius: BorderRadius.circular(999),
                      ),
                      child: Row(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          Container(
                            width: 8,
                            height: 8,
                            decoration: BoxDecoration(
                              shape: BoxShape.circle,
                              color: _calibrationColor(calibrationQuality),
                            ),
                          ),
                          const SizedBox(width: 8),
                          Text(
                            _calibrationLabel(calibrationQuality),
                            style: TextStyle(
                              fontSize: 11,
                              fontWeight: FontWeight.w700,
                              letterSpacing: 1.2,
                              color: _calibrationColor(calibrationQuality),
                            ),
                          ),
                        ],
                      ),
                    ),
                    const SizedBox(height: 8),
                    Padding(
                      padding: const EdgeInsets.symmetric(horizontal: 32),
                      child: Text(
                        _calibrationHint(calibrationQuality),
                        textAlign: TextAlign.center,
                        style: TextStyle(
                          fontSize: 12,
                          color: isDark
                              ? AppColors.textSecondaryDark
                              : AppColors.textSecondaryLight,
                        ),
                      ),
                    ),
                  ],
                  const SizedBox(height: 48),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class _CompassPainter extends CustomPainter {
  final double qiblaAngle;
  final bool isDark;
  final bool isAligned;

  _CompassPainter({
    required this.qiblaAngle,
    required this.isDark,
    required this.isAligned,
  });

  @override
  void paint(Canvas canvas, Size size) {
    final center = Offset(size.width / 2, size.height / 2);
    final radius = size.width / 2 - 8;

    // Outer circle
    final outerPaint = Paint()
      ..color = AppColors.primary.withValues(alpha: 0.15)
      ..style = PaintingStyle.stroke
      ..strokeWidth = 2;
    canvas.drawCircle(center, radius, outerPaint);

    // Inner dashed circle
    final innerPaint = Paint()
      ..color = AppColors.primary.withValues(alpha: 0.08)
      ..style = PaintingStyle.stroke
      ..strokeWidth = 1;
    canvas.drawCircle(center, radius * 0.7, innerPaint);

    // Cross lines
    final crossPaint = Paint()
      ..color = AppColors.primary.withValues(alpha: 0.1)
      ..strokeWidth = 1;
    canvas.drawLine(Offset(center.dx, center.dy - radius),
        Offset(center.dx, center.dy + radius), crossPaint);
    canvas.drawLine(Offset(center.dx - radius, center.dy),
        Offset(center.dx + radius, center.dy), crossPaint);
    // Diagonals
    final diagOffset = radius * 0.707;
    canvas.drawLine(Offset(center.dx - diagOffset, center.dy - diagOffset),
        Offset(center.dx + diagOffset, center.dy + diagOffset), crossPaint);
    canvas.drawLine(Offset(center.dx + diagOffset, center.dy - diagOffset),
        Offset(center.dx - diagOffset, center.dy + diagOffset), crossPaint);

    // Center dot
    final centerDotPaint = Paint()
      ..color = AppColors.primary.withValues(alpha: 0.3)
      ..style = PaintingStyle.stroke
      ..strokeWidth = 2;
    canvas.drawCircle(center, 6, centerDotPaint);

    // Qibla direction line
    final qiblaEndX =
        center.dx + radius * 0.85 * math.cos(qiblaAngle - math.pi / 2);
    final qiblaEndY =
        center.dy + radius * 0.85 * math.sin(qiblaAngle - math.pi / 2);

    // Glow effect
    final glowPaint = Paint()
      ..color = AppColors.primary.withValues(alpha: 0.3)
      ..strokeWidth = 6
      ..strokeCap = StrokeCap.round;
    canvas.drawLine(center, Offset(qiblaEndX, qiblaEndY), glowPaint);

    // Main line
    final linePaint = Paint()
      ..color = AppColors.primary
      ..strokeWidth = 3
      ..strokeCap = StrokeCap.round;
    canvas.drawLine(center, Offset(qiblaEndX, qiblaEndY), linePaint);

    final iconCenter = Offset(qiblaEndX, qiblaEndY);

    // Qibla icon circle at end
    final iconPaint = Paint()
      ..color = isAligned
          ? AppColors.primary
          : AppColors.primary.withValues(alpha: 0.9);
    canvas.drawCircle(iconCenter, 17, iconPaint);

    final iconBorderPaint = Paint()
      ..color = AppColors.cream.withValues(alpha: 0.82)
      ..style = PaintingStyle.stroke
      ..strokeWidth = 1.4;
    canvas.drawCircle(iconCenter, 17, iconBorderPaint);

    // Kaaba marker
    final kaabaBodyPaint = Paint()
      ..color = isDark ? const Color(0xFF14191D) : const Color(0xFF11161B)
      ..style = PaintingStyle.fill;
    final kaabaBody = RRect.fromRectAndRadius(
      Rect.fromCenter(
        center: iconCenter,
        width: 12,
        height: 11,
      ),
      const Radius.circular(1.8),
    );
    canvas.drawRRect(kaabaBody, kaabaBodyPaint);

    final kaabaGoldPaint = Paint()
      ..color = const Color(0xFFF0C14A)
      ..style = PaintingStyle.fill;
    canvas.drawRect(
      Rect.fromCenter(
        center: Offset(iconCenter.dx, iconCenter.dy - 2.4),
        width: 12,
        height: 2.0,
      ),
      kaabaGoldPaint,
    );

    final kaabaDoorPaint = Paint()
      ..color = const Color(0xFF7B5A16)
      ..style = PaintingStyle.fill;
    canvas.drawRRect(
      RRect.fromRectAndRadius(
        Rect.fromCenter(
          center: Offset(iconCenter.dx, iconCenter.dy + 1.8),
          width: 2.8,
          height: 4.2,
        ),
        const Radius.circular(0.6),
      ),
      kaabaDoorPaint,
    );
  }

  @override
  bool shouldRepaint(covariant _CompassPainter oldDelegate) =>
      qiblaAngle != oldDelegate.qiblaAngle ||
      isAligned != oldDelegate.isAligned;
}

enum _QiblaMode {
  live,
  simulated,
  locationDisabled,
  permissionDenied,
  permissionDeniedForever,
}

enum _CalibrationQuality {
  initializing,
  good,
  medium,
  poor,
}

class _QiblaBootstrapState {
  final _QiblaMode mode;

  const _QiblaBootstrapState(this.mode);
}
