<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\UserShoppingActivity;
use App\Models\GiftPrize;
use App\Models\UserGiftSpin;
use App\Models\UserGiftStreak;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class GiftCalendarController extends Controller
{
    private const STREAK_DAYS_REQUIRED = 30;

    /**
     * جلب بيانات التقويم: أيام 1-30، التتابع الحالي، وإمكانية السبين
     */
    public function getCalendar(Request $request): JsonResponse
    {
        $user = Auth::user();
        if (!$user) {
            return response()->json(['success' => false, 'message' => 'يجب تسجيل الدخول'], 401);
        }

        $streak = $this->getUserGiftStreak($user->id);
        $calendarDays = $this->buildCalendarDays($user->id, $streak['current_streak'], $streak['activity_dates']);

        return response()->json([
            'success' => true,
            'data' => [
                'calendar_days' => $calendarDays,
                'current_streak' => $streak['current_streak'],
                'can_spin' => $streak['current_streak'] >= self::STREAK_DAYS_REQUIRED,
                'streak_required' => self::STREAK_DAYS_REQUIRED,
                'last_spin_at' => $streak['last_spin_at'],
            ],
            'message' => 'تم جلب سجل الهدايا بنجاح',
        ]);
    }

    /**
     * سبين عجلة الحظ (يسمح فقط عند وصول 30 يوم متتالية)
     */
    public function spin(Request $request): JsonResponse
    {
        $user = Auth::user();
        if (!$user) {
            return response()->json(['success' => false, 'message' => 'يجب تسجيل الدخول'], 401);
        }

        $streak = $this->getUserGiftStreak($user->id);
        if ($streak['current_streak'] < self::STREAK_DAYS_REQUIRED) {
            return response()->json([
                'success' => false,
                'message' => 'تحتاج إلى ' . self::STREAK_DAYS_REQUIRED . ' يوم تسوق متتالية لفتح عجلة الحظ. تتابعك الحالي: ' . $streak['current_streak'],
            ], 400);
        }

        $prizes = GiftPrize::where('is_active', true)->orderBy('sort_order')->get();
        if ($prizes->isEmpty()) {
            return response()->json(['success' => false, 'message' => 'لا توجد جوائز متاحة'], 500);
        }

        try {
            DB::beginTransaction();

            $prize = $prizes->random(1)->first();
            UserGiftSpin::create([
                'user_id' => $user->id,
                'prize_id' => $prize->id,
                'spun_at' => now(),
            ]);

            UserGiftStreak::updateOrCreate(
                ['user_id' => $user->id],
                ['last_spin_at' => Carbon::today()]
            );

            DB::commit();

            return response()->json([
                'success' => true,
                'data' => [
                    'prize' => [
                        'id' => $prize->id,
                        'name_ar' => $prize->name_ar,
                        'emoji' => $prize->emoji,
                    ],
                ],
                'message' => 'مبروك! فزت بـ ' . $prize->name_ar,
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'success' => false,
                'message' => 'حدث خطأ أثناء السبين: ' . $e->getMessage(),
            ], 500);
        }
    }

    /**
     * حساب التتابع الحالي وأيام النشاط (بعد آخر سبين)
     */
    private function getUserGiftStreak(int $userId): array
    {
        $streakRecord = UserGiftStreak::where('user_id', $userId)->first();
        $lastSpinAt = $streakRecord?->last_spin_at;

        $query = UserShoppingActivity::where('user_id', $userId)
            ->where('activity_date', '<=', Carbon::today());
        if ($lastSpinAt) {
            $query->where('activity_date', '>', $lastSpinAt);
        }
        $activityDates = $query->pluck('activity_date')->map(fn ($d) => Carbon::parse($d)->format('Y-m-d'))->unique()->sort()->values()->all();

        $currentStreak = 0;
        $check = Carbon::today();
        while (true) {
            $d = $check->format('Y-m-d');
            if (!in_array($d, $activityDates, true)) {
                break;
            }
            $currentStreak++;
            $check->subDay();
        }

        return [
            'current_streak' => $currentStreak,
            'activity_dates' => $activityDates,
            'last_spin_at' => $lastSpinAt?->format('Y-m-d'),
        ];
    }

    /**
     * بناء مصفوفة الأيام 1-30 للتقويم (أي يوم نشط = تسوق فيه ضمن التتابع الحالي)
     */
    private function buildCalendarDays(int $userId, int $currentStreak, array $activityDates): array
    {
        $today = Carbon::today();
        $startDate = $currentStreak > 0
            ? $today->copy()->subDays($currentStreak - 1)
            : $today->copy();

        $days = [];
        for ($dayNumber = 1; $dayNumber <= self::STREAK_DAYS_REQUIRED; $dayNumber++) {
            $dayDate = $startDate->copy()->addDays($dayNumber - 1);
            $dateStr = $dayDate->format('Y-m-d');
            $isPastOrToday = $dayDate->lte($today);
            $active = $isPastOrToday && in_array($dateStr, $activityDates, true);

            $days[] = [
                'day_number' => $dayNumber,
                'date' => $dateStr,
                'active' => $active,
            ];
        }
        return $days;
    }
}
