<?php

namespace App\Models;

use App\Support\MariachiCatalogManager;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

class MariachiGroup extends Model
{
    protected $fillable = [
        'organization_id',
        'code',
        'name',
        'description',
        'is_active',
        'is_default',
        'sort_order',
    ];

    protected $casts = [
        'organization_id' => 'integer',
        'is_active' => 'boolean',
        'is_default' => 'boolean',
        'sort_order' => 'integer',
    ];

    public static function ensureDefaultForOrganization(int $organizationId): ?self
    {
        if ($organizationId <= 0) {
            return null;
        }

        $organization = Organization::query()->find($organizationId);
        $defaultName = trim((string) ($organization?->name ?? '')) ?: 'Mariachi 1';

        $existing = self::query()
            ->where('organization_id', $organizationId)
            ->orderByDesc('is_default')
            ->orderBy('sort_order')
            ->orderBy('id')
            ->first();

        if ($existing) {
            $shouldSyncLegacyName = Str::lower(trim((string) $existing->name)) === 'mariachi 1'
                && $defaultName !== '';
            $shouldSyncDescription = empty(trim((string) $existing->description));

            if (!$existing->is_default) {
                $existing->is_default = true;
            }

            if ($shouldSyncLegacyName) {
                $existing->name = $defaultName;
            }

            if ($shouldSyncDescription) {
                $existing->description = 'Grupo principal';
            }

            if ($existing->isDirty()) {
                $existing->save();
            }

            return $existing;
        }

        return self::query()->create([
            'organization_id' => $organizationId,
            'code' => 'grupo_1',
            'name' => $defaultName,
            'description' => 'Grupo principal',
            'is_active' => true,
            'is_default' => true,
            'sort_order' => 1,
        ]);
    }

    public function serenatas()
    {
        return $this->hasMany(Serenata::class);
    }

    public function serenataCodePrefix(): string
    {
        $name = trim((string) $this->name);
        $code = trim((string) $this->code);
        $source = $name !== '' ? $name : $code;
        $normalized = (string) Str::of($source)
            ->ascii()
            ->replaceMatches('/[^A-Za-z0-9]+/', ' ')
            ->trim();

        if ($normalized === '') {
            return 'SR';
        }

        $segments = preg_split('/\s+/', $normalized, -1, PREG_SPLIT_NO_EMPTY) ?: [];
        $prefix = '';

        foreach ($segments as $segment) {
            if (ctype_digit($segment)) {
                $prefix .= $segment;
                continue;
            }

            $prefix .= Str::upper(Str::substr($segment, 0, 1));
        }

        if ($prefix === '') {
            $prefix = Str::upper(Str::substr(str_replace(' ', '', $normalized), 0, 3));
        }

        $nameSlug = Str::slug($name, '_');
        $codeSlug = Str::slug($code, '_');
        if (
            $nameSlug !== ''
            && $codeSlug !== ''
            && preg_match('/^' . preg_quote($nameSlug, '/') . '_(\d+)$/', $codeSlug, $matches) === 1
        ) {
            $prefix .= $matches[1];
        }

        return (string) Str::of($prefix)->upper()->substr(0, 8);
    }

    public function customers()
    {
        return $this->hasMany(Customer::class);
    }

    public function giftItems()
    {
        return $this->hasMany(GiftItem::class);
    }

    public function artistItems()
    {
        return $this->hasMany(ArtistItem::class);
    }

    public function otherCostItems()
    {
        return $this->hasMany(OtherCostItem::class);
    }

    public function serenataPackages()
    {
        return $this->hasMany(SerenataPackage::class);
    }

    public function cloneCatalogFrom(self $sourceGroup): void
    {
        MariachiCatalogManager::cloneCatalogs($sourceGroup, $this);
    }

    public function ensureOwnCatalog(): void
    {
        MariachiCatalogManager::bootstrapBaseCatalog($this);
    }
}
