<?php

namespace App\Http\Controllers\Coach;

use App\Http\Controllers\Controller;
use App\Models\CoachPlan;
use App\Models\CoachPlanAuditLog;
use App\Models\CoachPlanPurchase;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Inertia\Inertia;
use Inertia\Response;

class CoachPlanController extends Controller
{
    /**
     * Display a listing of the coach's plans.
     */
    public function index(Request $request): Response
    {
        $user = $request->user();

        $plans = $user->coachPlans()
            ->withCount(['purchases', 'activePurchases'])
            ->orderBy('created_at', 'desc')
            ->get();

        // Get purchase statistics
        $allPurchases = CoachPlanPurchase::whereIn('coach_plan_id', $plans->pluck('id'))->get();

        $purchaseStats = [
            'paid' => $allPurchases->where('status', 'paid')->where('ends_at', '>', now())->count(),
            'pending' => $allPurchases->where('status', 'pending')->count(),
            'expired' => $allPurchases->where('status', 'paid')->where('ends_at', '<=', now())->count(),
            'cancelled' => $allPurchases->where('status', 'cancelled')->count(),
            'totalRevenue' => $allPurchases->where('status', 'paid')->sum('amount'),
        ];

        return Inertia::render('Coach/Plans/Index', [
            'plans' => $plans,
            'paypal_enabled' => $user->paypal_enabled,
            'paypal_email' => $user->paypal_email,
            'paypal_me_link' => $user->paypal_me_link,
            'purchaseStats' => $purchaseStats,
        ]);
    }

    /**
     * Show the form for creating a new plan.
     */
    public function create(Request $request): Response
    {
        return Inertia::render('Coach/Plans/Create');
    }

    /**
     * Store a newly created plan.
     */
    public function store(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'description' => 'nullable|string|max:2000',
            'hero_title' => 'nullable|string|max:255',
            'hero_subtitle' => 'nullable|string|max:255',
            'badge' => 'nullable|string|max:100',
            'price' => 'required|numeric|min:0',
            'currency' => 'nullable|string|max:10',
            'currency_symbol' => 'nullable|string|max:5',
            'duration_days' => 'required|integer|min:1',
            'features' => 'nullable|array',
            'target_points' => 'nullable|array',
            'faqs' => 'nullable|array',
            'is_active' => 'boolean',
            'is_public' => 'boolean',
            'max_clients' => 'nullable|integer|min:1',
            'image' => 'nullable|image|max:2048',
            'hero_image' => 'nullable|image|max:4096',
        ]);

        $user = $request->user();

        // Handle image upload with compression
        if ($request->hasFile('image')) {
            $validated['image'] = $this->processAndStoreImage(
                $request->file('image'),
                'coach-plans',
                800,
                800
            );
        }

        // Handle hero image upload
        if ($request->hasFile('hero_image')) {
            $validated['hero_image'] = $this->processAndStoreImage(
                $request->file('hero_image'),
                'coach-plans/heroes',
                1920,
                1080
            );
        }

        $validated['coach_id'] = $user->id;
        $validated['slug'] = Str::slug($validated['name']) . '-' . Str::random(6);

        $plan = $user->coachPlans()->create($validated);

        // Log creation
        CoachPlanAuditLog::logAction($plan, 'created', [
            'name' => $validated['name'],
            'price' => $validated['price'],
        ]);

        return redirect()->route('coach.plans.edit', $plan->id)
            ->with('success', 'Plan creado exitosamente. Completa los detalles de tu landing page.');
    }

    /**
     * Display the specified plan.
     */
    public function show(Request $request, CoachPlan $plan): Response
    {
        $user = $request->user();

        if ($plan->coach_id !== $user->id) {
            abort(403);
        }

        $plan->load(['purchases.client']);

        return Inertia::render('Coach/Plans/Show', [
            'plan' => $plan,
            'purchases' => $plan->purchases()->with(['client', 'receipts'])->orderBy('created_at', 'desc')->paginate(10),
        ]);
    }

    /**
     * Show the form for editing the specified plan.
     */
    public function edit(Request $request, CoachPlan $plan): Response
    {
        $user = $request->user();

        if ($plan->coach_id !== $user->id) {
            abort(403);
        }

        // Get recent audit logs
        $auditLogs = $plan->auditLogs()
            ->with('user:id,name')
            ->take(20)
            ->get();

        // Get payment methods
        $paymentMethods = $user->paymentMethods()
            ->ordered()
            ->get()
            ->map(fn($method) => array_merge($method->toArray(), [
                'display_name' => $method->display_name,
                'type_label' => $method->type_label,
                'masked_account' => $method->masked_account_number,
                'bank_logo_url' => $method->bank_logo ? asset('storage/' . $method->bank_logo) : null,
            ]));

        return Inertia::render('Coach/Plans/Edit', [
            'plan' => $plan,
            'auditLogs' => $auditLogs,
            'currencies' => $this->getCurrencies(),
            'paymentMethods' => $paymentMethods,
            'dominicanBanks' => \App\Models\CoachPaymentMethod::getDominicanBankNames(),
            'dominicanBanksData' => \App\Models\CoachPaymentMethod::DOMINICAN_BANKS,
            'accountTypes' => \App\Models\CoachPaymentMethod::ACCOUNT_TYPES,
            'documentTypes' => \App\Models\CoachPaymentMethod::DOCUMENT_TYPES,
        ]);
    }

    /**
     * Update the specified plan.
     */
    public function update(Request $request, CoachPlan $plan): RedirectResponse
    {
        $user = $request->user();

        if ($plan->coach_id !== $user->id) {
            abort(403);
        }

        $validated = $this->validatePlanData($request);

        // Track changes for audit log
        $changes = $this->getChanges($plan, $validated);

        // Handle image uploads with compression
        $this->handleImageUploads($request, $validated, $plan);

        // Handle results images
        $this->handleResultsImages($request, $validated, $plan);

        // Update the plan
        $plan->update($validated);

        // Log the update
        if (!empty($changes)) {
            CoachPlanAuditLog::logAction($plan, 'updated', $changes);
        }

        return redirect()->route('coach.plans.edit', $plan->id)
            ->with('success', 'Plan actualizado exitosamente.');
    }

    /**
     * Autosave draft data (AJAX endpoint).
     */
    public function autosave(Request $request, CoachPlan $plan): JsonResponse
    {
        $user = $request->user();

        if ($plan->coach_id !== $user->id) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        $draftData = $request->input('draft_data', []);

        $plan->update([
            'draft_data' => $draftData,
            'last_autosave_at' => now(),
        ]);

        CoachPlanAuditLog::logAction($plan, 'autosaved', [
            'fields_count' => count($draftData),
        ]);

        return response()->json([
            'success' => true,
            'saved_at' => now()->format('H:i:s'),
            'message' => 'Borrador guardado automáticamente',
        ]);
    }

    /**
     * Upload a transformation result image.
     */
    public function uploadResultImage(Request $request, CoachPlan $plan): JsonResponse|RedirectResponse
    {
        $user = $request->user();

        if ($plan->coach_id !== $user->id) {
            if ($request->expectsJson()) {
                return response()->json(['error' => 'Unauthorized'], 403);
            }
            abort(403);
        }

        $request->validate([
            'before_image' => 'required|image|max:10240',
            'after_image' => 'nullable|image|max:10240',
            'client_name' => 'nullable|string|max:100',
            'description' => 'nullable|string|max:500',
            'transformation_duration' => 'nullable|string|max:100',
            'testimonial' => 'nullable|string|max:1000',
            'category' => 'nullable|string|max:50',
            'order' => 'nullable|integer|min:0',
        ]);

        $results = $plan->results_images ?? [];

        try {
            // Process and compress images
            $beforePath = $this->processAndStoreImage(
                $request->file('before_image'),
                'coach-plans/results',
                800,
                1000
            );

            $afterPath = null;
            if ($request->hasFile('after_image')) {
                $afterPath = $this->processAndStoreImage(
                    $request->file('after_image'),
                    'coach-plans/results',
                    800,
                    1000
                );
            }

            $newResult = [
                'id' => Str::uuid()->toString(),
                'before' => $beforePath,
                'after' => $afterPath,
                'client_name' => $request->input('client_name', ''),
                'description' => $request->input('description', ''),
                'transformation_duration' => $request->input('transformation_duration', ''),
                'testimonial' => $request->input('testimonial', ''),
                'category' => $request->input('category', 'general'),
                'order' => $request->input('order', count($results)),
                'created_at' => now()->toIso8601String(),
            ];

            $results[] = $newResult;

            // Sort by order
            usort($results, fn($a, $b) => ($a['order'] ?? 0) <=> ($b['order'] ?? 0));

            $plan->update(['results_images' => $results]);

            CoachPlanAuditLog::logAction($plan, 'result_added', [
                'client_name' => $newResult['client_name'],
            ]);

            if ($request->expectsJson()) {
                return response()->json([
                    'success' => true,
                    'result' => $newResult,
                    'message' => 'Resultado agregado exitosamente',
                ]);
            }

            return redirect()->route('coach.plans.edit', $plan->id)
                ->with('success', 'Imagen de resultado agregada exitosamente.');

        } catch (\Exception $e) {
            Log::error('Error uploading transformation result', [
                'plan_id' => $plan->id,
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
            ]);

            if ($request->expectsJson()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Error al procesar la imagen: ' . $e->getMessage(),
                ], 500);
            }

            return redirect()->route('coach.plans.edit', $plan->id)
                ->with('error', 'Error al procesar la imagen.');
        }
    }

    /**
     * Update a specific result's data.
     */
    public function updateResult(Request $request, CoachPlan $plan, string $resultId): JsonResponse
    {
        $user = $request->user();

        if ($plan->coach_id !== $user->id) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        $request->validate([
            'client_name' => 'nullable|string|max:100',
            'description' => 'nullable|string|max:500',
            'transformation_duration' => 'nullable|string|max:100',
            'testimonial' => 'nullable|string|max:1000',
            'category' => 'nullable|string|max:50',
            'order' => 'nullable|integer|min:0',
        ]);

        $results = $plan->results_images ?? [];
        $index = array_search($resultId, array_column($results, 'id'));

        if ($index === false) {
            return response()->json(['error' => 'Result not found'], 404);
        }

        // Update fields
        foreach (['client_name', 'description', 'transformation_duration', 'testimonial', 'category', 'order'] as $field) {
            if ($request->has($field)) {
                $results[$index][$field] = $request->input($field);
            }
        }

        // Handle after image upload
        if ($request->hasFile('after_image')) {
            // Delete old after image if exists
            if (!empty($results[$index]['after'])) {
                Storage::disk('public')->delete($results[$index]['after']);
            }

            $results[$index]['after'] = $this->processAndStoreImage(
                $request->file('after_image'),
                'coach-plans/results',
                800,
                1000
            );
        }

        // Sort by order
        usort($results, fn($a, $b) => ($a['order'] ?? 0) <=> ($b['order'] ?? 0));

        $plan->update(['results_images' => $results]);

        return response()->json([
            'success' => true,
            'result' => $results[$index],
            'message' => 'Resultado actualizado',
        ]);
    }

    /**
     * Delete a specific result.
     */
    public function deleteResult(Request $request, CoachPlan $plan, string $resultId): JsonResponse
    {
        $user = $request->user();

        if ($plan->coach_id !== $user->id) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        $results = $plan->results_images ?? [];
        $index = array_search($resultId, array_column($results, 'id'));

        if ($index === false) {
            return response()->json(['error' => 'Result not found'], 404);
        }

        // Delete images from storage
        if (!empty($results[$index]['before'])) {
            Storage::disk('public')->delete($results[$index]['before']);
        }
        if (!empty($results[$index]['after'])) {
            Storage::disk('public')->delete($results[$index]['after']);
        }

        // Remove from array
        array_splice($results, $index, 1);

        // Re-index order
        foreach ($results as $i => &$result) {
            $result['order'] = $i;
        }

        $plan->update(['results_images' => $results]);

        CoachPlanAuditLog::logAction($plan, 'result_removed');

        return response()->json([
            'success' => true,
            'message' => 'Resultado eliminado',
        ]);
    }

    /**
     * Reorder results.
     */
    public function reorderResults(Request $request, CoachPlan $plan): JsonResponse
    {
        $user = $request->user();

        if ($plan->coach_id !== $user->id) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        $request->validate([
            'order' => 'required|array',
            'order.*' => 'string',
        ]);

        $results = $plan->results_images ?? [];
        $newOrder = $request->input('order');
        $reorderedResults = [];

        foreach ($newOrder as $index => $resultId) {
            $resultIndex = array_search($resultId, array_column($results, 'id'));
            if ($resultIndex !== false) {
                $results[$resultIndex]['order'] = $index;
                $reorderedResults[] = $results[$resultIndex];
            }
        }

        $plan->update(['results_images' => $reorderedResults]);

        return response()->json([
            'success' => true,
            'message' => 'Orden actualizado',
        ]);
    }

    /**
     * Get audit logs for a plan.
     */
    public function auditLogs(Request $request, CoachPlan $plan): JsonResponse
    {
        $user = $request->user();

        if ($plan->coach_id !== $user->id) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        $logs = $plan->auditLogs()
            ->with('user:id,name')
            ->paginate(50);

        return response()->json($logs);
    }

    /**
     * Update a result image's after image.
     */
    public function updateResultAfterImage(Request $request, CoachPlan $plan, int $index): RedirectResponse
    {
        $user = $request->user();

        if ($plan->coach_id !== $user->id) {
            abort(403);
        }

        $request->validate([
            'after_image' => 'required|image|max:4096',
        ]);

        $results = $plan->results_images ?? [];

        if (!isset($results[$index])) {
            return back()->with('error', 'Resultado no encontrado.');
        }

        $results[$index]['after'] = $this->processAndStoreImage(
            $request->file('after_image'),
            'coach-plans/results',
            800,
            1000
        );

        $plan->update(['results_images' => $results]);

        return redirect()->route('coach.plans.edit', $plan->id)
            ->with('success', 'Imagen actualizada exitosamente.');
    }

    /**
     * Remove the specified plan.
     */
    public function destroy(Request $request, CoachPlan $plan): RedirectResponse
    {
        $user = $request->user();

        if ($plan->coach_id !== $user->id) {
            abort(403);
        }

        if ($plan->activePurchases()->count() > 0) {
            return back()->with('error', 'No puedes eliminar un plan con compras activas.');
        }

        // Log before deletion
        CoachPlanAuditLog::logAction($plan, 'deleted', [
            'name' => $plan->name,
        ]);

        // Delete associated images
        if ($plan->image) {
            Storage::disk('public')->delete($plan->image);
        }
        if ($plan->hero_image) {
            Storage::disk('public')->delete($plan->hero_image);
        }
        if ($plan->coach_section_photo) {
            Storage::disk('public')->delete($plan->coach_section_photo);
        }
        foreach ($plan->results_images ?? [] as $result) {
            if (!empty($result['before'])) {
                Storage::disk('public')->delete($result['before']);
            }
            if (!empty($result['after'])) {
                Storage::disk('public')->delete($result['after']);
            }
        }

        $plan->delete();

        return redirect()->route('coach.plans.index')
            ->with('success', 'Plan eliminado exitosamente.');
    }

    /**
     * Show PayPal settings form.
     */
    public function paypalSettings(Request $request): Response
    {
        $user = $request->user();

        return Inertia::render('Coach/Plans/PaypalSettings', [
            'paypal_email' => $user->paypal_email,
            'paypal_me_link' => $user->paypal_me_link,
            'paypal_enabled' => $user->paypal_enabled,
        ]);
    }

    /**
     * Update PayPal settings.
     */
    public function updatePaypalSettings(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'paypal_email' => 'nullable|email|max:255',
            'paypal_me_link' => 'nullable|url|max:255',
            'paypal_enabled' => 'boolean',
        ]);

        if ($validated['paypal_me_link'] && !str_contains($validated['paypal_me_link'], 'paypal.me/')) {
            return back()->withErrors(['paypal_me_link' => 'El enlace de PayPal.me debe ser válido (ej: https://paypal.me/tunombre)']);
        }

        $request->user()->update($validated);

        return back()->with('success', 'Configuración de PayPal actualizada.');
    }

    /**
     * Get public URL for a plan.
     */
    public function publicLink(Request $request, CoachPlan $plan): Response
    {
        $user = $request->user();

        if ($plan->coach_id !== $user->id) {
            abort(403);
        }

        return Inertia::render('Coach/Plans/PublicLink', [
            'plan' => $plan,
            'publicUrl' => route('public.coach-plan', $plan->slug),
        ]);
    }

    /**
     * Mark a purchase as paid.
     */
    public function markPurchasePaid(Request $request, CoachPlanPurchase $purchase): RedirectResponse
    {
        $user = $request->user();

        if ($purchase->coachPlan->coach_id !== $user->id) {
            abort(403);
        }

        $request->validate([
            'payment_reference' => 'nullable|string|max:255',
        ]);

        $purchase->markAsPaid($request->payment_reference);

        // Notify buyer that their purchase has been confirmed
        try {
            if ($purchase->user) {
                $purchase->user->notify(new \App\Notifications\CoachPlanPurchaseConfirmed($purchase));
            }
        } catch (\Exception $e) {
            Log::warning('Failed to notify buyer about confirmed purchase: ' . $e->getMessage());
        }

        return back()->with('success', 'Pago confirmado exitosamente.');
    }

    /**
     * Cancel a purchase.
     */
    public function cancelPurchase(Request $request, CoachPlanPurchase $purchase): RedirectResponse
    {
        $user = $request->user();

        if ($purchase->coachPlan->coach_id !== $user->id) {
            abort(403);
        }

        if ($purchase->status !== 'pending') {
            return back()->with('error', 'Solo puedes cancelar compras pendientes.');
        }

        $purchase->update(['status' => 'cancelled']);

        // Send notification to buyer
        if ($purchase->user) {
            $purchase->user->notify(new \App\Notifications\CoachPlanPurchaseCancelled($purchase));
        }

        return back()->with('success', 'Compra cancelada.');
    }

    /**
     * Suspend a purchase.
     */
    public function suspendPurchase(Request $request, CoachPlanPurchase $purchase): RedirectResponse
    {
        $user = $request->user();

        if ($purchase->coachPlan->coach_id !== $user->id) {
            abort(403);
        }

        if ($purchase->status !== 'paid') {
            return back()->with('error', 'Solo puedes suspender compras activas (pagadas).');
        }

        $reason = $request->input('reason');
        $purchase->suspend($reason);

        return back()->with('success', 'Acceso suspendido. Se ha notificado al cliente.');
    }

    /**
     * Reactivate a suspended purchase.
     */
    public function reactivatePurchase(Request $request, CoachPlanPurchase $purchase): RedirectResponse
    {
        $user = $request->user();

        if ($purchase->coachPlan->coach_id !== $user->id) {
            abort(403);
        }

        if ($purchase->status !== 'suspended') {
            return back()->with('error', 'Solo puedes reactivar compras suspendidas.');
        }

        $purchase->reactivate();

        // Notify buyer of reactivation
        if ($purchase->user) {
            $purchase->user->notify(new \App\Notifications\CoachPlanPurchaseReactivated($purchase));
        }

        return back()->with('success', 'Acceso reactivado exitosamente.');
    }

    /**
     * Send payment reminder to buyer.
     */
    public function sendPaymentReminder(Request $request, CoachPlanPurchase $purchase): RedirectResponse
    {
        $user = $request->user();

        if ($purchase->coachPlan->coach_id !== $user->id) {
            abort(403);
        }

        if ($purchase->status !== 'pending') {
            return back()->with('error', 'Solo puedes enviar recordatorios a compras pendientes.');
        }

        if ($purchase->user) {
            $purchase->user->notify(new \App\Notifications\CoachPlanPaymentReminder($purchase));
        } elseif ($purchase->buyer_email) {
            // Create temporary notification recipient
            $tempUser = new \App\Models\User([
                'email' => $purchase->buyer_email,
                'name' => $purchase->buyer_name,
            ]);
            $tempUser->notify(new \App\Notifications\CoachPlanPaymentReminder($purchase));
        }

        return back()->with('success', 'Recordatorio de pago enviado.');
    }

    /**
     * Update a purchase (edit buyer info, amount, notes, status).
     */
    public function updatePurchase(Request $request, CoachPlanPurchase $purchase): RedirectResponse
    {
        $user = $request->user();

        if ($purchase->coachPlan->coach_id !== $user->id) {
            abort(403);
        }

        $request->validate([
            'buyer_name' => 'required|string|max:255',
            'buyer_email' => 'required|email|max:255',
            'buyer_phone' => 'nullable|string|max:50',
            'amount' => 'required|numeric|min:0',
            'status' => 'required|in:pending,paid,cancelled,refunded,suspended',
            'notes' => 'nullable|string|max:1000',
            'payment_reference' => 'nullable|string|max:255',
        ]);

        $oldStatus = $purchase->status;
        $newStatus = $request->status;

        $updateData = [
            'buyer_name' => $request->buyer_name,
            'buyer_email' => $request->buyer_email,
            'buyer_phone' => $request->buyer_phone,
            'amount' => $request->amount,
            'notes' => $request->notes,
            'payment_reference' => $request->payment_reference,
        ];

        // Handle status transitions
        if ($oldStatus !== $newStatus) {
            $updateData['status'] = $newStatus;

            if ($newStatus === 'paid' && $oldStatus !== 'paid') {
                $updateData['paid_at'] = now();
                $updateData['starts_at'] = now();
                $updateData['ends_at'] = now()->addDays($purchase->coachPlan->duration_days);
                $purchase->coachPlan->increment('current_clients');
            }

            if ($newStatus === 'refunded') {
                $updateData['paid_at'] = null;
                if ($oldStatus === 'paid') {
                    $purchase->coachPlan->decrement('current_clients');
                }
            }

            if ($newStatus === 'cancelled') {
                if ($oldStatus === 'paid') {
                    $purchase->coachPlan->decrement('current_clients');
                }
            }
        }

        $purchase->update($updateData);

        return back()->with('success', 'Compra actualizada exitosamente.');
    }

    /**
     * Refund a purchase.
     */
    public function refundPurchase(Request $request, CoachPlanPurchase $purchase): RedirectResponse
    {
        $user = $request->user();

        if ($purchase->coachPlan->coach_id !== $user->id) {
            abort(403);
        }

        if (!in_array($purchase->status, ['paid', 'suspended'])) {
            return back()->with('error', 'Solo puedes reembolsar compras pagadas o suspendidas.');
        }

        $purchase->update([
            'status' => 'refunded',
        ]);

        // Decrement client count
        $purchase->coachPlan->decrement('current_clients');

        // Notify buyer of refund
        if ($purchase->user) {
            $purchase->user->notify(new \App\Notifications\CoachPlanPurchaseRefunded($purchase));
        }

        return back()->with('success', 'Compra marcada como reembolsada.');
    }

    /**
     * Delete a single purchase.
     */
    public function deletePurchase(Request $request, CoachPlanPurchase $purchase): RedirectResponse
    {
        $user = $request->user();

        if ($purchase->coachPlan->coach_id !== $user->id) {
            abort(403);
        }

        if ($purchase->status === 'paid') {
            $purchase->coachPlan->decrement('current_clients');
        }

        $purchase->delete();

        return back()->with('success', 'Compra eliminada.');
    }

    /**
     * Bulk confirm purchases.
     */
    public function bulkConfirmPurchases(Request $request): RedirectResponse
    {
        $request->validate([
            'purchase_ids' => 'required|array|min:1',
            'purchase_ids.*' => 'integer|exists:coach_plan_purchases,id',
        ]);

        $user = $request->user();
        $confirmed = 0;
        $errors = 0;

        $purchases = CoachPlanPurchase::whereIn('id', $request->purchase_ids)
            ->whereHas('coachPlan', function ($query) use ($user) {
                $query->where('coach_id', $user->id);
            })
            ->where('status', 'pending')
            ->get();

        foreach ($purchases as $purchase) {
            try {
                $purchase->update([
                    'status' => 'paid',
                    'paid_at' => now(),
                    'ends_at' => now()->addDays($purchase->coachPlan->duration_days),
                ]);

                // Notify the buyer
                if ($purchase->user) {
                    $purchase->user->notify(new \App\Notifications\CoachPlanPurchaseConfirmed($purchase));
                } elseif ($purchase->buyer_email) {
                    $tempUser = new \App\Models\User([
                        'email' => $purchase->buyer_email,
                        'name' => $purchase->buyer_name,
                    ]);
                    $tempUser->notify(new \App\Notifications\CoachPlanPurchaseConfirmed($purchase));
                }

                $confirmed++;
            } catch (\Exception $e) {
                $errors++;
            }
        }

        $message = $confirmed > 0 ? "$confirmed compras confirmadas." : 'No se confirmaron compras.';
        if ($errors > 0) {
            $message .= " $errors errores.";
        }

        return back()->with('success', $message);
    }

    /**
     * Bulk cancel purchases.
     */
    public function bulkCancelPurchases(Request $request): RedirectResponse
    {
        $request->validate([
            'purchase_ids' => 'required|array|min:1',
            'purchase_ids.*' => 'integer|exists:coach_plan_purchases,id',
        ]);

        $user = $request->user();
        $cancelled = 0;

        $purchases = CoachPlanPurchase::whereIn('id', $request->purchase_ids)
            ->whereHas('coachPlan', function ($query) use ($user) {
                $query->where('coach_id', $user->id);
            })
            ->whereIn('status', ['pending', 'paid'])
            ->get();

        foreach ($purchases as $purchase) {
            $purchase->update(['status' => 'cancelled']);
            $cancelled++;

            // Send notification to buyer (consistent with cancelPurchase)
            if ($purchase->user) {
                $purchase->user->notify(new \App\Notifications\CoachPlanPurchaseCancelled($purchase));
            }
        }

        return back()->with('success', "$cancelled compras canceladas.");
    }

    /**
     * Bulk delete purchases.
     */
    public function bulkDeletePurchases(Request $request): RedirectResponse
    {
        $request->validate([
            'purchase_ids' => 'required|array|min:1',
            'purchase_ids.*' => 'integer|exists:coach_plan_purchases,id',
        ]);

        $user = $request->user();

        $deleted = CoachPlanPurchase::whereIn('id', $request->purchase_ids)
            ->whereHas('coachPlan', function ($query) use ($user) {
                $query->where('coach_id', $user->id);
            })
            ->delete();

        return back()->with('success', "$deleted compras eliminadas.");
    }

    /**
     * Validate plan data for update.
     */
    private function validatePlanData(Request $request): array
    {
        $rules = [
            'name' => 'required|string|max:255',
            'slug' => 'nullable|string|max:255|regex:/^[a-z0-9-]+$/',
            'seo_title' => 'nullable|string|max:255',
            'seo_description' => 'nullable|string|max:500',
            'seo_keywords' => 'nullable|string|max:500',
            'description' => 'nullable|string|max:2000',
            'hero_title' => 'nullable|string|max:255',
            'hero_subtitle' => 'nullable|string|max:255',
            'badge' => 'nullable|string|max:100',
            'price' => 'required|numeric|min:0',
            'currency' => 'nullable|string|max:10',
            'currency_symbol' => 'nullable|string|max:5',
            'duration_days' => 'required|integer|min:1',
            'features' => 'nullable|array',
            'target_points' => 'nullable|array',
            'faqs' => 'nullable|array',
            'results_images' => 'nullable|array',
            'is_active' => 'boolean',
            'is_public' => 'boolean',
            'max_clients' => 'nullable|integer|min:1',
            'new_results_images' => 'nullable|array',
            'new_results_images.*.before' => 'nullable|image|max:4096',
            'new_results_images.*.after' => 'nullable|image|max:4096',
            'new_results_images.*.client_name' => 'nullable|string|max:100',
            'new_results_images.*.description' => 'nullable|string|max:500',
            'new_results_images.*.transformation_duration' => 'nullable|string|max:100',
            'new_results_images.*.testimonial' => 'nullable|string|max:1000',
            // Coach section
            'coach_section_title' => 'nullable|string|max:255',
            'coach_section_bio' => 'nullable|string|max:2000',
            'coach_section_tagline' => 'nullable|string|max:255',
            'coach_section_stats' => 'nullable|string|max:100',
            // Landing page fields
            'show_top_banner' => 'boolean',
            'top_banner_text' => 'nullable|string|max:500',
            'hero_badge' => 'nullable|string|max:255',
            'hero_description' => 'nullable|string|max:2000',
            'hero_cta_text' => 'nullable|string|max:100',
            'hero_secondary_cta_text' => 'nullable|string|max:100',
            'hero_stats' => 'nullable|array',
            'hero_stats.*.title' => 'nullable|string|max:100',
            'hero_stats.*.subtitle' => 'nullable|string|max:100',
            'method_title' => 'nullable|string|max:255',
            'method_subtitle' => 'nullable|string|max:500',
            'method_items' => 'nullable|array',
            'method_items.*.title' => 'nullable|string|max:255',
            'method_items.*.description' => 'nullable|string|max:1000',
            'method_items.*.icon' => 'nullable|string|max:50',
            'includes_title' => 'nullable|string|max:255',
            'includes_subtitle' => 'nullable|string|max:500',
            'includes_items' => 'nullable|array',
            'includes_items.*.title' => 'nullable|string|max:255',
            'includes_items.*.description' => 'nullable|string|max:500',
            'how_it_works_title' => 'nullable|string|max:255',
            'how_it_works_subtitle' => 'nullable|string|max:500',
            'how_it_works_steps' => 'nullable|array',
            'how_it_works_steps.*.title' => 'nullable|string|max:255',
            'how_it_works_steps.*.description' => 'nullable|string|max:1000',
            'nav_links' => 'nullable|array',
            // Pricing section
            'pricing_title' => 'nullable|string|max:255',
            'pricing_subtitle' => 'nullable|string|max:500',
            'pricing_guarantee_text' => 'nullable|string|max:500',
            'pricing_tiers' => 'nullable|array',
            'pricing_tiers.*.name' => 'nullable|string|max:100',
            'pricing_tiers.*.description' => 'nullable|string|max:255',
            'pricing_tiers.*.price' => 'nullable|numeric|min:0',
            'pricing_tiers.*.period' => 'nullable|string|max:50',
            'pricing_tiers.*.features' => 'nullable|array',
            'pricing_tiers.*.featured' => 'boolean',
            'pricing_tiers.*.cta' => 'nullable|string|max:100',
            // Results section
            'results_title' => 'nullable|string|max:255',
            'results_subtitle' => 'nullable|string|max:500',
            // FAQ section
            'faq_title' => 'nullable|string|max:255',
            'faq_subtitle' => 'nullable|string|max:500',
            // Final CTA
            'final_cta_title' => 'nullable|string|max:255',
            'final_cta_subtitle' => 'nullable|string|max:500',
            'final_cta_button_text' => 'nullable|string|max:100',
            // Landing colors
            'landing_colors' => 'nullable|array',
            'landing_colors.bg_primary' => 'nullable|string|max:30',
            'landing_colors.bg_secondary' => 'nullable|string|max:30',
            'landing_colors.bg_card' => 'nullable|string|max:30',
            'landing_colors.accent' => 'nullable|string|max:30',
            'landing_colors.text_primary' => 'nullable|string|max:30',
            'landing_colors.text_secondary' => 'nullable|string|max:30',
            'landing_colors.header_bg' => 'nullable|string|max:30',
            'landing_colors.banner_bg' => 'nullable|string|max:30',
        ];

        // Only validate image fields if they are actual files
        if ($request->hasFile('image')) {
            $rules['image'] = 'image|max:2048';
        }
        if ($request->hasFile('hero_image')) {
            $rules['hero_image'] = 'image|max:4096';
        }
        if ($request->hasFile('coach_section_photo')) {
            $rules['coach_section_photo'] = 'image|max:2048';
        }

        return $request->validate($rules);
    }

    /**
     * Handle image uploads.
     */
    private function handleImageUploads(Request $request, array &$validated, CoachPlan $plan): void
    {
        if ($request->hasFile('image')) {
            if ($plan->image) {
                Storage::disk('public')->delete($plan->image);
            }
            $validated['image'] = $this->processAndStoreImage(
                $request->file('image'),
                'coach-plans',
                800,
                800
            );
        }

        if ($request->hasFile('hero_image')) {
            if ($plan->hero_image) {
                Storage::disk('public')->delete($plan->hero_image);
            }
            $validated['hero_image'] = $this->processAndStoreImage(
                $request->file('hero_image'),
                'coach-plans/heroes',
                1920,
                1080
            );
        }

        if ($request->hasFile('coach_section_photo')) {
            if ($plan->coach_section_photo) {
                Storage::disk('public')->delete($plan->coach_section_photo);
            }
            $validated['coach_section_photo'] = $this->processAndStoreImage(
                $request->file('coach_section_photo'),
                'coach-plans/coach-photos',
                600,
                600
            );
        }
    }

    /**
     * Handle results images.
     */
    private function handleResultsImages(Request $request, array &$validated, CoachPlan $plan): void
    {
        $existingResults = [];

        if (!empty($validated['results_images'])) {
            foreach ($validated['results_images'] as $result) {
                if (is_array($result) && isset($result['before']) && is_string($result['before'])) {
                    $existingResults[] = [
                        'id' => $result['id'] ?? Str::uuid()->toString(),
                        'before' => $result['before'],
                        'after' => $result['after'] ?? null,
                        'client_name' => $result['client_name'] ?? $result['name'] ?? '',
                        'description' => $result['description'] ?? '',
                        'transformation_duration' => $result['transformation_duration'] ?? '',
                        'testimonial' => $result['testimonial'] ?? '',
                        'category' => $result['category'] ?? 'general',
                        'order' => $result['order'] ?? 0,
                        'created_at' => $result['created_at'] ?? now()->toIso8601String(),
                    ];
                }
            }
        }

        if ($request->has('new_results_images')) {
            $newResults = $request->input('new_results_images', []);
            foreach ($newResults as $index => $resultData) {
                $beforePath = null;
                $afterPath = null;

                if ($request->hasFile("new_results_images.{$index}.before")) {
                    $beforePath = $this->processAndStoreImage(
                        $request->file("new_results_images.{$index}.before"),
                        'coach-plans/results',
                        800,
                        1000
                    );
                }

                if ($request->hasFile("new_results_images.{$index}.after")) {
                    $afterPath = $this->processAndStoreImage(
                        $request->file("new_results_images.{$index}.after"),
                        'coach-plans/results',
                        800,
                        1000
                    );
                }

                if ($beforePath) {
                    $existingResults[] = [
                        'id' => Str::uuid()->toString(),
                        'before' => $beforePath,
                        'after' => $afterPath,
                        'client_name' => $resultData['client_name'] ?? $resultData['name'] ?? '',
                        'description' => $resultData['description'] ?? '',
                        'transformation_duration' => $resultData['transformation_duration'] ?? '',
                        'testimonial' => $resultData['testimonial'] ?? '',
                        'category' => $resultData['category'] ?? 'general',
                        'order' => count($existingResults),
                        'created_at' => now()->toIso8601String(),
                    ];
                }
            }
        }

        $validated['results_images'] = $existingResults;
        unset($validated['new_results_images']);
    }

    /**
     * Process and store an image with compression.
     */
    private function processAndStoreImage($file, string $path, int $maxWidth, int $maxHeight): string
    {
        $filename = Str::uuid() . '.webp';
        $fullPath = $path . '/' . $filename;

        try {
            // Try to use GD for compression
            $sourceImage = match ($file->getMimeType()) {
                'image/jpeg', 'image/jpg' => imagecreatefromjpeg($file->getPathname()),
                'image/png' => imagecreatefrompng($file->getPathname()),
                'image/gif' => imagecreatefromgif($file->getPathname()),
                'image/webp' => imagecreatefromwebp($file->getPathname()),
                default => null,
            };

            if ($sourceImage) {
                $width = imagesx($sourceImage);
                $height = imagesy($sourceImage);

                // Calculate new dimensions
                $ratio = min($maxWidth / $width, $maxHeight / $height);
                if ($ratio < 1) {
                    $newWidth = (int) ($width * $ratio);
                    $newHeight = (int) ($height * $ratio);
                } else {
                    $newWidth = $width;
                    $newHeight = $height;
                }

                // Create resized image
                $resizedImage = imagecreatetruecolor($newWidth, $newHeight);

                // Preserve transparency for PNG
                imagealphablending($resizedImage, false);
                imagesavealpha($resizedImage, true);

                imagecopyresampled(
                    $resizedImage,
                    $sourceImage,
                    0, 0, 0, 0,
                    $newWidth, $newHeight,
                    $width, $height
                );

                // Save as WebP
                ob_start();
                imagewebp($resizedImage, null, 85);
                $imageData = ob_get_clean();

                Storage::disk('public')->put($fullPath, $imageData);

                imagedestroy($sourceImage);
                imagedestroy($resizedImage);
            } else {
                // Fallback to simple storage
                $filename = Str::uuid() . '.' . $file->getClientOriginalExtension();
                $fullPath = $path . '/' . $filename;
                $file->storeAs($path, $filename, 'public');
            }
        } catch (\Exception $e) {
            // Fallback to simple storage if compression fails
            $filename = Str::uuid() . '.' . $file->getClientOriginalExtension();
            $fullPath = $path . '/' . $filename;
            $file->storeAs($path, $filename, 'public');
        }

        return $fullPath;
    }

    /**
     * Get changes between old and new data.
     */
    private function getChanges(CoachPlan $plan, array $newData): array
    {
        $changes = [];
        $trackFields = ['name', 'price', 'duration_days', 'is_active', 'is_public'];

        foreach ($trackFields as $field) {
            if (isset($newData[$field]) && $plan->{$field} != $newData[$field]) {
                $changes[$field] = [
                    'old' => $plan->{$field},
                    'new' => $newData[$field],
                ];
            }
        }

        return $changes;
    }

    /**
     * Get available currencies.
     */
    private function getCurrencies(): array
    {
        return [
            ['code' => 'USD', 'symbol' => '$', 'name' => 'Dólar estadounidense'],
            ['code' => 'EUR', 'symbol' => '€', 'name' => 'Euro'],
            ['code' => 'MXN', 'symbol' => '$', 'name' => 'Peso mexicano'],
            ['code' => 'COP', 'symbol' => '$', 'name' => 'Peso colombiano'],
            ['code' => 'ARS', 'symbol' => '$', 'name' => 'Peso argentino'],
            ['code' => 'CLP', 'symbol' => '$', 'name' => 'Peso chileno'],
            ['code' => 'PEN', 'symbol' => 'S/', 'name' => 'Sol peruano'],
            ['code' => 'DOP', 'symbol' => 'RD$', 'name' => 'Peso dominicano'],
            ['code' => 'GBP', 'symbol' => '£', 'name' => 'Libra esterlina'],
        ];
    }
}
