<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\JobFormSettings;
use App\Models\JobPosting;
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

class JobPostingController extends Controller
{
    // Geçerli template seçenekleri
    const JOB_PDF_TEMPLATES  = ['classic', 'banner', 'social'];
    const FORM_TEMPLATES     = ['classic', 'modern', 'minimal'];
    const VISUAL_SIZES       = ['square', 'portrait', 'landscape', 'story'];

    public function index(Request $request)
    {
        $query = JobPosting::withCount('applications');

        if ($request->filled('status')) {
            $query->where('status', $request->status);
        }
        if ($request->filled('department')) {
            $query->where('department', $request->department);
        }

        $jobs = $query->latest()->paginate(20);
        $departments = JobPosting::distinct()->pluck('department')->filter()->sort()->values();

        $stats = [
            'total'     => JobPosting::count(),
            'published' => JobPosting::where('status', 'published')->count(),
            'draft'     => JobPosting::where('status', 'draft')->count(),
            'closed'    => JobPosting::where('status', 'closed')->count(),
        ];

        return view('admin.ilanlar.index', compact('jobs', 'departments', 'stats'));
    }

    public function create()
    {
        return view('admin.ilanlar.create');
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'title'                   => 'required|string|max:255',
            'department'              => 'required|string|max:100',
            'employment_type'         => 'required|string|max:100',
            'location'                => 'required|string|max:100',
            'description'             => 'required|string',
            'requirements'            => 'required|string',
            'working_hours'           => 'nullable|string|max:255',
            'salary_range'            => 'nullable|string|max:255',
            'closes_at'               => 'nullable|date|after_or_equal:today',
            'required_documents'      => 'nullable|string|max:2000',
            'custom_application_form' => 'nullable|file|mimes:pdf,doc,docx|max:10240',
            'conditions_pdf'          => 'nullable|file|mimes:pdf|max:10240',
        ]);

        $slug = Str::slug($validated['title']);
        $originalSlug = $slug;
        $count = 1;
        while (JobPosting::where('slug', $slug)->exists()) {
            $slug = $originalSlug . '-' . $count++;
        }

        $isPublish = $request->input('action') === 'publish';

        $data = array_merge(
            collect($validated)->except(['custom_application_form', 'conditions_pdf'])->toArray(),
            [
                'slug'         => $slug,
                'status'       => $isPublish ? 'published' : 'draft',
                'published_at' => $isPublish ? now() : null,
                'created_by'   => auth()->id(),
            ]
        );

        if ($request->hasFile('custom_application_form')) {
            $file = $request->file('custom_application_form');
            $path = $file->store('application-forms', 'public');
            $data['custom_application_form_path'] = $path;
            $data['custom_application_form_name'] = $this->sanitizeFilename($file->getClientOriginalName());
        }

        if ($request->hasFile('conditions_pdf')) {
            $file = $request->file('conditions_pdf');
            $path = $file->store('conditions-pdfs', 'public');
            $data['conditions_pdf_path'] = $path;
            $data['conditions_pdf_name'] = $this->sanitizeFilename($file->getClientOriginalName());
        }

        // İlana özel form ayarları
        $useCustomFormSettings = $request->boolean('use_custom_form_settings');
        $data['use_custom_form_settings'] = $useCustomFormSettings;
        if ($useCustomFormSettings) {
            $data['job_form_settings'] = $this->extractJobFormSettings($request);
        }

        $job = JobPosting::create($data);

        $message = $isPublish ? 'İlan başarıyla yayınlandı.' : 'İlan taslak olarak kaydedildi.';

        return redirect()->route('admin.ilanlar.show', $job)
            ->with('success', $message);
    }

    public function show(JobPosting $ilanlar)
    {
        $ilanlar->loadCount('applications');

        $applicationStats = [
            'total'               => $ilanlar->applications_count,
            'yeni'                => $ilanlar->applications()->where('status', 'yeni')->count(),
            'incelendi'           => $ilanlar->applications()->where('status', 'incelendi')->count(),
            'gorusmeye_cagirildi' => $ilanlar->applications()->where('status', 'görüşmeye_çağrıldı')->count(),
            'reddedildi'          => $ilanlar->applications()->where('status', 'reddedildi')->count(),
            'ise_alindi'          => $ilanlar->applications()->where('status', 'işe_alındı')->count(),
        ];

        $formSettings = JobFormSettings::getOrCreate();

        return view('admin.ilanlar.show', [
            'job'              => $ilanlar,
            'applicationStats' => $applicationStats,
            'formSettings'     => $formSettings,
        ]);
    }

    public function edit(JobPosting $ilanlar)
    {
        return view('admin.ilanlar.edit', ['job' => $ilanlar]);
    }

    public function update(Request $request, JobPosting $ilanlar)
    {
        $validated = $request->validate([
            'title'                   => 'required|string|max:255',
            'department'              => 'required|string|max:100',
            'employment_type'         => 'required|string|max:100',
            'location'                => 'required|string|max:100',
            'description'             => 'required|string',
            'requirements'            => 'required|string',
            'working_hours'           => 'nullable|string|max:255',
            'salary_range'            => 'nullable|string|max:255',
            'closes_at'               => 'nullable|date|after_or_equal:today',
            'required_documents'      => 'nullable|string|max:2000',
            'custom_application_form' => 'nullable|file|mimes:pdf,doc,docx|max:10240',
            'conditions_pdf'          => 'nullable|file|mimes:pdf|max:10240',
        ]);

        $action = $request->input('action', 'save');

        if ($action === 'publish') {
            $validated['status']       = 'published';
            $validated['published_at'] = $ilanlar->published_at ?? now();
            $message = 'İlan yayınlandı.';
        } elseif ($action === 'draft') {
            $validated['status']       = 'draft';
            $validated['published_at'] = null;
            $message = 'İlan taslağa alındı.';
        } elseif ($action === 'close') {
            $validated['status'] = 'closed';
            $message = 'İlan kapatıldı.';
        } else {
            $message = 'İlan başarıyla güncellendi.';
        }

        $data = collect($validated)->except(['custom_application_form', 'conditions_pdf'])->toArray();

        if ($request->hasFile('custom_application_form')) {
            if ($ilanlar->custom_application_form_path && Storage::disk('public')->exists($ilanlar->custom_application_form_path)) {
                Storage::disk('public')->delete($ilanlar->custom_application_form_path);
            }
            $file = $request->file('custom_application_form');
            $path = $file->store('application-forms', 'public');
            $data['custom_application_form_path'] = $path;
            $data['custom_application_form_name'] = $this->sanitizeFilename($file->getClientOriginalName());
        }

        if ($request->input('remove_custom_form') === '1') {
            if ($ilanlar->custom_application_form_path && Storage::disk('public')->exists($ilanlar->custom_application_form_path)) {
                Storage::disk('public')->delete($ilanlar->custom_application_form_path);
            }
            $data['custom_application_form_path'] = null;
            $data['custom_application_form_name'] = null;
        }

        if ($request->hasFile('conditions_pdf')) {
            if ($ilanlar->conditions_pdf_path && Storage::disk('public')->exists($ilanlar->conditions_pdf_path)) {
                Storage::disk('public')->delete($ilanlar->conditions_pdf_path);
            }
            $file = $request->file('conditions_pdf');
            $path = $file->store('conditions-pdfs', 'public');
            $data['conditions_pdf_path'] = $path;
            $data['conditions_pdf_name'] = $this->sanitizeFilename($file->getClientOriginalName());
        }

        if ($request->input('remove_conditions_pdf') === '1') {
            if ($ilanlar->conditions_pdf_path && Storage::disk('public')->exists($ilanlar->conditions_pdf_path)) {
                Storage::disk('public')->delete($ilanlar->conditions_pdf_path);
            }
            $data['conditions_pdf_path'] = null;
            $data['conditions_pdf_name'] = null;
        }

        // İlana özel form ayarları
        $useCustomFormSettings = $request->boolean('use_custom_form_settings');
        $data['use_custom_form_settings'] = $useCustomFormSettings;
        $data['job_form_settings'] = $useCustomFormSettings ? $this->extractJobFormSettings($request) : null;

        $ilanlar->update($data);

        return redirect()->route('admin.ilanlar.show', $ilanlar)
            ->with('success', $message);
    }

    public function destroy(JobPosting $ilanlar)
    {
        $ilanlar->delete();
        return redirect()->route('admin.ilanlar.index')
            ->with('success', 'İlan silindi.');
    }

    public function publish(JobPosting $jobPosting)
    {
        $closesAtExpired = $jobPosting->closes_at && $jobPosting->closes_at->isPast();

        $data = [
            'status'       => 'published',
            'published_at' => $jobPosting->published_at ?? now(),
        ];

        // Son başvuru tarihi geçmişse temizle — geçmiş tarihli ilan yayında olamaz
        if ($closesAtExpired) {
            $data['closes_at'] = null;
        }

        $jobPosting->update($data);

        $message = $closesAtExpired
            ? 'İlan yayınlandı. Son başvuru tarihi geçmiş olduğundan temizlendi; lütfen düzenleyerek yeni bir tarih belirleyin.'
            : 'İlan yayınlandı.';

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

    public function close(JobPosting $jobPosting)
    {
        $jobPosting->update(['status' => 'closed']);
        return back()->with('success', 'İlan kapatıldı.');
    }

    public function makeDraft(JobPosting $jobPosting)
    {
        $jobPosting->update([
            'status'       => 'draft',
            'published_at' => null,
        ]);
        return back()->with('success', 'İlan taslağa alındı.');
    }

    public function duplicate(JobPosting $jobPosting)
    {
        $newJob = $jobPosting->replicate();
        $newJob->status = 'draft';
        $newJob->published_at = null;
        $newJob->closes_at = null;
        $newJob->created_by = auth()->id();
        // Dosya yollarını temizle — kopya orijinal dosyaya bağımlı olmamalı
        $newJob->custom_application_form_path = null;
        $newJob->custom_application_form_name = null;
        $newJob->conditions_pdf_path = null;
        $newJob->conditions_pdf_name = null;

        $slug = $jobPosting->slug . '-kopya';
        $count = 1;
        while (JobPosting::where('slug', $slug)->exists()) {
            $slug = $jobPosting->slug . '-kopya-' . $count++;
        }
        $newJob->slug = $slug;
        $newJob->title = $jobPosting->title . ' (Kopya)';
        $newJob->save();

        return redirect()->route('admin.ilanlar.edit', $newJob)
            ->with('success', 'İlan kopyalandı. Düzenleyip yayınlayabilirsiniz.');
    }

    /**
     * Özel başvuru formunu güvenli şekilde indir/görüntüle.
     */
    public function downloadCustomForm(JobPosting $jobPosting)
    {
        if (!$jobPosting->custom_application_form_path) {
            abort(404, 'Bu ilana ait özel başvuru formu bulunamadı.');
        }

        $disk = Storage::disk('public');

        if (!$disk->exists($jobPosting->custom_application_form_path)) {
            abort(404, 'Dosya bulunamadı.');
        }

        $fileName = $jobPosting->custom_application_form_name
            ?? basename($jobPosting->custom_application_form_path);

        return $disk->response($jobPosting->custom_application_form_path, $fileName, [
            'Content-Disposition' => 'inline; filename="' . $fileName . '"',
        ]);
    }

    /**
     * Export the job posting as a PDF file.
     * ?template=classic|banner|social
     */
    public function exportPdf(Request $request, JobPosting $jobPosting)
    {
        $template = $request->get('template', 'classic');
        if (!in_array($template, self::JOB_PDF_TEMPLATES)) {
            $template = 'classic';
        }

        // Social media size parameter: square | portrait | landscape | story
        $size = $request->get('size', 'square');
        $allowedSizes = ['square', 'portrait', 'landscape', 'story'];
        if (!in_array($size, $allowedSizes)) {
            $size = 'square';
        }

        $settings = JobFormSettings::getOrCreate();

        $viewMap = [
            'classic' => 'admin.ilanlar.pdf.job-posting',
            'banner'  => 'admin.ilanlar.pdf.job-posting-banner',
            'social'  => 'admin.ilanlar.pdf.job-posting-social',
        ];

        // DomPDF options — background-color render için gerekli
        $dompdfOptions = [
            'isHtml5ParserEnabled'    => true,
            'isRemoteEnabled'         => false,
            'defaultFont'             => 'DejaVu Sans',
            'isFontSubsettingEnabled' => true,
            'chroot'                  => storage_path('app/public'),
        ];

        // Paper size mapping for social media formats
        if ($template === 'social') {
            $paperMap = [
                'square'    => [[297, 297], 'portrait'],   // ~1080x1080 equivalent in mm
                'portrait'  => [[297, 371], 'portrait'],   // ~1080x1350 equivalent in mm
                'landscape' => [[330, 173], 'landscape'],  // ~1200x628 equivalent in mm
                'story'     => [[297, 528], 'portrait'],   // ~1080x1920 equivalent in mm
            ];
            [$paperSize, $orientation] = $paperMap[$size];
            $pdf = Pdf::loadView($viewMap[$template], [
                'job'      => $jobPosting,
                'settings' => $settings,
                'size'     => $size,
            ])->setOptions($dompdfOptions)->setPaper($paperSize, $orientation);
        } elseif ($template === 'banner') {
            $pdf = Pdf::loadView($viewMap[$template], [
                'job'      => $jobPosting,
                'settings' => $settings,
            ])->setOptions($dompdfOptions)->setPaper('a4', 'landscape');
        } else {
            $pdf = Pdf::loadView($viewMap[$template], [
                'job'      => $jobPosting,
                'settings' => $settings,
            ])->setOptions($dompdfOptions)->setPaper('a4', 'portrait');
        }

        $filename = 'ilan-' . $jobPosting->slug . '-' . $template . ($template === 'social' ? '-' . $size : '') . '-' . now()->format('Y-m-d') . '.pdf';

        return $pdf->download($filename);
    }

    /**
     * Generate a branded application form PDF for this job posting.
     * ?template=classic|modern|minimal
     */
    public function generateApplicationForm(Request $request, JobPosting $jobPosting)
    {
        $template = $request->get('template', 'classic');
        if (!in_array($template, self::FORM_TEMPLATES)) {
            $template = 'classic';
        }

        $settings = JobFormSettings::getOrCreate();

        $viewMap = [
            'classic' => 'admin.ilanlar.pdf.application-form',
            'modern'  => 'admin.ilanlar.pdf.application-form-modern',
            'minimal' => 'admin.ilanlar.pdf.application-form-minimal',
        ];

        $pdf = Pdf::loadView($viewMap[$template], [
            'job'      => $jobPosting,
            'settings' => $settings,
        ])->setPaper('a4', 'portrait');

        $filename = 'basvuru-formu-' . $jobPosting->slug . '-' . $template . '-' . now()->format('Y-m-d') . '.pdf';

        return $pdf->download($filename);
    }

    /**
     * Yüklenen dosya adını güvenli hale getirir.
     * Path traversal ve header injection karakterlerini temizler.
     */
    private function sanitizeFilename(string $filename): string
    {
        // Sadece dosya adını al (path traversal önlemi)
        $filename = basename($filename);
        // Güvenli olmayan karakterleri alt çizgiyle değiştir
        $filename = preg_replace('/[^\w\-.]/', '_', $filename);
        // Birden fazla nokta içeren tehlikeli uzantıları temizle (örn. file.php.pdf)
        $filename = preg_replace('/\.{2,}/', '.', $filename);
        return $filename ?: 'dosya';
    }

    /**
     * Request'ten ilan bazlı form ayarlarını çıkar.
     */
    protected function extractJobFormSettings(Request $request): array
    {
        return [
            'company_name'        => $request->input('jfs_company_name', ''),
            'form_title'          => $request->input('jfs_form_title', ''),
            'show_phone'          => $request->boolean('jfs_show_phone'),
            'show_linkedin'       => $request->boolean('jfs_show_linkedin'),
            'show_cover_letter'   => $request->boolean('jfs_show_cover_letter'),
            'show_source'         => $request->boolean('jfs_show_source'),
            'form_template'       => in_array($request->input('jfs_form_template'), self::FORM_TEMPLATES)
                                        ? $request->input('jfs_form_template')
                                        : 'classic',
            'footer_text'         => $request->input('jfs_footer_text', ''),
        ];
    }

    /**
     * Return a template preview as HTML fragment (AJAX).
     * ?type=job|form&template=classic|...
     */
    public function previewTemplate(Request $request, JobPosting $jobPosting)
    {
        $type     = $request->get('type', 'job');
        $template = $request->get('template', 'classic');
        $settings = JobFormSettings::getOrCreate();

        if ($type === 'form') {
            $templates = self::FORM_TEMPLATES;
            $viewMap = [
                'classic' => 'admin.ilanlar.pdf.application-form',
                'modern'  => 'admin.ilanlar.pdf.application-form-modern',
                'minimal' => 'admin.ilanlar.pdf.application-form-minimal',
            ];
        } else {
            $templates = self::JOB_PDF_TEMPLATES;
            $viewMap = [
                'classic' => 'admin.ilanlar.pdf.job-posting',
                'banner'  => 'admin.ilanlar.pdf.job-posting-banner',
                'social'  => 'admin.ilanlar.pdf.job-posting-social',
            ];
        }

        if (!in_array($template, $templates)) {
            $template = $templates[0];
        }

        $html = view($viewMap[$template], [
            'job'      => $jobPosting,
            'settings' => $settings,
            'preview'  => true,
        ])->render();

        return response($html)->header('Content-Type', 'text/html');
    }
}