<?php

namespace App\Http\Controllers\API\V1\Offer;

use App\Http\Controllers\Controller;
use App\Models\Offer;
use App\Models\Redemption;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class RedemptionController extends Controller
{
    public function redeem(Request $request, $offerId)
    {
        $user = auth()->user();

        // Check if user has active subscription
        if (!$user->hasActiveSubscription()) {
            return response()->json([
                'success' => false,
                'message' => 'You need an active subscription to redeem offers'
            ], 403);
        }

        $offer = Offer::with('venue')->findOrFail($offerId);

        // Check if offer is active
        if (!$offer->isActive()) {
            return response()->json([
                'success' => false,
                'message' => 'This offer is not currently active'
            ], 400);
        }

        // Check if offer can be redeemed
        if (!$offer->canBeRedeemed()) {
            return response()->json([
                'success' => false,
                'message' => 'This offer has reached its redemption limit'
            ], 400);
        }

        // Check user's redemption count for this offer
        $userRedemptionCount = Redemption::where('offer_id', $offer->id)
            ->where('user_id', $user->id)
            ->whereIn('status', ['pending', 'redeemed'])
            ->count();

        if ($userRedemptionCount >= $offer->redemption_per_user) {
            return response()->json([
                'success' => false,
                'message' => 'You have reached the redemption limit for this offer'
            ], 400);
        }

        // Create redemption
        DB::beginTransaction();
        try {
            $redemption = Redemption::create([
                'offer_id' => $offer->id,
                'user_id' => $user->id,
                'venue_id' => $offer->venue_id,
                'status' => 'pending',
            ]);

            // Increment offer redemption count
            $offer->increment('redemption_count');

            DB::commit();

            // Send notification to user
            $channels = config_value('notifications.channels.offer_redeemed', ['database']);
            notify($user, 'offer_redeemed', [
                'offer_name' => $offer->title,
                'business_name' => $offer->venue->business->business_name ?? 'Business',
                'redeemed_at' => now()->format('Y-m-d H:i'),
                'action_url' => route('user.offers.show', $offer),
            ], $channels);

            // Send notification to business owner
            $businessChannels = config_value('notifications.channels.offer_redeemed_business', ['database']);
            notify($offer->venue->business->owner, 'offer_redeemed_by_user', [
                'offer_name' => $offer->title,
                'user_name' => $user->first_name . ' ' . $user->last_name,
                'venue_name' => $offer->venue->name,
                'redeemed_at' => now()->format('Y-m-d H:i'),
                'action_url' => route('business.offers.show', $offer),
            ], $businessChannels);

            return response()->json([
                'success' => true,
                'message' => 'Offer redeemed successfully. Show this code at the venue.',
                'data' => [
                    'redemption' => $redemption->load(['offer', 'venue']),
                    'redemption_code' => $redemption->redemption_code,
                ]
            ], 201);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'success' => false,
                'message' => 'Failed to redeem offer. Please try again.'
            ], 500);
        }
    }

    public function myRedemptions(Request $request)
    {
        $query = Redemption::with(['offer', 'venue', 'staff'])
            ->where('user_id', auth()->id());

        // Filter by status
        if ($request->has('status')) {
            $query->where('status', $request->status);
        }

        // Sort
        $sortBy = $request->sort_by ?? 'created_at';
        $sortOrder = $request->sort_order ?? 'desc';

        $redemptions = $query->orderBy($sortBy, $sortOrder)
            ->paginate($request->per_page ?? 15);

        return response()->json([
            'success' => true,
            'data' => $redemptions
        ]);
    }

    public function show($id)
    {
        $redemption = Redemption::with(['offer', 'venue', 'user', 'staff'])
            ->where('user_id', auth()->id())
            ->findOrFail($id);

        return response()->json([
            'success' => true,
            'data' => $redemption
        ]);
    }

    public function cancel($id)
    {
        $redemption = Redemption::where('user_id', auth()->id())
            ->where('status', 'pending')
            ->findOrFail($id);

        if ($redemption->status !== 'pending') {
            return response()->json([
                'success' => false,
                'message' => 'Only pending redemptions can be cancelled'
            ], 400);
        }

        DB::beginTransaction();
        try {
            $redemption->update(['status' => 'cancelled']);

            // Decrement offer redemption count
            $redemption->offer->decrement('redemption_count');

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Redemption cancelled successfully'
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'success' => false,
                'message' => 'Failed to cancel redemption'
            ], 500);
        }
    }

    public function stats()
    {
        $user = auth()->user();

        $stats = [
            'total_redemptions' => Redemption::where('user_id', $user->id)->count(),
            'pending_redemptions' => Redemption::where('user_id', $user->id)
                ->where('status', 'pending')
                ->count(),
            'redeemed_redemptions' => Redemption::where('user_id', $user->id)
                ->where('status', 'redeemed')
                ->count(),
            'expired_redemptions' => Redemption::where('user_id', $user->id)
                ->where('status', 'expired')
                ->count(),
        ];

        return response()->json([
            'success' => true,
            'data' => $stats
        ]);
    }

    /**
     * Validate redemption code (Manual code entry by venue staff)
     */
    public function validateCode(Request $request)
    {
        $validated = $request->validate([
            'redemption_code' => 'required|string|size:12',
        ]);

        $redemption = Redemption::where('redemption_code', strtoupper($validated['redemption_code']))
            ->where('status', 'pending')
            ->with(['offer', 'venue', 'user'])
            ->first();

        if (!$redemption) {
            return response()->json([
                'success' => false,
                'message' => 'Invalid or already used redemption code',
            ], 404);
        }

        // Check if code is expired
        if ($redemption->created_at->addHours(24)->isPast()) {
            $redemption->update(['status' => 'expired']);
            return response()->json([
                'success' => false,
                'message' => 'This redemption code has expired',
            ], 400);
        }

        return response()->json([
            'success' => true,
            'message' => 'Redemption code is valid',
            'data' => [
                'redemption' => $redemption,
                'offer' => $redemption->offer,
                'venue' => $redemption->venue,
                'user' => [
                    'name' => $redemption->user->full_name,
                    'phone' => $redemption->user->phone,
                ],
            ],
        ]);
    }

    /**
     * Complete redemption with manual code entry (Business staff)
     */
    public function completeRedemption(Request $request)
    {
        $validated = $request->validate([
            'redemption_code' => 'required|string|size:12',
            'notes' => 'nullable|string|max:500',
        ]);

        $redemption = Redemption::where('redemption_code', strtoupper($validated['redemption_code']))
            ->where('status', 'pending')
            ->first();

        if (!$redemption) {
            return response()->json([
                'success' => false,
                'message' => 'Invalid or already used redemption code',
            ], 404);
        }

        // Check if code is expired
        if ($redemption->created_at->addHours(24)->isPast()) {
            $redemption->update(['status' => 'expired']);
            return response()->json([
                'success' => false,
                'message' => 'This redemption code has expired',
            ], 400);
        }

        DB::beginTransaction();
        try {
            $redemption->update([
                'status' => 'redeemed',
                'redeemed_at' => now(),
                'redeemed_by_staff' => auth()->id(),
                'notes' => $validated['notes'] ?? null,
            ]);

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Redemption completed successfully',
                'data' => $redemption->load('offer', 'venue', 'user'),
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'success' => false,
                'message' => 'Failed to complete redemption',
            ], 500);
        }
    }
}
