<?php

namespace App\Workflows\Services;

use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;

class StepTemplateService
{
    /**
     * Get all available step template configurations
     */
    public static function getTemplateOptions(): array
    {
        return config('workflows.step_templates', []);
    }

    /**
     * Get system key options based on subject type
     */
    public static function getSystemKeyOptions(?string $subjectType = null): array
    {
        $requiredSteps = config('workflows.required_steps', []);
        $systemKeys = [];

        // Collect all unique system keys from required_steps
        foreach ($requiredSteps as $keys) {
            foreach ($keys as $key) {
                // Convert key to human-readable label
                $systemKeys[$key] = ucwords(str_replace('_', ' ', $key));
            }
        }

        return $systemKeys;
    }

    /**
     * Get required system keys for a subject type
     */
    public static function getRequiredSystemKeys(?string $subjectType = null): array
    {
        $requiredSteps = config('workflows.required_steps', []);

        return $subjectType && isset($requiredSteps[$subjectType])
            ? $requiredSteps[$subjectType]
            : [];
    }

    /**
     * Check if a system key is required for a subject type
     */
    public static function isSystemKeyRequired(string $systemKey, ?string $subjectType = null): bool
    {
        return in_array($systemKey, self::getRequiredSystemKeys($subjectType));
    }

    /**
     * Detect which template key a given record matches
     */
    public static function detectTemplateKey($record): string
    {
        $options = self::getTemplateOptions();

        foreach ($options as $key => $option) {
            // Check if validation, data_bindings, and form_definition match
            $recordValidation = $record->validation ?? [];
            $recordDataBindings = $record->data_bindings ?? [];
            $recordFormDefinition = $record->form_definition ?? [];

            if ($recordValidation == $option['validation'] &&
                $recordDataBindings == $option['data_bindings'] &&
                $recordFormDefinition == ($option['form_definition'] ?? [])) {
                return $key;
            }
        }

        return 'none';
    }

    /**
     * Get template configuration for a specific key
     */
    public static function getTemplate(string $templateKey): ?array
    {
        $options = self::getTemplateOptions();

        return $options[$templateKey] ?? null;
    }

    /**
     * Get dropdown options for Filament select field
     */
    public static function getSelectOptions(): array
    {
        $options = self::getTemplateOptions();
        $selectOptions = ['none' => 'None (Basic Step)'];

        foreach ($options as $key => $option) {
            $selectOptions[$key] = $option['label'];
        }

        return $selectOptions;
    }

    /**
     * Get template label for display purposes
     */
    public static function getTemplateLabel(string $templateKey): string
    {
        if ($templateKey === 'none') {
            return 'Basic Step';
        }

        $options = self::getTemplateOptions();

        return $options[$templateKey]['label'] ?? 'Unknown';
    }

    /**
     * Get suggested system keys for a template
     */
    public static function getSuggestedSystemKeys(string $templateKey): array
    {
        $template = self::getTemplate($templateKey);

        return $template['suggested_system_keys'] ?? [];
    }

    /**
     * Build Filament form components from JSON form definition
     *
     * Supported field types:
     * - text: TextInput (or Textarea if multiline=true)
     * - textarea: Textarea with optional rows
     * - number: TextInput with numeric validation and min/max/step
     * - date: DatePicker with optional min_date/max_date
     *
     * Common attributes:
     * - name: Field name (required)
     * - label: Display label (defaults to formatted name)
     * - required: Whether field is required (boolean)
     * - helper_text: Helper text below field
     * - disabled: Whether field is disabled (boolean)
     * - placeholder: Placeholder text
     */
    public static function buildFormComponents(array $formDefinition): array
    {
        $components = [];

        foreach ($formDefinition as $field) {
            $component = self::createFilamentComponent($field);
            if ($component) {
                $components[] = $component;
            }
        }

        return $components;
    }

    /**
     * Create a single Filament component from field definition
     */
    protected static function createFilamentComponent(array $field)
    {
        $type = $field['type'];
        $name = $field['name'];
        $label = $field['label'] ?? ucfirst(str_replace('_', ' ', $name));

        switch ($type) {
            case 'text':
                if (isset($field['multiline']) && $field['multiline']) {
                    $component = Textarea::make($name)
                        ->label($label);
                } else {
                    $component = TextInput::make($name)
                        ->label($label);
                }

                if (isset($field['placeholder'])) {
                    $component->placeholder($field['placeholder']);
                }

                break;

            case 'textarea':
                $component = Textarea::make($name)
                    ->label($label);

                if (isset($field['placeholder'])) {
                    $component->placeholder($field['placeholder']);
                }

                if (isset($field['rows'])) {
                    $component->rows($field['rows']);
                }

                break;
            case 'number':
                $component = TextInput::make($name)
                    ->label($label)
                    ->numeric();

                if (isset($field['min'])) {
                    $component->minValue($field['min']);
                }

                if (isset($field['max'])) {
                    $component->maxValue($field['max']);
                }

                if (isset($field['step'])) {
                    $component->step($field['step']);
                }

                break;

            case 'date':
                $component = DatePicker::make($name)
                    ->label($label);

                if (isset($field['min_date'])) {
                    $component->minDate($field['min_date']);
                }

                if (isset($field['max_date'])) {
                    $component->maxDate($field['max_date']);
                }

                break;

            default:
                return null;
        }

        // Apply common attributes
        if (isset($field['required']) && $field['required']) {
            $component->required();
        }

        if (isset($field['helper_text'])) {
            $component->helperText($field['helper_text']);
        }

        if (isset($field['disabled']) && $field['disabled']) {
            $component->disabled();
        }

        return $component;
    }

    /**
     * Get form definition for a step template or step instance
     */
    public static function getFormDefinition($stepTemplateOrKey): array
    {
        // If it's a string, it's a template key
        if (is_string($stepTemplateOrKey)) {
            $template = self::getTemplate($stepTemplateOrKey);

            return $template['form_definition'] ?? [];
        }

        // If it's an object with form_definition property
        if (is_object($stepTemplateOrKey) && isset($stepTemplateOrKey->form_definition)) {
            return is_array($stepTemplateOrKey->form_definition)
                ? $stepTemplateOrKey->form_definition
                : json_decode($stepTemplateOrKey->form_definition, true) ?? [];
        }

        return [];
    }
}
