<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Component extends Model
{
    /**
     * Component entity for representing discovered Twig components
     *
     * This model is not backed by a database table - it's a data structure
     * for representing component metadata during runtime.
     */

    protected $fillable = [
        'name',
        'filename',
        'path',
        'absolute_path',
        'category',
        'description',
        'file_size',
        'modified_at',
        'is_renderable',
        'error_message',
    ];

    protected $casts = [
        'modified_at' => 'datetime',
        'is_renderable' => 'boolean',
        'file_size' => 'integer',
    ];

    /**
     * Create component instance from file path
     */
    public static function fromFilePath(string $absolutePath, string $relativePath): self
    {
        $filename = basename($absolutePath);
        $name = self::generateName($filename);
        $category = self::extractCategory($relativePath);
        $description = self::generateDescription($name, $category);

        return new self([
            'name' => $name,
            'filename' => $filename,
            'path' => $relativePath,
            'absolute_path' => $absolutePath,
            'category' => $category,
            'description' => $description,
            'file_size' => file_exists($absolutePath) ? filesize($absolutePath) : 0,
            'modified_at' => file_exists($absolutePath) ? filemtime($absolutePath) : time(),
            'is_renderable' => true,
            'error_message' => null,
        ]);
    }

    /**
     * Generate display name from filename
     */
    public static function generateName(string $filename): string
    {
        $name = pathinfo($filename, PATHINFO_FILENAME);
        $name = str_replace(['_', '-'], ' ', $name);
        $name = ucwords($name);

        return $name;
    }

    /**
     * Extract category from relative path
     */
    public static function extractCategory(string $relativePath): string
    {
        $pathParts = explode('/', dirname($relativePath));
        $categoryParts = array_filter($pathParts, function($part) {
            return $part !== '.' && !empty($part);
        });

        if (empty($categoryParts)) {
            return 'general';
        }

        return implode('/', $categoryParts);
    }

    /**
     * Generate description from name and category
     */
    public static function generateDescription(string $name, string $category): string
    {
        $categoryName = str_replace(['/', '_', '-'], ' ', $category);
        $categoryName = ucwords($categoryName);

        return $name . ' component for ' . strtolower($categoryName) . ' functionality';
    }

    /**
     * Mark component as non-renderable with error
     */
    public function markAsError(string $errorMessage): void
    {
        $this->is_renderable = false;
        $this->error_message = $errorMessage;
    }

    /**
     * Get component for JSON serialization
     */
    public function toArray()
    {
        return [
            'name' => $this->name,
            'filename' => $this->filename,
            'path' => $this->path,
            'category' => $this->category,
            'description' => $this->description,
            'file_size' => $this->file_size,
            'modified_at' => $this->modified_at?->toISOString(),
            'is_renderable' => $this->is_renderable,
            'error_message' => $this->error_message,
        ];
    }
}