<?php

namespace PHPNative\Tailwind\Model;

use PHPNative\Core\TypedCollection;
use PHPNative\Tailwind\Style\Border;
use PHPNative\Tailwind\Style\Flex;
use PHPNative\Tailwind\Style\Margin;
use PHPNative\Tailwind\Style\MediaQueryEnum;
use PHPNative\Tailwind\Style\Padding;
use PHPNative\Tailwind\Style\StateEnum;
use PHPNative\Tailwind\Style\Text;

class StyleCollection extends TypedCollection
{
    protected function type(): string
    {
        return Style::class;
    }

    public function getValidStyles(MediaQueryEnum $mediaQueryEnum, StateEnum $state): array
    {
        $items = [];

        foreach($this->items() as $style) {
            if(($style->state == StateEnum::normal || $style->state === $state) && ($style->mediaQuery->value === 0 || $style->mediaQuery->value <= $mediaQueryEnum->value)) {
                $items[] = $style;
            }
        }

        return $this->merge($items);
    }

    private function merge(array $styles): array
    {
        $tmp = [];

        foreach($styles as $style) {
            $className = $style->style::class;

            // Ensure we always work on cloned styles in the merged result
            if (!isset($tmp[$className])) {
                $tmp[$className] = clone $style->style;
                continue;
            }

            if ($className === Padding::class) {
                \PHPNative\Tailwind\Parser\Padding::merge($tmp[$className], $style->style);
            } elseif ($className === Margin::class) {
                \PHPNative\Tailwind\Parser\Margin::merge($tmp[$className], $style->style);
            } elseif ($className === Border::class) {
                \PHPNative\Tailwind\Parser\Border::merge($tmp[$className], $style->style);
            } elseif ($className === Text::class) {
                \PHPNative\Tailwind\Parser\Text::merge($tmp[$className], $style->style);
            } elseif ($className === Flex::class) {
                \PHPNative\Tailwind\Parser\Flex::merge($tmp[$className], $style->style);
            } elseif ($className === \PHPNative\Tailwind\Style\Shadow::class) {
                \PHPNative\Tailwind\Parser\Shadow::merge($tmp[$className], $style->style);
            } else {
                // Default: overwrite with cloned instance
                $tmp[$className] = clone $style->style;
            }
        }

        return $tmp;
    }

    public function __clone()
    {
        $cloned = [];
        foreach ($this->items() as $style) {
            $cloned[] = clone $style;
        }

        $this->setElements($cloned);
    }
}
