<?php

namespace App\Livewire\Admin\Services;

use App\Models\Service;
use App\Models\ServiceCategory;
use App\Models\Work;
use App\Models\Redirect;
use Livewire\Component;
use Livewire\WithFileUploads;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\DB;

class ServiceEdit extends Component
{
    use WithFileUploads;

    public $service;

    // ================= SERVICE FIELDS =================
    public $title;
    public $service_category_id;
    public $description;
    public $work_section_header;
    public $h1;
    public $h2;

    // media options
    public $mediaType = 'video'; // video | image_upload | image_url
    public $hero_video;
    public $hero_image;
    public $hero_image_url;

    public $status = true;

    private $mounted = false;

    // ================= SEO FIELDS =================
    public $meta_title;
    public $meta_description;
    public $meta_keywords;
    public $canonical_url;
    public $og_title;
    public $og_description;
    public $og_image;

    // ================= ROBOTS =================
    public $noindex = false;
    public $nofollow = false;

    // ================= SCHEMA FIELDS =================
    public $schema_type = 'Service';
    public $schema_markup;

    public $service_schema;
    public $faq_schema;
    public $org_schema;
    public $webpage_schema;
    public $article_schema;
    public $breadcrumb_schema;
    public $localbusiness_schema;

    // ================= REDIRECTION FIELDS =================
    public $old_url;
    public $redirect_to;
    public $redirect_type = '301'; // store as string (DB type issue fix)

    // ================= RELATIONS =================
    public $selectedWorks = [];

    /**
     * Normalize URL to path
     * - If full URL provided, keep only path
     * - Ensure it starts with /
     * - Remove trailing slash (optional)
     */
    private function normalizeUrl($value): ?string
    {
        $value = trim((string) $value);
        if ($value === '') return null;

        // If user entered full URL -> extract path
        if (Str::startsWith($value, ['http://', 'https://'])) {
            $path = parse_url($value, PHP_URL_PATH);
            $value = $path ?: '/';
        }

        // If user entered domain like google.com without scheme
        // Keep as is (external destination allowed)
        // BUT for old_url we want path only, so we handle that below while saving.
        // Here just return sanitized.
        // If it looks like a path, ensure leading slash.
        if (Str::startsWith($value, '/')) {
            // ok
        } else {
            // if it's like services/abc -> make /services/abc
            // if it's just "twsttt" -> /twsttt (still valid as path)
            if (!str_contains($value, '.')) {
                $value = '/' . $value;
            }
        }

        // Remove trailing slash except root
        if ($value !== '/') {
            $value = rtrim($value, '/');
        }

        return $value;
    }

    public function mount($id)
    {
        // Load service with category relation for URL building
        $this->service = Service::with('category')->findOrFail($id);

        $this->title = $this->service->title;
        $this->service_category_id = $this->service->service_category_id;
        $this->description = $this->service->description;
        $this->work_section_header = $this->service->work_section_header;
        $this->h1 = $this->service->h1;
        $this->h2 = $this->service->h2;
        $this->status = (bool) $this->service->status;

        // ===== saved media detect =====
        $hero = $this->service->hero_video;

        if ($hero) {
            $ext = strtolower(pathinfo($hero, PATHINFO_EXTENSION));

            if (in_array($ext, ['mp4','webm','ogg'])) {
                $this->mediaType = 'video';
                $this->hero_video = $hero;
            } elseif (Str::startsWith($hero, ['http://', 'https://'])) {
                $this->mediaType = 'image_url';
                $this->hero_image_url = $hero;
            } else {
                $this->mediaType = 'image_upload';
            }
        }

        // SEO
        $this->meta_title = $this->service->meta_title;
        $this->meta_description = $this->service->meta_description;
        $this->meta_keywords = $this->service->meta_keywords;
        $this->canonical_url = $this->service->canonical_url;
        $this->og_title = $this->service->og_title;
        $this->og_description = $this->service->og_description;
        $this->og_image = $this->service->og_image;

        // Robots
        $this->noindex = (bool) $this->service->noindex;
        $this->nofollow = (bool) $this->service->nofollow;

        // Schema
        $this->schema_type = $this->service->schema_type ?? 'Service';
        $this->schema_markup = $this->service->schema_markup;
        $this->service_schema = $this->service->service_schema;
        $this->faq_schema = $this->service->faq_schema;
        $this->org_schema = $this->service->org_schema;
        $this->webpage_schema = $this->service->webpage_schema;
        $this->article_schema = $this->service->article_schema;
        $this->breadcrumb_schema = $this->service->breadcrumb_schema;
        $this->localbusiness_schema = $this->service->localbusiness_schema;

        $this->selectedWorks = $this->service->works()->pluck('works.id')->toArray();

        // ================= REDIRECT LOAD (ROBUST) =================
        $categorySlug = optional($this->service->category)->slug;
        $serviceSlug  = $this->service->slug;

        $currentPath = ($categorySlug)
            ? '/services/' . $categorySlug . '/' . $serviceSlug
            : null;

        $currentPath = $this->normalizeUrl($currentPath);

        // Also check full URL form stored in DB (just in case)
        $appUrl = rtrim((string) config('app.url'), '/');
        $fullCurrent = $currentPath ? ($appUrl . $currentPath) : null;

        $redirect = null;

        if ($currentPath) {
            $redirect = Redirect::where('status', 1)
                ->where(function ($q) use ($currentPath, $fullCurrent) {
                    $q->where('new_url', $currentPath);

                    if ($fullCurrent) {
                        $q->orWhere('new_url', $fullCurrent);
                    }

                    // in case someone saved with trailing slash
                    $q->orWhere('new_url', $currentPath . '/');
                    if ($fullCurrent) $q->orWhere('new_url', $fullCurrent . '/');
                })
                ->first();
        }

        if ($redirect) {
            $this->old_url = $redirect->old_url;
            $this->redirect_to = $redirect->new_url;
            $this->redirect_type = (string) ($redirect->type ?? '301');
        } else {
            $this->old_url = null;
            $this->redirect_to = null;
            $this->redirect_type = '301';
        }

        $this->mounted = true;
    }

    public function updatedMediaType($type)
    {
        if (!$this->mounted) return;

        $this->hero_video = null;
        $this->hero_image = null;
        $this->hero_image_url = null;
    }

    public function update()
    {
        $this->validate([
            'title' => 'required|string|max:255',
            'service_category_id' => 'required|exists:service_categories,id',
            'mediaType' => 'required|in:video,image_upload,image_url',
            'hero_image' => 'nullable|image|max:4096',

            // Redirect validation
            'old_url' => 'nullable|string|max:255',
            'redirect_to' => 'nullable|string|max:255',
            'redirect_type' => 'nullable|in:301,302',
        ]);

        DB::transaction(function () {

            $heroValue = $this->hero_video;

            // ===== IMAGE UPLOAD =====
            if ($this->mediaType === 'image_upload' && $this->hero_image) {

                $extension = strtolower($this->hero_image->getClientOriginalExtension());
                $filename = Str::uuid()->toString() . '.' . $extension;

                $destination = public_path('uploads/services');

                if (!is_dir($destination)) {
                    mkdir($destination, 0755, true);
                }

                $tempPath = $this->hero_image->getRealPath();
                $finalPath = $destination . DIRECTORY_SEPARATOR . $filename;

                rename($tempPath, $finalPath);

                $heroValue = 'uploads/services/' . $filename;
            }

            // ===== IMAGE URL =====
            if ($this->mediaType === 'image_url') {
                $heroValue = $this->hero_image_url;
            }

            // Update Service fields
            $this->service->update([
                'title' => $this->title,
                'service_category_id' => $this->service_category_id,
                'description' => $this->description,
                'work_section_header' => $this->work_section_header,
                'h1' => $this->h1,
                'h2' => $this->h2,
                'hero_video' => $heroValue,
                'status' => $this->status ? 1 : 0,
            ]);

            // Works sync
            $this->service->works()->sync($this->selectedWorks);

            // ================= REDIRECT SAVE (NORMALIZED) =================
            $old = $this->normalizeUrl($this->old_url);
            $toRaw = trim((string) $this->redirect_to);

            // new_url can be external like https://google.com OR internal path
            $to = $toRaw;
            if (Str::startsWith($toRaw, ['http://','https://'])) {
                $to = rtrim($toRaw, '/');
            } else {
                $to = $this->normalizeUrl($toRaw);
            }

            if ($old && $to) {
                Redirect::updateOrCreate(
                    ['old_url' => $old],
                    [
                        'new_url' => $to,
                        'type' => (string) $this->redirect_type, // string -> no truncation
                        'status' => 1,
                    ]
                );
            } else {
                // If cleared, delete by old_url
                if ($old) {
                    Redirect::where('old_url', $old)->delete();
                }
            }
        });

        session()->flash('success', 'Service updated successfully.');
        return redirect()->route('admin.services');
    }

    public function render()
    {
        return view('livewire.admin.services.service-edit', [
            'categories' => ServiceCategory::orderBy('name')->get(),
            'works' => Work::orderBy('position')->orderBy('client_name')->get(),
        ])->layout('layouts.admin');
    }
}
