import 'package:siro_driver/constant/currency.dart';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:siro_driver/constant/box_name.dart';
import 'package:siro_driver/constant/links.dart';
import 'package:siro_driver/controller/functions/crud.dart';
import '../../../main.dart';

// ════════════════════════════════════════════
//  نموذج التحدي
// ════════════════════════════════════════════

class Challenge {
  final String id;
  final String titleEn;
  final String titleAr;
  final String descriptionEn;
  final String descriptionAr;
  final IconData icon;
  final Color color;
  final int target;
  final int reward; // نقاط
  final String type; // 'daily' or 'weekly'
  final String metric; // 'trips', 'earnings', 'hours', 'acceptance_rate'
  int currentProgress;
  bool isClaimed;

  Challenge({
    required this.id,
    required this.titleEn,
    required this.titleAr,
    required this.descriptionEn,
    required this.descriptionAr,
    required this.icon,
    required this.color,
    required this.target,
    required this.reward,
    required this.type,
    required this.metric,
    this.currentProgress = 0,
    this.isClaimed = false,
  });

  double get progress => (currentProgress / target).clamp(0.0, 1.0);
  bool get isCompleted => currentProgress >= target;
}

// ════════════════════════════════════════════
class ChallengesController extends GetxController {
  bool isLoading = false;
  List<Challenge> dailyChallenges = [];
  List<Challenge> weeklyChallenges = [];

  @override
  void onInit() {
    super.onInit();
    _generateChallenges();
    _loadProgress();
    fetchChallengeProgress();
  }

  void _generateChallenges() {
    final now = DateTime.now();
    final isWeekend = now.weekday == 5 || now.weekday == 6; // الجمعة والسبت
    String country = box.read(BoxName.countryCode) ?? 'Jordan';

    int dailyEarningsTarget;
    int dailyEarningsReward;
    int weeklyEarningsTarget;
    int weeklyEarningsReward;

    String dailyEarningsDescAr;
    String dailyEarningsDescEn;
    String weeklyEarningsDescAr;
    String weeklyEarningsDescEn;

    if (country == 'Syria') {
      dailyEarningsTarget = 150000;
      dailyEarningsReward = 100; // 100 pts -> 10,000 SYP
      weeklyEarningsTarget = 1000000;
      weeklyEarningsReward = 500; // 500 pts -> 50,000 SYP
      dailyEarningsDescAr = 'اربح 150,000 ل.س اليوم';
      dailyEarningsDescEn = 'Earn 150,000 SYP today';
      weeklyEarningsDescAr = 'اربح 1,000,000 ل.س هذا الأسبوع';
      weeklyEarningsDescEn = 'Earn 1,000,000 SYP this week';
    } else if (country == 'Egypt') {
      dailyEarningsTarget = 300;
      dailyEarningsReward = 30; // 30 pts -> 30 EGP
      weeklyEarningsTarget = 2000;
      weeklyEarningsReward = 200; // 200 pts -> 200 EGP
      dailyEarningsDescAr = 'اربح 300 ج.م اليوم';
      dailyEarningsDescEn = 'Earn 300 EGP today';
      weeklyEarningsDescAr = 'اربح 2000 ج.م هذا الأسبوع';
      weeklyEarningsDescEn = 'Earn 2000 EGP this week';
    } else {
      // Jordan / default
      dailyEarningsTarget = 30;
      dailyEarningsReward = 60; // 60 pts -> 3 JOD (60 * 0.05 = 3 JOD)
      weeklyEarningsTarget = 200;
      weeklyEarningsReward = 400; // 400 pts -> 20 JOD (400 * 0.05 = 20 JOD)
      dailyEarningsDescAr = 'اربح 30 د.أ اليوم';
      dailyEarningsDescEn = 'Earn 30 JOD today';
      weeklyEarningsDescAr = 'اربح 200 د.أ هذا الأسبوع';
      weeklyEarningsDescEn = 'Earn 200 JOD this week';
    }

    dailyChallenges = [
      Challenge(
        id: 'daily_trips_5',
        titleEn: 'Road Runner',
        titleAr: 'سائق سريع',
        descriptionEn: 'Complete 5 trips today',
        descriptionAr: 'أكمل 5 رحلات اليوم',
        icon: Icons.local_taxi_rounded,
        color: const Color(0xFF2196F3),
        target: 5,
        reward: country == 'Syria' ? 50 : (country == 'Egypt' ? 50 : 100),
        type: 'daily',
        metric: 'trips',
      ),
      Challenge(
        id: 'daily_trips_10',
        titleEn: 'Marathon Driver',
        titleAr: 'سائق الماراثون',
        descriptionEn: 'Complete 10 trips today',
        descriptionAr: 'أكمل 10 رحلات اليوم',
        icon: Icons.directions_car_rounded,
        color: const Color(0xFFFF9800),
        target: 10,
        reward: country == 'Syria' ? 150 : (country == 'Egypt' ? 150 : 300),
        type: 'daily',
        metric: 'trips',
      ),
      Challenge(
        id: 'daily_earnings',
        titleEn: 'Money Maker',
        titleAr: 'صانع المال',
        descriptionEn: dailyEarningsDescEn,
        descriptionAr: dailyEarningsDescAr,
        icon: Icons.monetization_on_rounded,
        color: const Color(0xFF4CAF50),
        target: dailyEarningsTarget,
        reward: dailyEarningsReward,
        type: 'daily',
        metric: 'earnings',
      ),
      if (isWeekend)
        Challenge(
          id: 'daily_weekend_bonus',
          titleEn: 'Weekend Warrior',
          titleAr: 'محارب عطلة نهاية الأسبوع',
          descriptionEn: 'Complete 8 trips on the weekend',
          descriptionAr: 'أكمل 8 رحلات في عطلة نهاية الأسبوع',
          icon: Icons.celebration_rounded,
          color: const Color(0xFFE91E63),
          target: 8,
          reward: country == 'Syria' ? 200 : (country == 'Egypt' ? 200 : 400),
          type: 'daily',
          metric: 'trips',
        ),
    ];

    weeklyChallenges = [
      Challenge(
        id: 'weekly_trips_30',
        titleEn: 'Weekly Champion',
        titleAr: 'بطل الأسبوع',
        descriptionEn: 'Complete 30 trips this week',
        descriptionAr: 'أكمل 30 رحلة هذا الأسبوع',
        icon: Icons.emoji_events_rounded,
        color: const Color(0xFFFFD700),
        target: 30,
        reward: country == 'Syria' ? 300 : (country == 'Egypt' ? 300 : 600),
        type: 'weekly',
        metric: 'trips',
      ),
      Challenge(
        id: 'weekly_earnings',
        titleEn: 'Big Earner',
        titleAr: 'الربح الكبير',
        descriptionEn: weeklyEarningsDescEn,
        descriptionAr: weeklyEarningsDescAr,
        icon: Icons.account_balance_wallet_rounded,
        color: const Color(0xFF9C27B0),
        target: weeklyEarningsTarget,
        reward: weeklyEarningsReward,
        type: 'weekly',
        metric: 'earnings',
      ),
      Challenge(
        id: 'weekly_hours',
        titleEn: 'Time Master',
        titleAr: 'سيد الوقت',
        descriptionEn: 'Drive for 20 hours this week',
        descriptionAr: 'اقضِ 20 ساعة في القيادة هذا الأسبوع',
        icon: Icons.timer_rounded,
        color: const Color(0xFF00BCD4),
        target: 20,
        reward: country == 'Syria' ? 400 : (country == 'Egypt' ? 400 : 800),
        type: 'weekly',
        metric: 'hours',
      )
    ];
  }

  void _loadProgress() {
    final today = DateTime.now().toIso8601String().split('T')[0];
    final savedDate = box.read('challenges_date');

    if (savedDate != today) {
      // يوم جديد — إعادة تعيين التحديات اليومية
      box.write('challenges_date', today);
      for (var c in dailyChallenges) {
        box.write('challenge_${c.id}_claimed', false);
      }
    }

    // تحميل حالة المطالبة
    for (var c in dailyChallenges) {
      c.isClaimed = box.read('challenge_${c.id}_claimed') ?? false;
    }
    for (var c in weeklyChallenges) {
      c.isClaimed = box.read('challenge_${c.id}_claimed') ?? false;
    }
  }

  Future<void> fetchChallengeProgress() async {
    isLoading = true;
    update();

    try {
      // جلب رحلات اليوم
      var todayRes = await CRUD().getWallet(
        link: AppLink.getDriverPaymentToday,
        payload: {'driverID': box.read(BoxName.driverID).toString()},
      );

      int todayTrips = 0;
      double todayEarnings = 0;

      if (todayRes != null && todayRes != 'failure') {
        var data = jsonDecode(todayRes);
        todayEarnings = double.tryParse(
                data['message']?[0]?['todayAmount']?.toString() ?? '0') ??
            0;
        todayTrips = int.tryParse(
                data['message']?[0]?['todayCount']?.toString() ?? '0') ??
            0;
      }

      // تحديث التحديات اليومية
      for (var c in dailyChallenges) {
        switch (c.metric) {
          case 'trips':
            c.currentProgress = todayTrips;
            break;
          case 'earnings':
            c.currentProgress = todayEarnings.toInt();
            break;
        }
      }

      // 2. Fetch weekly earnings from PAYMENT server
      var weeklyEarningsRes = await CRUD().getWallet(
        link: AppLink.getDriverWeekPaymentMove,
        payload: {'driverID': box.read(BoxName.driverID).toString()},
      );

      double weeklyEarnings = 0;
      if (weeklyEarningsRes != null && weeklyEarningsRes != 'failure') {
        var data = jsonDecode(weeklyEarningsRes);
        if (data['message'] is List && data['message'].isNotEmpty) {
          weeklyEarnings = double.tryParse(
                  data['message'][0]['totalAmount']?.toString() ?? '0') ??
              0;
        }
      }

      // 3. Fetch weekly trips and hours from RIDES server (avoiding earnings join)
      var weeklyAggregateRes = await CRUD().get(
        link: AppLink.getWeeklyAggregate,
        payload: {'driver_id': box.read(BoxName.driverID).toString()},
      );

      int weeklyTrips = 0;
      double weeklyHours = 0;

      if (weeklyAggregateRes != null && weeklyAggregateRes != 'failure') {
        var data = jsonDecode(weeklyAggregateRes);
        if (data['message'] is List) {
          for (var day in data['message']) {
            weeklyTrips += int.tryParse(day['trips']?.toString() ?? '0') ?? 0;
            weeklyHours +=
                double.tryParse(day['hours']?.toString() ?? '0') ?? 0;
          }
        }
      }

      for (var c in weeklyChallenges) {
        switch (c.metric) {
          case 'trips':
            c.currentProgress = weeklyTrips;
            break;
          case 'earnings':
            c.currentProgress = weeklyEarnings.toInt();
            break;
          case 'hours':
            c.currentProgress = weeklyHours.toInt();
            break;
        }
      }
    } catch (e) {
      debugPrint('❌ [Challenges] Error: $e');
    }

    isLoading = false;
    update();
  }

  final Set<String> _claimingChallenges = {};

  bool isClaiming(String challengeId) =>
      _claimingChallenges.contains(challengeId);

  Future<void> claimReward(Challenge challenge) async {
    if (!challenge.isCompleted ||
        challenge.isClaimed ||
        _claimingChallenges.contains(challenge.id)) return;

    _claimingChallenges.add(challenge.id);
    update();

    try {
      var res = await CRUD().post(
        link: AppLink.claimChallengeReward,
        payload: {
          'driver_id': box.read(BoxName.driverID).toString(),
          'challenge_id': challenge.id,
          'points': challenge.reward.toString(),
        },
      );

      if (res != null && res != 'failure') {
        challenge.isClaimed = true;
        box.write('challenge_${challenge.id}_claimed', true);
        debugPrint('🎉 Claimed ${challenge.reward} points for ${challenge.id}');
      }
    } catch (e) {
      debugPrint('❌ [Challenges] Claim error: $e');
    } finally {
      _claimingChallenges.remove(challenge.id);
      update();
    }
  }
}
