<?php

namespace App\Jobs;

use DOMDocument;
use Exception;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Log;
use Mtc\ContentManager\Contracts\PageModel;
use Mtc\ContentManager\Facades\Media;
use Mtc\ContentManager\Facades\Page;
use Mtc\ContentManager\Models\ContentCategory;
use Mtc\ContentManager\Models\MediaFolder;
use Mtc\MercuryDataModels\SeoData;
use Mtc\MercuryDataModels\Template;

class WordPressArticleImport implements ShouldQueue
{
    use Dispatchable;
    use InteractsWithQueue;
    use Queueable;
    use SerializesModels;

    /**
     * Create a new job instance.
     */
    public function __construct(
        private readonly array $postData,
        private readonly ?string $featuredImageUrl,
        private readonly string $templateSlug = 'blog-article',
        private readonly array $categories = [],
    ) {
        //
    }

    /**
     * Execute the job.
     */
    public function handle(): void
    {
        try {
            $template = Template::query()->where('slug', $this->templateSlug)->first();

            if (!$template) {
                Log::error('WordPressArticleImport: Template "' . $this->templateSlug . '" not found');
                return;
            }

            $mediaFolder = MediaFolder::query()->firstOrCreate(['name' => 'Blog Images']);

            $page = app(PageModel::class)->updateOrCreate([
                'slug' => $this->postData['slug'],
            ], [
                'template_id' => $template->id,
                'title' => html_entity_decode($this->postData['title']),
                'status' => 'published',
                'published_at' => Carbon::parse($this->postData['date']),
                'category' => 'blog',
            ]);

            Page::syncContentWithTemplate($page->id);
            $this->syncCategories($page);
            $this->updatePageSeo($page);

            // Import featured image
            $featuredImage = null;
            if (!empty($this->featuredImageUrl)) {
                try {
                    $featuredImage = Media::importImageFromUrl($this->featuredImageUrl);
                    $featuredImage->update(['folder_id' => $mediaFolder->id]);

                    if ($page->mediaUses()->exists() === false) {
                        Media::setUsesForModel([$featuredImage->id], $page, ['primary' => true]);
                    }
                } catch (Exception $e) {
                    Log::error('WordPressArticleImport: Failed to import featured image', [
                        'url' => $this->featuredImageUrl,
                        'error' => $e->getMessage(),
                    ]);
                }
            }

            // Process body content - import inline images
            $bodyContent = $this->processContentImages(
                $this->postData['content'] ?? '',
                $mediaFolder
            );

            // Map content to template sub-elements
            foreach ($page->content as $content) {
                foreach ($content->subContent as $subContent) {
                    $subContentName = strtoupper($subContent->name);

                    if (
                        $subContentName === 'TEXT'
                        || $subContentName === 'DESCRIPTION'
                        || $subContentName === 'BODY'
                    ) {
                        $subContent->content = $bodyContent;
                        $subContent->save();
                    } elseif (
                        $subContentName === 'EXCERPT'
                        || $subContentName === 'SUMMARY'
                        || $subContentName === 'TOP DESCRIPTION'
                    ) {
                        $subContent->content = $this->postData['excerpt'] ?? '';
                        $subContent->save();
                    } elseif (
                        $subContentName === 'IMAGE'
                        || $subContentName === 'MAIN IMAGE'
                    ) {
                        if ($featuredImage) {
                            Media::setUsesForModel([$featuredImage->id], $subContent);
                            $subContent->content = '<img src="' . $featuredImage->original_url . '"/>';
                            $subContent->save();
                        }
                    }
                }
            }
        } catch (Exception $exception) {
            Log::error('WordPressArticleImport: ' . $exception->getMessage(), [
                'slug' => $this->postData['slug'] ?? 'unknown',
            ]);
        }
    }

    private function syncCategories(PageModel $page): void
    {
        if (empty($this->categories)) {
            return;
        }

        $categoryIds = [];
        foreach ($this->categories as $cat) {
            $category = ContentCategory::firstOrCreate(
                ['slug' => $cat['slug']],
                ['name' => $cat['name']],
            );
            $categoryIds[] = $category->id;
        }

        $page->categories()->sync($categoryIds);
    }

    private function updatePageSeo(PageModel $page): void
    {
        $seoTitle = $this->postData['seo_title'] ?? null;
        $seoDescription = $this->postData['seo_description'] ?? null;

        if (empty($seoTitle) && empty($seoDescription)) {
            return;
        }

        SeoData::query()->updateOrCreate([
            'path' => $page->urlPath(),
        ], array_filter([
            'title' => $seoTitle ?: $page->title,
            'description' => $seoDescription,
        ]));
    }

    private function processContentImages(string $html, MediaFolder $mediaFolder): string
    {
        if (empty($html)) {
            return '';
        }

        $doc = new DOMDocument();
        libxml_use_internal_errors(true);
        $doc->loadHTML('<?xml encoding="UTF-8">' . $html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
        libxml_clear_errors();

        $images = $doc->getElementsByTagName('img');
        $importedUrls = [];

        foreach ($images as $img) {
            $src = $img->getAttribute('src');

            if (empty($src) || stripos($src, 'base64') !== false) {
                continue;
            }

            if (isset($importedUrls[$src])) {
                $img->setAttribute('src', $importedUrls[$src]);
                continue;
            }

            try {
                $newImage = Media::importImageFromUrl(str_replace(' ', '%20', $src));
                \Mtc\ContentManager\Models\Media::query()
                    ->where('id', $newImage->id)
                    ->update(['folder_id' => $mediaFolder->id]);

                $importedUrls[$src] = $newImage->original_url;
                $img->setAttribute('src', $newImage->original_url);
            } catch (Exception $e) {
                Log::error('WordPressArticleImport: Failed to import inline image', [
                    'url' => $src,
                    'error' => $e->getMessage(),
                ]);
            }
        }

        $output = $doc->saveHTML();
        // Remove the XML encoding declaration we added
        $output = str_replace('<?xml encoding="UTF-8">', '', $output);

        return $output;
    }
}
