<?php

namespace App\Support;

use App\Models\ArtistItem;
use App\Models\CatalogPriceRule;
use App\Models\GiftItem;
use App\Models\MariachiGroup;
use App\Models\OtherCostItem;
use App\Models\SerenataPackage;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;

class MariachiCatalogManager
{
    public static function bootstrapBaseCatalog(MariachiGroup $group): void
    {
        if ($group->artistItems()->exists() || $group->giftItems()->exists() || $group->otherCostItems()->exists()) {
            return;
        }

        foreach (ArtistItem::defaultCatalog() as $item) {
            $group->artistItems()->create(array_merge($item, [
                'organization_id' => $group->organization_id,
                'internal_cost' => (float) ($item['internal_cost'] ?? $item['base_price'] ?? 0),
                'base_price' => (float) ($item['base_price'] ?? 0),
                'is_active' => true,
            ]));
        }

        foreach (GiftItem::defaultCatalog() as $item) {
            $group->giftItems()->create(array_merge($item, [
                'organization_id' => $group->organization_id,
                'internal_cost' => (float) ($item['internal_cost'] ?? $item['base_price'] ?? 0),
                'base_price' => (float) ($item['base_price'] ?? 0),
                'is_active' => true,
                'is_default' => (bool) ($item['is_default'] ?? false),
            ]));
        }

        foreach (OtherCostItem::defaultCatalog() as $item) {
            $group->otherCostItems()->create(array_merge($item, [
                'organization_id' => $group->organization_id,
                'internal_cost' => (float) ($item['internal_cost'] ?? $item['base_price'] ?? 0),
                'base_price' => (float) ($item['base_price'] ?? 0),
                'is_active' => true,
            ]));
        }
    }

    public static function cloneCatalogs(MariachiGroup $sourceGroup, MariachiGroup $targetGroup): void
    {
        if ($sourceGroup->id === $targetGroup->id) {
            return;
        }

        self::bootstrapBaseCatalog($sourceGroup);

        self::cloneItemCollection($sourceGroup->giftItems()->with('priceRules')->get(), $targetGroup, GiftItem::class);
        self::cloneItemCollection($sourceGroup->artistItems()->with('priceRules')->get(), $targetGroup, ArtistItem::class);
        self::cloneItemCollection($sourceGroup->otherCostItems()->with('priceRules')->get(), $targetGroup, OtherCostItem::class);
        self::cloneItemCollection($sourceGroup->serenataPackages()->with('priceRules')->get(), $targetGroup, SerenataPackage::class);
    }

    /**
     * @param  Collection<int, Model>  $items
     */
    private static function cloneItemCollection(Collection $items, MariachiGroup $targetGroup, string $targetClass): void
    {
        $clonedIdMap = [];

        foreach ($items as $item) {
            $attributes = collect($item->getAttributes())
                ->except(['id', 'created_at', 'updated_at'])
                ->all();

            $attributes['organization_id'] = $targetGroup->organization_id;
            $attributes['mariachi_group_id'] = $targetGroup->id;

            if ($targetClass === SerenataPackage::class) {
                $attributes['gift_codes'] = $item->gift_codes ?? [];
                $attributes['artist_codes'] = $item->artist_codes ?? [];
                $attributes['other_cost_codes'] = $item->other_cost_codes ?? [];
            }

            $cloned = $targetClass::query()->create($attributes);
            $clonedIdMap[(int) $item->id] = $cloned;
        }

        foreach ($items as $item) {
            /** @var Model|null $cloned */
            $cloned = $clonedIdMap[(int) $item->id] ?? null;
            if (!$cloned || !method_exists($item, 'priceRules')) {
                continue;
            }

            foreach ($item->priceRules as $rule) {
                $ruleAttributes = collect($rule->getAttributes())
                    ->except(['id', 'priceable_id', 'priceable_type', 'created_at', 'updated_at'])
                    ->all();

                CatalogPriceRule::query()->create(array_merge($ruleAttributes, [
                    'organization_id' => $targetGroup->organization_id,
                    'priceable_type' => $cloned::class,
                    'priceable_id' => $cloned->getKey(),
                ]));
            }
        }
    }
}
