<?php

namespace App\Support;

use App\Exceptions\VideoDialogueException;
use App\Services\AI\HiggsfieldSeedanceVideoAvatarProvider;

class VideoDialogue
{
    public static function wordBudget(int $duration, ?string $engine = null): int
    {
        if ($engine === HiggsfieldSeedanceVideoAvatarProvider::ENGINE) {
            $speechSeconds = max(1, $duration - 1);
            $pace = (float) config('creative.higgsfield_spoken_words_per_second', 2.7);

            return max(6, (int) floor($speechSeconds * $pace));
        }

        $extendCount = config('creative.vertex_extend_durations', [])[$duration] ?? null;

        if ($extendCount !== null) {
            return self::clipWordBudget(8) + ((int) $extendCount * self::clipWordBudget(7));
        }

        return self::clipWordBudget($duration);
    }

    public static function wordFloor(int $duration, ?string $engine = null): int
    {
        return max(6, self::wordBudget($duration, $engine) - 2);
    }

    private static function clipWordBudget(int $duration): int
    {
        return max(6, (int) floor(max(1, $duration) * (float) config('creative.spoken_words_per_second', 2.2)));
    }

    public static function wordCount(string $dialogue): int
    {
        return count(preg_split('/\s+/', trim($dialogue), flags: PREG_SPLIT_NO_EMPTY) ?: []);
    }

    public static function assertFits(string $dialogue, int $duration): void
    {
        if (trim($dialogue) === '') {
            throw new VideoDialogueException('Video dialogue is empty. Please generate a new script.');
        }

        if (self::wordCount($dialogue) > self::wordBudget($duration)) {
            throw new VideoDialogueException('Video dialogue is too long for the selected duration. Please generate a shorter script.');
        }
    }

    public static function limitToBudget(string $dialogue, int $duration, ?string $engine = null): string
    {
        $budget = self::wordBudget($duration, $engine);
        $words = preg_split('/\s+/', trim($dialogue), flags: PREG_SPLIT_NO_EMPTY) ?: [];

        if (count($words) <= $budget) {
            return trim($dialogue);
        }

        $trimmed = rtrim(implode(' ', array_slice($words, 0, $budget)), ',;:-');
        if ($trimmed !== '' && preg_match('/[.!?]$/', $trimmed) !== 1) {
            $trimmed .= '.';
        }

        return $trimmed;
    }
}
