<?php

namespace App\Http\Controllers;

use App\Models\Concours;
use App\Models\PdfTemplate;
use App\Models\PdfTemplateAttribute;
use App\Services\PdfGeneratorService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;

class PdfTemplateController extends Controller
{
    protected $pdfGenerator;

    public function __construct(PdfGeneratorService $pdfGenerator)
    {
        $this->pdfGenerator = $pdfGenerator;
    }

    /**
     * Display a listing of PDF templates for a concours
     */
    public function index(Concours $concours)
    {
        $templates = $concours->pdfTemplates()->orderBy('created_at', 'desc')->paginate(10);
        return view('backoffice.concours.pdf-templates.index', compact('concours', 'templates'));
    }

    /**
     * Show the form for creating a new PDF template
     */
    public function create(Concours $concours)
    {
        $availableCandidateAttributes = PdfTemplate::getAvailableCandidateAttributes();
        $availableConcoursAttributes = PdfTemplate::getAvailableConcoursAttributes();
        
        return view('backoffice.concours.pdf-templates.create', compact(
            'concours',
            'availableCandidateAttributes',
            'availableConcoursAttributes'
        ));
    }

    /**
     * Store a newly created PDF template in database
     */
    public function store(Request $request, Concours $concours)
    {
        $validated = $request->validate([
            'template_name' => 'required|string|max:255',
            'template_body' => 'nullable|string',
            'header_image' => 'nullable|file|mimes:jpeg,png,jpg,gif|max:5120',
            'header_pdf' => 'nullable|file|mimes:pdf|max:5120',
            'footer_image' => 'nullable|file|mimes:jpeg,png,jpg,gif|max:5120',
            'footer_pdf' => 'nullable|file|mimes:pdf|max:5120',
            'selected_attributes' => 'nullable|array',
            'selected_attributes.*' => 'string',
            'attribute_labels' => 'nullable|array',
        ]);

        $data = [
            'concours_id' => $concours->id,
            'template_name' => $validated['template_name'],
            'template_body' => $validated['template_body'] ?? null,
            'created_by' => auth()->id(),
        ];

        // Handle header image upload
        if ($request->hasFile('header_image')) {
            $path = $request->file('header_image')->store('pdf-templates/headers', 'concours');
            $data['header_image_path'] = $path;
        }

        // Handle header PDF upload
        if ($request->hasFile('header_pdf')) {
            $path = $request->file('header_pdf')->store('pdf-templates/headers', 'concours');
            $data['header_pdf_path'] = $path;
        }

        // Handle footer image upload
        if ($request->hasFile('footer_image')) {
            $path = $request->file('footer_image')->store('pdf-templates/footers', 'concours');
            $data['footer_image_path'] = $path;
        }

        // Handle footer PDF upload
        if ($request->hasFile('footer_pdf')) {
            $path = $request->file('footer_pdf')->store('pdf-templates/footers', 'concours');
            $data['footer_pdf_path'] = $path;
        }

        // Store selected attributes
        if (!empty($validated['selected_attributes'])) {
            $data['selected_attributes'] = $validated['selected_attributes'];
        }

        // Store attribute labels mapping
        if (!empty($validated['attribute_labels'])) {
            $data['attributes_labels'] = $validated['attribute_labels'];
        }

        // Create the template
        $template = new PdfTemplate($data);
        $template->save();

        // Create attribute records
        if (!empty($validated['selected_attributes'])) {
            $allAttributes = PdfTemplate::getAllAvailableAttributes();
            foreach ($validated['selected_attributes'] as $index => $attrKey) {
                if (isset($allAttributes[$attrKey])) {
                    $labelToSave = $validated['attribute_labels'][$attrKey] ?? $allAttributes[$attrKey];
                    PdfTemplateAttribute::create([
                        'pdf_template_id' => $template->id,
                        'attribute_key' => $attrKey,
                        'attribute_label' => $labelToSave,
                        'sort_order' => $index,
                    ]);
                }
            }
        }

        return redirect()->route('concours.pdf-templates.index', $concours)
                       ->with('success', 'تم إنشاء القالب بنجاح.');
    }

    /**
     * Show the form for editing a PDF template
     */
    public function edit(Concours $concours, PdfTemplate $pdfTemplate)
    {
        // Ensure the template belongs to this concours
        if ($pdfTemplate->concours_id !== $concours->id) {
            abort(403);
        }

        $availableCandidateAttributes = PdfTemplate::getAvailableCandidateAttributes();
        $availableConcoursAttributes = PdfTemplate::getAvailableConcoursAttributes();
        $selectedAttributes = $pdfTemplate->selected_attributes ?? [];

        return view('backoffice.concours.pdf-templates.edit', compact(
            'concours',
            'pdfTemplate',
            'availableCandidateAttributes',
            'availableConcoursAttributes',
            'selectedAttributes'
        ));
    }

    /**
     * Update the specified PDF template
     */
    public function update(Request $request, Concours $concours, PdfTemplate $pdfTemplate)
    {
        // Ensure the template belongs to this concours
        if ($pdfTemplate->concours_id !== $concours->id) {
            abort(403);
        }

        $validated = $request->validate([
            'template_name' => 'required|string|max:255',
            'template_body' => 'nullable|string',
            'header_image' => 'nullable|file|mimes:jpeg,png,jpg,gif|max:5120',
            'header_pdf' => 'nullable|file|mimes:pdf|max:5120',
            'footer_image' => 'nullable|file|mimes:jpeg,png,jpg,gif|max:5120',
            'footer_pdf' => 'nullable|file|mimes:pdf|max:5120',
            'selected_attributes' => 'nullable|array',
            'selected_attributes.*' => 'string',
            'attribute_labels' => 'nullable|array',
            'remove_header_image' => 'nullable|boolean',
            'remove_header_pdf' => 'nullable|boolean',
            'remove_footer_image' => 'nullable|boolean',
            'remove_footer_pdf' => 'nullable|boolean',
        ]);

        $updateData = [
            'template_name' => $validated['template_name'],
            'template_body' => $validated['template_body'] ?? null,
        ];

        // Handle header image
        if ($request->hasFile('header_image')) {
            if ($pdfTemplate->header_image_path && Storage::disk('concours')->exists($pdfTemplate->header_image_path)) {
                Storage::disk('concours')->delete($pdfTemplate->header_image_path);
            }
            $path = $request->file('header_image')->store('pdf-templates/headers', 'concours');
            $updateData['header_image_path'] = $path;
        } elseif ($request->boolean('remove_header_image')) {
            if ($pdfTemplate->header_image_path && Storage::disk('concours')->exists($pdfTemplate->header_image_path)) {
                Storage::disk('concours')->delete($pdfTemplate->header_image_path);
            }
            $updateData['header_image_path'] = null;
        }

        // Handle header PDF
        if ($request->hasFile('header_pdf')) {
            if ($pdfTemplate->header_pdf_path && Storage::disk('concours')->exists($pdfTemplate->header_pdf_path)) {
                Storage::disk('concours')->delete($pdfTemplate->header_pdf_path);
            }
            $path = $request->file('header_pdf')->store('pdf-templates/headers', 'concours');
            $updateData['header_pdf_path'] = $path;
        } elseif ($request->boolean('remove_header_pdf')) {
            if ($pdfTemplate->header_pdf_path && Storage::disk('concours')->exists($pdfTemplate->header_pdf_path)) {
                Storage::disk('concours')->delete($pdfTemplate->header_pdf_path);
            }
            $updateData['header_pdf_path'] = null;
        }

        // Handle footer image
        if ($request->hasFile('footer_image')) {
            if ($pdfTemplate->footer_image_path && Storage::disk('concours')->exists($pdfTemplate->footer_image_path)) {
                Storage::disk('concours')->delete($pdfTemplate->footer_image_path);
            }
            $path = $request->file('footer_image')->store('pdf-templates/footers', 'concours');
            $updateData['footer_image_path'] = $path;
        } elseif ($request->boolean('remove_footer_image')) {
            if ($pdfTemplate->footer_image_path && Storage::disk('concours')->exists($pdfTemplate->footer_image_path)) {
                Storage::disk('concours')->delete($pdfTemplate->footer_image_path);
            }
            $updateData['footer_image_path'] = null;
        }

        // Handle footer PDF
        if ($request->hasFile('footer_pdf')) {
            if ($pdfTemplate->footer_pdf_path && Storage::disk('concours')->exists($pdfTemplate->footer_pdf_path)) {
                Storage::disk('concours')->delete($pdfTemplate->footer_pdf_path);
            }
            $path = $request->file('footer_pdf')->store('pdf-templates/footers', 'concours');
            $updateData['footer_pdf_path'] = $path;
        } elseif ($request->boolean('remove_footer_pdf')) {
            if ($pdfTemplate->footer_pdf_path && Storage::disk('concours')->exists($pdfTemplate->footer_pdf_path)) {
                Storage::disk('concours')->delete($pdfTemplate->footer_pdf_path);
            }
            $updateData['footer_pdf_path'] = null;
        }

        // Update selected attributes
        if (!empty($validated['selected_attributes'])) {
            $updateData['selected_attributes'] = $validated['selected_attributes'];
        } else {
            $updateData['selected_attributes'] = null;
        }

        // Update attribute labels mapping
        if ($request->has('attribute_labels') && !empty($request->input('attribute_labels'))) {
            $updateData['attributes_labels'] = $request->input('attribute_labels');
        } else {
            $updateData['attributes_labels'] = null;
        }

        // Update the template
        $pdfTemplate->update($updateData);

        // Rebuild attribute records
        $pdfTemplate->attributes()->delete();
        if (!empty($validated['selected_attributes'])) {
            $allAttributes = PdfTemplate::getAllAvailableAttributes();
            foreach ($validated['selected_attributes'] as $index => $attrKey) {
                if (isset($allAttributes[$attrKey])) {
                    $labelToSave = $request->input('attribute_labels.' . $attrKey) ?? $allAttributes[$attrKey];
                    PdfTemplateAttribute::create([
                        'pdf_template_id' => $pdfTemplate->id,
                        'attribute_key' => $attrKey,
                        'attribute_label' => $labelToSave,
                        'sort_order' => $index,
                    ]);
                }
            }
        }

        return redirect()->route('concours.pdf-templates.index', $concours)
                       ->with('success', 'تم تحديث القالب بنجاح.');
    }

    /**
     * Delete a PDF template
     */
    public function destroy(Concours $concours, PdfTemplate $pdfTemplate)
    {
        // Ensure the template belongs to this concours
        if ($pdfTemplate->concours_id !== $concours->id) {
            abort(403);
        }

        // Delete associated files
        foreach (['header_image_path', 'header_pdf_path', 'footer_image_path', 'footer_pdf_path'] as $field) {
            if ($pdfTemplate->{$field} && Storage::disk('concours')->exists($pdfTemplate->{$field})) {
                Storage::disk('concours')->delete($pdfTemplate->{$field});
            }
        }

        // Delete the template
        $pdfTemplate->delete();

        return redirect()->route('concours.pdf-templates.index', $concours)
                       ->with('success', 'تم حذف القالب بنجاح.');
    }

    /**
     * Toggle active state for a template. Ensures only one active template per concours.
     */
    public function toggleActive(Concours $concours, PdfTemplate $pdfTemplate)
    {
        if ($pdfTemplate->concours_id !== $concours->id) {
            abort(403);
        }

        if (!empty($pdfTemplate->is_active)) {
            // Deactivate this template
            $pdfTemplate->update(['is_active' => false]);
            return redirect()->route('concours.pdf-templates.index', $concours)
                             ->with('success', 'تم تعطيل القالب بنجاح.');
        }

        // Activate this template and deactivate others
        PdfTemplate::where('concours_id', $concours->id)
            ->where('id', '!=', $pdfTemplate->id)
            ->update(['is_active' => false]);

        $pdfTemplate->update(['is_active' => true]);

        return redirect()->route('concours.pdf-templates.index', $concours)
                         ->with('success', 'تم تفعيل القالب بنجاح.');
    }

    /**
     * Toggle publish state for a template.
     */
    public function togglePublish(Concours $concours, PdfTemplate $pdfTemplate)
    {
        if ($pdfTemplate->concours_id !== $concours->id) {
            abort(403);
        }

        $newState = !($pdfTemplate->is_published ?? false);
        $pdfTemplate->update(['is_published' => $newState]);

        return redirect()->back()
                 ->with('success', $newState ? 'تم نشر القالب.' : 'تم إلغاء نشر القالب.');
    }

    /**
     * Preview a PDF template (render for a specific candidate)
     */
    public function preview(Concours $concours, PdfTemplate $pdfTemplate, Request $request)
    {
        // Ensure the template belongs to this concours
        if ($pdfTemplate->concours_id !== $concours->id) {
            abort(403);
        }

        $candidateId = $request->query('candidate_id');
        
        // Get candidate if provided, otherwise default to first candidate (if any)
        $candidate = null;
        if ($candidateId) {
            $candidate = $concours->candidates()->find($candidateId);
            if (!$candidate) {
                return back()->with('error', 'المترشح غير موجود.');
            }
        } else {
            $candidate = $concours->candidates()->first();
        }

        $processedBody = $this->pdfGenerator->getProcessedBody($pdfTemplate, $candidate, $candidate === null);

        return view('backoffice.concours.pdf-templates.preview', compact(
            'concours',
            'pdfTemplate',
            'candidate',
            'processedBody'
        ));
    }

    /**
     * Generate PDF for a specific candidate or all candidates
     */
    public function generate(Concours $concours, PdfTemplate $pdfTemplate, Request $request)
    {
        // Ensure the template belongs to this concours
        if ($pdfTemplate->concours_id !== $concours->id) {
            abort(403);
        }

        $candidateId = $request->query('candidate_id');
        
        if ($candidateId) {
            // Generate PDF for a single candidate
            $candidate = $concours->candidates()->find($candidateId);
            if (!$candidate) {
                return back()->with('error', 'المترشح غير موجود.');
            }
            
            return $this->pdfGenerator->generateForCandidate(
                $pdfTemplate,
                $candidate
            );
        } else {
            // Generate PDF for all candidates
            return $this->pdfGenerator->generateForAllCandidates(
                $pdfTemplate,
                $concours
            );
        }
    }

    /**
     * Preview empty template
     */
    public function previewEmpty(Concours $concours, PdfTemplate $pdfTemplate)
    {
        if ($pdfTemplate->concours_id !== $concours->id) {
            abort(403);
        }

        $candidateAttributes = PdfTemplate::getAvailableCandidateAttributes();
        $concoursAttributes = PdfTemplate::getAvailableConcoursAttributes();

        $processedBody = $this->pdfGenerator->getProcessedBody($pdfTemplate, null, true);

        return view('backoffice.concours.pdf-templates.preview', [
            'concours' => $concours,
            'pdfTemplate' => $pdfTemplate,
            'candidate' => null,
            'availableCandidateAttributes' => $candidateAttributes,
            'availableConcoursAttributes' => $concoursAttributes,
            'showEmpty' => true,
            'processedBody' => $processedBody,
        ]);
    }

    /**
     * Download empty template as PDF
     */
    public function downloadEmpty(Concours $concours, PdfTemplate $pdfTemplate)
    {
        if ($pdfTemplate->concours_id !== $concours->id) {
            abort(403);
        }

        return $this->pdfGenerator->generateEmptyTemplate($pdfTemplate);
    }

    /**
     * Serve a file stored on the 'concours' shared disk for preview (header/footer images/PDFs)
     */
    public function sharedFile(Concours $concours, PdfTemplate $pdfTemplate, Request $request)
    {
        if ($pdfTemplate->concours_id !== $concours->id) {
            abort(403);
        }

        $path = $request->query('path');
        if (empty($path)) {
            abort(404);
        }

        $disk = Storage::disk('concours');
        if (!$disk->exists($path)) {
            abort(404);
        }

        $full = $disk->path($path);
        if (!file_exists($full) || !is_readable($full)) {
            abort(404);
        }

        $mime = null;
        if (function_exists('mime_content_type')) {
            $mime = @mime_content_type($full);
        }

        return response()->file($full, $mime ? ['Content-Type' => $mime] : []);
    }

    /**
     * Get PDF data as base64 for embedding in preview
     */
    public function getPdfData(Concours $concours, PdfTemplate $pdfTemplate, Request $request)
    {
        if ($pdfTemplate->concours_id !== $concours->id) {
            abort(403);
        }

        $candidateId = $request->query('candidate_id');
        $pdfContent = null;

        if ($candidateId) {
            $candidate = $concours->candidates()->find($candidateId);
            if ($candidate) {
                $pdfContent = $this->pdfGenerator->generateForCandidatePdf(
                    $pdfTemplate,
                    $candidate
                );
            }
        }

        if (!$pdfContent) {
            return response()->json([
                'error' => 'فشل في إنشاء PDF',
                'data' => null
            ], 400);
        }

        return response()->json([
            'success' => true,
            'data' => 'data:application/pdf;base64,' . base64_encode($pdfContent)
        ]);
    }
}
