<?php

declare(strict_types=1);

/**
 * AI Response Data Transfer Object
 *
 * Represents the structured response from AI model interactions
 */
readonly class AiResponseDto
{
    /**
     * @param string|null $sql Generated SQL query (if any)
     * @param string|null $explanation AI explanation or response text
     * @param array $metadata Additional metadata from AI response
     */
    public function __construct(
        public ?string $sql = null,
        public ?string $explanation = null,
        public array $metadata = [],
    ) {}

    /**
     * Create DTO from array response
     *
     * @param array $response Raw AI response array
     * @return self
     */
    public static function fromArray(array $response): self
    {
        return new self(
            sql: $response['sql'] ?? null,
            explanation: $response['explanation'] ?? null,
            metadata: array_diff_key($response, array_flip(['sql', 'explanation'])),
        );
    }

    /**
     * Check if response contains SQL query
     *
     * @return bool
     */
    public function hasSql(): bool
    {
        return !empty($this->sql);
    }

    /**
     * Check if response contains explanation
     *
     * @return bool
     */
    public function hasExplanation(): bool
    {
        return !empty($this->explanation);
    }

    /**
     * Convert DTO to array
     *
     * @return array
     */
    public function toArray(): array
    {
        $result = [];

        if ($this->sql !== null) {
            $result['sql'] = $this->sql;
        }

        if ($this->explanation !== null) {
            $result['explanation'] = $this->explanation;
        }

        return array_merge($result, $this->metadata);
    }

    /**
     * Get SQL query with validation
     *
     * @return string
     * @throws InvalidArgumentException If no SQL is available
     */
    public function getSql(): string
    {
        if (!$this->hasSql()) {
            throw new InvalidArgumentException('AI response does not contain SQL query');
        }

        return $this->sql;
    }

    /**
     * Get explanation with validation
     *
     * @return string
     * @throws InvalidArgumentException If no explanation is available
     */
    public function getExplanation(): string
    {
        if (!$this->hasExplanation()) {
            throw new InvalidArgumentException('AI response does not contain explanation');
        }

        return $this->explanation;
    }
}
