<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use App\Models\Player;

class FootballMatch extends Model
{
    use HasFactory;

    protected $table = 'matches';

    protected $fillable = [
        'home_team_id',
        'away_team_id',
        'date',
        'venue',
        'competition',
        'status',
        'score_home',
        'score_away',
        'period',
        'timer_accumulated',
        'timer_started_at',
        'running',
        'show_overlay',
        'show_sponsors',
        'lineup_side',
        'extra_time',
        'popup',
        'notes',
    ];

    protected $casts = [
        'date'              => 'datetime',
        'timer_started_at'  => 'datetime',
        'timer_accumulated' => 'float',
        'running'           => 'boolean',
        'show_overlay'      => 'boolean',
        'show_sponsors'     => 'boolean',
        'score_home'        => 'integer',
        'score_away'        => 'integer',
        'extra_time'        => 'integer',
        'popup'             => 'array',
    ];

    public function homeTeam(): BelongsTo
    {
        return $this->belongsTo(Team::class, 'home_team_id');
    }

    public function awayTeam(): BelongsTo
    {
        return $this->belongsTo(Team::class, 'away_team_id');
    }

    public function events(): HasMany
    {
        return $this->hasMany(MatchEvent::class, 'match_id')->orderByDesc('created_at');
    }

    /**
     * Get current elapsed seconds.
     * Uses Carbon's absolute difference to avoid sign issues across Carbon versions.
     */
    public function currentSeconds(): float
    {
        if ($this->running && $this->timer_started_at) {
            $elapsed = now()->diffInSeconds($this->timer_started_at);
            return max(0.0, (float) $this->timer_accumulated + $elapsed);
        }

        return max(0.0, (float) $this->timer_accumulated);
    }

    /**
     * Build the full broadcast state payload sent to Reverb and the public API.
     * All team relations are loaded safely — missing teams return null-safe defaults.
     */
    public function toBroadcastState(): array
    {
        $home = $this->relationLoaded('homeTeam') ? $this->homeTeam : $this->homeTeam()->first();
        $away = $this->relationLoaded('awayTeam') ? $this->awayTeam : $this->awayTeam()->first();

        return [
            'matchId'          => $this->id,
            'home'             => $home ? [
                'name'    => $home->name,
                'short'   => $home->short   ?? mb_substr($home->name, 0, 3),
                'letter'  => $home->letter  ?? mb_strtoupper(mb_substr($home->name, 0, 1)),
                'color'   => $home->color   ?? '#1e3a5f',
                'variant' => 'home',
            ] : ['name' => 'Home', 'short' => 'HOM', 'letter' => 'H', 'color' => '#1e3a5f', 'variant' => 'home'],
            'away'             => $away ? [
                'name'    => $away->name,
                'short'   => $away->short   ?? mb_substr($away->name, 0, 3),
                'letter'  => $away->letter  ?? mb_strtoupper(mb_substr($away->name, 0, 1)),
                'color'   => $away->color   ?? '#8b1a1a',
                'variant' => 'away',
            ] : ['name' => 'Away', 'short' => 'AWY', 'letter' => 'A', 'color' => '#8b1a1a', 'variant' => 'away'],
            'scoreHome'        => $this->score_home,
            'scoreAway'        => $this->score_away,
            'period'           => $this->period,
            'timerAccumulated' => $this->timer_accumulated,
            'timerStartedAt'   => $this->timer_started_at?->timestamp,
            'running'          => $this->running,
            'showOverlay'      => $this->show_overlay,
            'showSponsors'     => $this->show_sponsors ?? true,
            'extraTime'        => $this->extra_time,
            'popup'            => $this->popup,
            'events'           => $this->events()
                ->take(20)
                ->get()
                ->map(fn (MatchEvent $e) => $e->toArray())
                ->values()
                ->toArray(),
            'sponsors'         => Sponsor::where('visible', true)
                ->orderBy('sort_order')
                ->get()
                ->map(fn (Sponsor $s) => [
                    'id'      => $s->getKey(),
                    'name'    => $s->name,
                    'tier'    => $s->tier,
                    'visible' => (bool) $s->getAttribute('visible'),
                ])
                ->values()
                ->toArray(),
            'lineupSide'       => $this->lineup_side,
            'lineupPlayers'    => $this->buildLineupPlayers($home, $away),
        ];
    }

    private function buildLineupPlayers(?Team $home, ?Team $away): array
    {
        if (! $this->lineup_side) {
            return [];
        }

        $team = $this->lineup_side === 'home' ? $home : $away;

        if (! $team) {
            return [];
        }

        return Player::where('team_id', $team->id)
            ->orderBy('number')
            ->get()
            ->map(fn (Player $p) => [
                'id'       => $p->id,
                'number'   => $p->number,
                'name'     => $p->name,
                'position' => $p->position,
                'photoUrl' => $p->photo_url,
            ])
            ->values()
            ->toArray();
    }
}
