<?php

declare(strict_types=1);

namespace App\Framework\Console\Layout;

final readonly class TerminalSize
{
    public function __construct(
        public int $width,
        public int $height
    ) {
    }

    public static function detect(): self
    {
        $width = 80;  // Default fallback
        $height = 24; // Default fallback

        // Try to get terminal size from stty
        if (function_exists('exec') && strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') {
            $output = [];
            $return = 0;
            exec('stty size 2>/dev/null', $output, $return);

            if ($return === 0 && ! empty($output[0])) {
                $dimensions = explode(' ', trim($output[0]));
                if (count($dimensions) === 2) {
                    $height = (int) $dimensions[0];
                    $width = (int) $dimensions[1];
                }
            }
        }

        // Try environment variables as fallback
        if ($width === 80 || $height === 24) {
            $envWidth = $_ENV['COLUMNS'] ?? $_SERVER['COLUMNS'] ?? null;
            $envHeight = $_ENV['LINES'] ?? $_SERVER['LINES'] ?? null;

            if ($envWidth && is_numeric($envWidth)) {
                $width = (int) $envWidth;
            }
            if ($envHeight && is_numeric($envHeight)) {
                $height = (int) $envHeight;
            }
        }

        return new self($width, $height);
    }

    public function isNarrow(): bool
    {
        return $this->width < 80;
    }

    public function isWide(): bool
    {
        return $this->width >= 120;
    }

    public function isShort(): bool
    {
        return $this->height < 24;
    }

    public function isTall(): bool
    {
        return $this->height >= 40;
    }

    public function getBreakpoint(): TerminalBreakpoint
    {
        return match (true) {
            $this->width >= 160 => TerminalBreakpoint::EXTRA_LARGE,
            $this->width >= 120 => TerminalBreakpoint::LARGE,
            $this->width >= 80 => TerminalBreakpoint::MEDIUM,
            $this->width >= 60 => TerminalBreakpoint::SMALL,
            default => TerminalBreakpoint::EXTRA_SMALL
        };
    }

    public function getUsableWidth(int $padding = 4): int
    {
        return max(40, $this->width - $padding); // Minimum 40 chars
    }

    public function getUsableHeight(int $reserved = 3): int
    {
        return max(10, $this->height - $reserved); // Minimum 10 lines
    }

    public function toArray(): array
    {
        return [
            'width' => $this->width,
            'height' => $this->height,
            'breakpoint' => $this->getBreakpoint()->value,
            'usable_width' => $this->getUsableWidth(),
            'usable_height' => $this->getUsableHeight(),
            'is_narrow' => $this->isNarrow(),
            'is_wide' => $this->isWide(),
            'is_short' => $this->isShort(),
            'is_tall' => $this->isTall(),
        ];
    }
}
