<?php

namespace App\Services;

use App\Models\CertificateTemplate;
use App\User;
use Intervention\Image\Facades\Image;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;

class CertificateGenerationService
{
        /**
     * Generate a certificate image using template and student data
     */
    public function generateCertificateFromTemplate($template, $studentData, $isPreview = false)
    {
        try {
            // Load template background image
            $templatePath = storage_path('app/public/' . $template->background_image);

            if (!file_exists($templatePath)) {
                throw new \Exception("Template background image not found: {$templatePath}");
            }

            $img = Image::make($templatePath);

            // Get image dimensions
            $width = $img->width();
            $height = $img->height();

            // Get template fields from template_data
            $fields = $template->template_fields ?? [];

            if (empty($fields)) {
                // Use default fields if no custom fields defined
                $fields = $template->default_template_data['fields'] ?? [];
            }

            // Apply each field to the image
            foreach ($fields as $field) {
                $text = $this->getFieldTextFromTemplate($field, $studentData);

                if ($text) {
                    $this->applyTextToImageFromTemplate($img, $field, $text, $width, $height);
                }
            }

            // Save generated certificate
            $filename = 'certificate_' . Str::random(8) . '_' . time() . '.jpg';
            $path = 'certificates/' . $filename;

            if ($isPreview) {
                $path = 'previews/' . $filename;
            }

            $img->save(storage_path('app/public/' . $path), 90);

            return $path;

        } catch (\Exception $e) {
            Log::error("Certificate generation failed for template {$template->id}: " . $e->getMessage());
            throw $e;
        }
    }

    /**
     * Generate a certificate image using template and user data (legacy method)
     */
    public function generateCertificate($user, $template, $graduationDate, $customData = [], $isPreview = false)
    {
        try {
            // Load template image
            $templatePath = storage_path('app/public/' . $template->image_path);

            if (!file_exists($templatePath)) {
                throw new \Exception("Template image not found: {$templatePath}");
            }

            $img = Image::make($templatePath);

            // Get image dimensions
            $width = $img->width();
            $height = $img->height();

            // Get template fields from template_data
            $fields = $template->template_fields ?? [];

            if (empty($fields)) {
                // Use default fields if no custom fields defined
                $fields = $template->default_template_data['fields'] ?? [];
            }

            // Apply each field to the image
            foreach ($fields as $field) {
                $text = $this->getFieldText($field, $user, $graduationDate, $customData);

                if ($text) {
                    $this->applyTextToImage($img, $field, $text, $width, $height);
                }
            }

            // Save generated certificate
            $filename = 'certificate_' . $user->id . '_' . time() . '.jpg';
            $path = 'graduation-certificates/' . $filename;

            if ($isPreview) {
                $path = 'previews/' . $filename;
            }

            $img->save(storage_path('app/public/' . $path), 90);

            return $path;

        } catch (\Exception $e) {
            Log::error("Certificate generation failed for user {$user->id}: " . $e->getMessage());
            throw $e;
        }
    }



    /**
     * Get text content for a field
     */
    private function getFieldText($field, $user, $graduationDate, $customData)
    {
        // Handle both old field structure and new template data structure
        $dataSource = $field->data_source ?? $field->field_key ?? $field->id ?? '';

        switch ($dataSource) {
            case 'student_name':
                return $user->full_name ?? $user->name ?? '';
            case 'student_email':
                return $user->email ?? '';
            case 'graduation_date':
                return $graduationDate->format('F j, Y');
            case 'completion_date':
                return $graduationDate->format('F j, Y');
            case 'current_date':
                return now()->format('F j, Y');
            case 'current_time':
                return now()->format('g:i A');
            case 'serial_number':
                return $this->generateSerialNumber($user);
            case 'certificate_id':
                return 'CERT-' . str_pad($user->id, 6, '0', STR_PAD_LEFT);
            case 'course_name':
                return $customData['course_name'] ?? '';
            case 'instructor_name':
                return $customData['instructor_name'] ?? '';
            case 'organization_name':
                return $customData['organization_name'] ?? '';
            case 'custom_text':
                return $field->default_value ?? '';
            default:
                // Check custom data
                if (isset($customData[$dataSource])) {
                    return $customData[$dataSource];
                }

                // Check if it's a custom field
                if (isset($customData['custom_' . $dataSource])) {
                    return $customData['custom_' . $dataSource];
                }

                // Check if field has a default value
                if (isset($field->default_value)) {
                    return $field->default_value;
                }

                // Check if field has a value (template placeholder)
                if (isset($field->value)) {
                    return $field->value;
                }

                return '';
        }
    }

    /**
     * Apply text to image with proper positioning and styling
     */
    private function applyTextToImage($img, $field, $text, $imageWidth, $imageHeight)
    {
        // Handle both old field structure and new template data structure
        $fontSize = $field->font_size ?? $field->fontSize ?? 16;
        $fontSize = min($fontSize, $imageWidth / 20);

        // Convert percentage coordinates to pixels (handle both x/y and percentage-based)
        $x = isset($field->x) ? $field->x : 0;
        $y = isset($field->y) ? $field->y : 0;

        // If coordinates are percentages, convert to pixels
        if ($x <= 100 && $y <= 100) {
            $x = ($x / 100) * $imageWidth;
            $y = ($y / 100) * $imageHeight;
        }

        // Get font file path
        $fontFamily = $field->font_family ?? $field->fontFamily ?? 'Arial';
        $fontPath = $this->getFontPath($fontFamily);

        $img->text($text, $x, $y, function ($font) use ($field, $fontSize, $fontPath) {
            $font->file($fontPath);
            $font->size($fontSize);

            // Handle color property
            $color = $field->color ?? '#000000';
            $font->color($color);

            // Handle alignment properties
            $align = $field->align ?? $field->textAlign ?? 'center';
            $font->align($align);

            // Handle vertical alignment (default to top)
            $valign = $field->valign ?? 'top';
            $font->valign($valign);

            // Handle font weight
            $fontWeight = $field->bold ?? $field->fontWeight ?? 'normal';
            if ($fontWeight === 'bold' || $fontWeight === true) {
                $font->weight('bold');
            }

            // Handle font style
            $fontStyle = $field->italic ?? $field->fontStyle ?? 'normal';
            if ($fontStyle === 'italic' || $fontStyle === true) {
                $font->style('italic');
            }
        });
    }

    /**
     * Get font file path
     */
    private function getFontPath($fontFamily)
    {
        $fontMap = [
            'Arial' => 'arial.ttf',
            'Times New Roman' => 'times.ttf',
            'Courier New' => 'cour.ttf',
            'Georgia' => 'georgia.ttf',
            'Verdana' => 'verdana.ttf',
            'Helvetica' => 'arial.ttf', // Fallback to Arial
        ];

        $fontFile = $fontMap[$fontFamily] ?? 'arial.ttf';
        $fontPath = public_path('assets/default/fonts/' . $fontFile);

        // Fallback to default font if not found
        if (!file_exists($fontPath)) {
            $fontPath = public_path('assets/default/fonts/Montserrat-Medium.ttf');
        }

        return $fontPath;
    }

    /**
     * Generate serial number for certificate
     */
    private function generateSerialNumber($user)
    {
        $prefix = 'CERT';
        $userId = str_pad($user->id, 6, '0', STR_PAD_LEFT);
        $year = date('Y');
        $month = date('m');
        $random = strtoupper(substr(md5(uniqid()), 0, 4));

        return "{$prefix}-{$userId}-{$year}{$month}-{$random}";
    }

    /**
     * Process CSV data for bulk certificate generation
     */
    public function processCSVData($csvFile)
    {
        $data = [];
        $handle = fopen($csvFile->getPathname(), 'r');

        if ($handle !== false) {
            $headers = fgetcsv($handle);

            while (($row = fgetcsv($handle)) !== false) {
                if (count($row) === count($headers)) {
                    $data[] = array_combine($headers, $row);
                }
            }

            fclose($handle);
        }

        return $data;
    }

    /**
     * Find user from CSV row data
     */
    public function findUserFromCSVRow($row)
    {
        // Try to find user by email first, then by name
        if (isset($row['email']) && !empty($row['email'])) {
            return User::where('email', trim($row['email']))->where('role_name', 'user')->first();
        }

        if (isset($row['full_name']) && !empty($row['full_name'])) {
            return User::where('full_name', trim($row['full_name']))->where('role_name', 'user')->first();
        }

        if (isset($row['name']) && !empty($row['name'])) {
            return User::where('full_name', trim($row['name']))->where('role_name', 'user')->first();
        }

        return null;
    }

    /**
     * Validate certificate data
     */
    public function validateCertificateData($data)
    {
        $errors = [];

        if (empty($data['template_id'])) {
            $errors[] = 'Template is required';
        }

        if (empty($data['graduation_date'])) {
            $errors[] = 'Graduation date is required';
        }

        if (empty($data['user_ids']) || !is_array($data['user_ids'])) {
            $errors[] = 'At least one student must be selected';
        }

        return $errors;
    }

    /**
     * Clean up preview files
     */
        public function cleanupPreviewFiles()
    {
        $previewPath = storage_path('app/public/previews');

        if (is_dir($previewPath)) {
            $files = glob($previewPath . '/*');
            $now = time();

            foreach ($files as $file) {
                if (is_file($file)) {
                    // Delete files older than 1 hour
                    if ($now - filemtime($file) >= 3600) {
                        unlink($file);
                    }
                }
            }
        }
    }

    /**
     * Get text content for a field from template
     */
    private function getFieldTextFromTemplate($field, $studentData)
    {
        $value = $field['value'] ?? '';

        // Replace placeholders with actual data
        $value = str_replace('{{student_name}}', $studentData['student_name'] ?? '', $value);
        $value = str_replace('{{student_email}}', $studentData['student_email'] ?? '', $value);
        $value = str_replace('{{student_id}}', $studentData['student_id'] ?? '', $value);
        $value = str_replace('{{course_name}}', $studentData['course_name'] ?? '', $value);
        $value = str_replace('{{graduation_date}}', $studentData['graduation_date'] ?? '', $value);
        $value = str_replace('{{completion_date}}', $studentData['completion_date'] ?? '', $value);
        $value = str_replace('{{instructor_name}}', $studentData['instructor_name'] ?? '', $value);
        $value = str_replace('{{organization_name}}', $studentData['organization_name'] ?? '', $value);
        $value = str_replace('{{serial_number}}', $studentData['serial_number'] ?? '', $value);
        $value = str_replace('{{certificate_id}}', $studentData['certificate_id'] ?? '', $value);
        $value = str_replace('{{current_date}}', $studentData['current_date'] ?? '', $value);
        $value = str_replace('{{current_time}}', $studentData['current_time'] ?? '', $value);

        return $value;
    }

    /**
     * Apply text to image from template with proper positioning and styling
     */
    private function applyTextToImageFromTemplate($img, $field, $text, $imageWidth, $imageHeight)
    {
        // Calculate font size based on image width
        $fontSize = min($field['fontSize'], $imageWidth / 20);

        // Convert percentage coordinates to pixels
        $x = ($field['x'] / 100) * $imageWidth;
        $y = ($field['y'] / 100) * $imageHeight;

        // Get font file path
        $fontPath = $this->getFontPath($field['fontFamily']);

        $img->text($text, $x, $y, function ($font) use ($field, $fontSize, $fontPath) {
            $font->file($fontPath);
            $font->size($fontSize);
            $font->color($field['color']);
            $font->align($field['textAlign']);
            $font->valign('top');

            if (isset($field['fontWeight']) && $field['fontWeight'] === 'bold') {
                $font->weight('bold');
            }

            if (isset($field['fontSize']) && $field['fontStyle'] === 'italic') {
                $font->style('italic');
            }
        });
    }
}
