<?php

namespace OtomaticAi\Content\Image;

use DOMDocument;
use DOMElement;
use OtomaticAi\Content\Contracts\ShouldDisplay;
use OtomaticAi\Utils\Image as UtilsImage;

class Image implements ShouldDisplay
{
    const PROVIDER = "image";

    public UtilsImage $image;
    public ?string $title;
    public ?string $description;
    public ?string $legend;
    public ?string $uid;

    /**
     * @param UtilsImage $image
     * @param string $title
     * @param string $description
     * @param string $legend
     * @param string $uid
     */
    public function __construct(UtilsImage $image, string $title = null, string $description = null, string $legend = null, string $uid = null)
    {
        $this->image = $image;
        $this->title = $title;
        $this->description = $description;
        $this->legend = $legend;

        if ($uid) {
            $this->uid = $uid;
        } else {
            $this->uid = uniqid("image-");
        }
    }

    /**
     * @param DOMDocument $document
     * @return DOMElement|null
     */
    public function toHtmlElement(DOMDocument $document): ?DOMElement
    {
        if (($attachmentId = $this->image->save($this->title, $this->description, $this->legend)) !== null) {
            $el = $document->createElement("otoimage");
            $el->setAttribute("attachment", $attachmentId);
            $el->setAttribute("uid", $this->uid);

            return $el;
        }

        return null;
    }

    /**
     * @return array|null
     */
    public function toArray(): ?array
    {
        if (($attachmentId = $this->image->save($this->title, $this->description, $this->legend)) !== null) {
            return [
                "attachment" => $attachmentId,
                "uid" => $this->uid,
            ];
        }

        return null;
    }

    /**
     * @param DOMElement $node
     * @return DOMElement|null
     */
    public function toDisplayElement(DOMElement $node): ?DOMElement
    {
        $attachmentId = $this->image->getAttachmentId();
        if (!empty($attachmentId)) {

            $clone = $node->ownerDocument->createElement("otoimage");
            foreach ($node->attributes as $attribute) {
                $clone->setAttribute($attribute->name, stripslashes($attribute->value));
            }

            $srcs = wp_get_attachment_image_src($attachmentId, "full");
            if (!empty($srcs)) {
                $clone->setAttribute("src", $srcs[0]);
                $clone->setAttribute("uid", $this->uid);

                return $clone;
            }
        }

        return null;
    }

    /**
     * @param DOMElement $node
     * @return self|null
     */
    static public function fromHtmlElement(DOMElement $node): ?self
    {
        $provider = $node->getAttribute("provider");

        switch ($provider) {
            case "flux":
                return Flux::fromHtmlElement($node);
            case "dall-e":
                return DallE::fromHtmlElement($node);
            case "ideogram":
                return Ideogram::fromHtmlElement($node);
            case "grok":
                return Grok::fromHtmlElement($node);
            case "gemini":
                return Gemini::fromHtmlElement($node);
            case "pexels":
                return Pexels::fromHtmlElement($node);
            case "pixabay":
                return Pixabay::fromHtmlElement($node);
            case "stable-diffusion":
                return StableDiffusion::fromHtmlElement($node);
            case "unsplash":
                return Unsplash::fromHtmlElement($node);
            case "google-image":
                return GoogleImage::fromHtmlElement($node);
            case "bing-image":
                return BingImage::fromHtmlElement($node);
        }

        return null;
    }

    /**
     * @param array $data
     * @return self|null
     */
    static public function fromArray(array $data): ?self
    {
        $provider = $data["provider"];

        switch ($provider) {
            case "flux":
                return Flux::fromArray($data);
            case "dall-e":
                return DallE::fromArray($data);
            case "ideogram":
                return Ideogram::fromArray($data);
            case "grok":
                return Grok::fromArray($data);
            case "gemini":
                return Gemini::fromArray($data);
            case "pexels":
                return Pexels::fromArray($data);
            case "pixabay":
                return Pixabay::fromArray($data);
            case "stable-diffusion":
                return StableDiffusion::fromArray($data);
            case "unsplash":
                return Unsplash::fromArray($data);
            case "google-image":
                return GoogleImage::fromArray($data);
            case "bing-image":
                return BingImage::fromArray($data);
        }

        return null;
    }
}
