<?php

namespace App\Http\Controllers\Coach;

use App\Http\Controllers\Controller;
use App\Models\Client;
use App\Models\Invoice;
use App\Models\MealPlan;
use App\Models\Setting;
use App\Models\Workout;
use App\Services\PdfService;
use App\Services\PdfBrowsershotService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\BinaryFileResponse;

class PdfController extends Controller
{
    protected PdfService $pdfService;
    protected PdfBrowsershotService $browsershotService;

    public function __construct(PdfService $pdfService, PdfBrowsershotService $browsershotService)
    {
        $this->pdfService = $pdfService;
        $this->browsershotService = $browsershotService;
    }

    /**
     * Determine which PDF engine to use.
     * Returns 'browsershot' for modern PDFs or 'dompdf' for legacy.
     */
    private function getPdfEngine(): string
    {
        return Setting::get('pdf_engine', 'browsershot');
    }

    /**
     * Download invoice PDF.
     */
    public function invoice(Request $request, Invoice $invoice): BinaryFileResponse
    {
        $this->authorize('view', $invoice);

        try {
            // Use modern Browsershot or fallback to DomPDF
            if ($this->getPdfEngine() === 'browsershot') {
                $filename = $this->browsershotService->generateInvoice($invoice);
            } else {
                $filename = $this->pdfService->generateInvoice($invoice);
            }

            $filePath = storage_path("app/public/{$filename}");
            
            if (!file_exists($filePath)) {
                abort(404, 'No se pudo generar el PDF de la factura.');
            }

            return response()->download(
                $filePath,
                "factura-{$invoice->invoice_number}.pdf"
            );
        } catch (\Exception $e) {
            Log::error('Invoice PDF Error: ' . $e->getMessage());
            // Fallback to DomPDF if Browsershot fails
            $filename = $this->pdfService->generateInvoice($invoice);
            $filePath = storage_path("app/public/{$filename}");
            return response()->download($filePath, "factura-{$invoice->invoice_number}.pdf");
        }
    }

    /**
     * Download workout PDF.
     */
    public function workout(Request $request, Client $client, Workout $workout)
    {
        $this->authorize('view', $client);

        try {
            // Load required relationships
            $workout->load('exercises', 'client');
            
            // Use modern Browsershot or fallback to DomPDF
            if ($this->getPdfEngine() === 'browsershot') {
                try {
                    $filename = $this->browsershotService->generateWorkout($workout);
                } catch (\Exception $e) {
                    Log::warning('Browsershot failed, using DomPDF: ' . $e->getMessage());
                    $filename = $this->pdfService->generateWorkout($workout);
                }
            } else {
                $filename = $this->pdfService->generateWorkout($workout);
            }
            
            // Use Storage::disk('public') to check file existence
            $disk = Storage::disk('public');
            
            if (!$disk->exists($filename)) {
                Log::error("PDF file not found on public disk: {$filename}");
                return redirect()->back()->with('error', 'No se pudo generar el PDF de la rutina.');
            }

            // Get the full path for download
            $filePath = $disk->path($filename);
            
            return response()->download(
                $filePath,
                "rutina-{$client->name}-{$workout->name}.pdf"
            );
            
        } catch (\Exception $e) {
            Log::error('Workout PDF Generation Error: ' . $e->getMessage() . ' at ' . $e->getFile() . ':' . $e->getLine());
            return redirect()->back()->with('error', 'Error al generar el PDF: ' . $e->getMessage());
        }
    }

    /**
     * Download meal plan PDF.
     */
    public function mealPlan(Request $request, Client $client, MealPlan $meal_plan)
    {
        $this->authorize('view', $client);

        try {
            // Load required relationships
            $meal_plan->load('dietPlans.items.food', 'client');
            
            // Get language from query parameter (default to Spanish)
            $lang = $request->query('lang', 'es');
            
            // Use modern Browsershot or fallback to DomPDF
            if ($this->getPdfEngine() === 'browsershot') {
                try {
                    $filename = $this->browsershotService->generateMealPlan($meal_plan, $lang);
                } catch (\Exception $e) {
                    Log::warning('Browsershot failed, using DomPDF: ' . $e->getMessage());
                    $filename = $this->pdfService->generateMealPlan($meal_plan, $lang);
                }
            } else {
                $filename = $this->pdfService->generateMealPlan($meal_plan, $lang);
            }
            
            // Use Storage::disk('public') to check file existence
            $disk = Storage::disk('public');
            
            if (!$disk->exists($filename)) {
                Log::error("PDF file not found on public disk: {$filename}");
                return redirect()->back()->with('error', 'No se pudo generar el PDF de la dieta.');
            }

            // Get the full path for download
            $filePath = $disk->path($filename);
            
            // File name based on language
            $langSuffix = $lang === 'en' ? '-EN' : '-ES';
            
            return response()->download(
                $filePath,
                "dieta-{$client->name}-{$meal_plan->name}{$langSuffix}.pdf"
            );
            
        } catch (\Exception $e) {
            Log::error('PDF Generation Error: ' . $e->getMessage() . ' at ' . $e->getFile() . ':' . $e->getLine());
            return redirect()->back()->with('error', 'Error al generar el PDF: ' . $e->getMessage());
        }
    }

    /**
     * Preview workout PDF (inline viewing).
     */
    public function previewWorkout(Request $request, Client $client, Workout $workout)
    {
        $this->authorize('view', $client);

        try {
            $workout->load('exercises', 'client');
            
            // Use modern Browsershot or fallback to DomPDF
            if ($this->getPdfEngine() === 'browsershot') {
                try {
                    $filename = $this->browsershotService->generateWorkout($workout);
                } catch (\Exception $e) {
                    Log::warning('Browsershot preview failed, using DomPDF: ' . $e->getMessage());
                    $filename = $this->pdfService->generateWorkout($workout);
                }
            } else {
                $filename = $this->pdfService->generateWorkout($workout);
            }
            
            $disk = Storage::disk('public');
            
            if (!$disk->exists($filename)) {
                return response()->json(['error' => 'No se pudo generar el PDF de la rutina.'], 404);
            }

            // Stream the PDF for inline viewing
            return response($disk->get($filename), 200)
                ->header('Content-Type', 'application/pdf')
                ->header('Content-Disposition', 'inline; filename="rutina-' . $client->name . '-' . $workout->name . '.pdf"');
                
        } catch (\Exception $e) {
            Log::error('Workout PDF Preview Error: ' . $e->getMessage());
            return response()->json(['error' => 'Error al generar la vista previa'], 500);
        }
    }

    /**
     * Preview meal plan PDF (inline viewing).
     */
    public function previewMealPlan(Request $request, Client $client, MealPlan $meal_plan)
    {
        $this->authorize('view', $client);

        try {
            $meal_plan->load('dietPlans.items.food', 'client');
            
            // Use modern Browsershot or fallback to DomPDF
            if ($this->getPdfEngine() === 'browsershot') {
                try {
                    $filename = $this->browsershotService->generateMealPlan($meal_plan);
                } catch (\Exception $e) {
                    Log::warning('Browsershot preview failed, using DomPDF: ' . $e->getMessage());
                    $filename = $this->pdfService->generateMealPlan($meal_plan);
                }
            } else {
                $filename = $this->pdfService->generateMealPlan($meal_plan);
            }
            
            $disk = Storage::disk('public');
            
            if (!$disk->exists($filename)) {
                return response()->json(['error' => 'No se pudo generar el PDF de la dieta.'], 404);
            }

            // Stream the PDF for inline viewing
            return response($disk->get($filename), 200)
                ->header('Content-Type', 'application/pdf')
                ->header('Content-Disposition', 'inline; filename="dieta-' . $client->name . '-' . $meal_plan->name . '.pdf"');
                
        } catch (\Exception $e) {
            Log::error('MealPlan PDF Preview Error: ' . $e->getMessage());
            return response()->json(['error' => 'Error al generar la vista previa'], 500);
        }
    }
}

