<?php

namespace GriffinForms\Admin\App\FormControls;

abstract class Format
{
    protected $field = [];
    protected $field_key = '';
    protected $field_value = '';
    protected $context_id = '';

    public function __construct(string $field_key, $field_value = '', string $context_id = '', array $field_config = [])
    {
        $this->field_key = $field_key;
        $this->field_value = $field_value;
        $this->context_id = $context_id;
        $this->field = $field_config;
    }

    protected function getHtmlId(): string
    {
        $context = $this->context_id !== '' ? sanitize_key($this->context_id) : 'app';
        return sprintf('gf-%s-%s', $context, sanitize_key($this->field_key));
    }

    protected function getFieldName(): string
    {
        return $this->field['name'] ?? $this->field_key;
    }

    protected function getLabel(): string
    {
        return $this->field['label'] ?? ucfirst(str_replace('_', ' ', $this->field_key));
    }

    protected function shouldRenderLabel(): bool
    {
        return !isset($this->field['show_label']) || !empty($this->field['show_label']);
    }

    protected function isRequired(): bool
    {
        return !empty($this->field['required']);
    }

    protected function getDescription(): string
    {
        return $this->field['description'] ?? '';
    }

    protected function getContainerClasses(): string
    {
        $classes = ['mb-3', 'gf-app-control'];
        if (!empty($this->field['container_classes'])) {
            $classes[] = trim((string) $this->field['container_classes']);
        }
        return trim(implode(' ', $classes));
    }

    protected function getLabelClasses(): string
    {
        $classes = ['form-label', 'gf-app-control-label'];
        if (!empty($this->field['label_classes'])) {
            $classes[] = trim((string) $this->field['label_classes']);
        }
        return trim(implode(' ', $classes));
    }

    protected function getInputClasses(): string
    {
        $classes = ['form-control', 'gf-app-control-input'];
        if (!empty($this->field['input_classes'])) {
            $classes[] = trim((string) $this->field['input_classes']);
        }
        return trim(implode(' ', $classes));
    }

    protected function getInputAttributes(): array
    {
        return isset($this->field['attributes']) && is_array($this->field['attributes'])
            ? $this->field['attributes']
            : [];
    }

    abstract public function render(): string;

    protected function renderLabel(): string
    {
        if (!$this->shouldRenderLabel()) {
            return '';
        }

        $label = $this->getLabel();
        $html_id = $this->getHtmlId();
        $required_mark = $this->isRequired() ? '<span class="text-danger">*</span>' : '';

        return sprintf(
            '<label for="%s" class="%s">%s %s</label>',
            esc_attr($html_id),
            esc_attr($this->getLabelClasses()),
            esc_html($label),
            $required_mark
        );
    }

    protected function renderDescription(): string
    {
        $description = $this->getDescription();
        if ($description === '') {
            return '';
        }

        return sprintf(
            '<div class="form-text gf-app-control-description">%s</div>',
            esc_html($description)
        );
    }

    protected function renderAttributes(array $attrs): string
    {
        $html = '';
        foreach ($attrs as $attr_name => $attr_value) {
            if ($attr_value === null || $attr_value === false) {
                continue;
            }

            if ($attr_value === true) {
                $html .= sprintf(' %s="%s"', esc_attr($attr_name), esc_attr($attr_name));
                continue;
            }

            $html .= sprintf(' %s="%s"', esc_attr($attr_name), esc_attr((string) $attr_value));
        }

        return $html;
    }
}
