<?php

namespace GriffinForms\Admin\App\Html\Modals\Integrations\Renders;

use GriffinForms\Config;

/**
 * Base Format class for integration view renderers
 *
 * Provides common rendering methods and helpers for all integration views:
 * - GridView: Grid of all integrations
 * - InfoView: Individual integration details
 * - ConfigView: Configuration form
 *
 * @since 1.0.0
 */
abstract class Format
{
    protected $config;

    public function __construct()
    {
        $this->config = Config::getInstance();
    }

    /**
     * Render the view
     *
     * @return string HTML output
     */
    abstract public function render($data = []): string;

    // ========== Common Helper Methods ==========

    /**
     * Escape HTML attributes
     *
     * @param string $text Text to escape
     * @return string Escaped text
     */
    protected function escAttr(string $text): string
    {
        return esc_attr($text);
    }

    /**
     * Escape HTML content
     *
     * @param string $text Text to escape
     * @return string Escaped text
     */
    protected function escHtml(string $text): string
    {
        return esc_html($text);
    }

    /**
     * Escape and safe URL
     *
     * @param string $url URL to escape
     * @return string Escaped URL
     */
    protected function escUrl(string $url): string
    {
        return esc_url($url);
    }

    /**
     * Translate text
     *
     * @param string $text Text to translate
     * @return string Translated text
     */
    protected function trans(string $text): string
    {
        return __($text, 'griffinforms-form-builder');
    }

    /**
     * Get CSS class string from array
     *
     * @param array $classes Array of class names
     * @return string Space-separated class string
     */
    protected function getClasses(array $classes): string
    {
        return implode(' ', array_filter($classes));
    }

    /**
     * Render data attribute for JavaScript
     *
     * @param string $key Attribute name (without 'data-' prefix)
     * @param mixed $value Attribute value
     * @return string data-* attribute
     */
    protected function dataAttr(string $key, $value = ''): string
    {
        $key = $this->escAttr($key);
        if (is_array($value) || is_object($value)) {
            $value = json_encode($value);
        }
        $value = $this->escAttr((string) $value);
        return "data-{$key}=\"{$value}\"";
    }

    /**
     * Build integration card status badge HTML
     *
     * @param array $provider Provider metadata
     * @param array $status Integration status
     * @return string Badge HTML
     */
    protected function renderStatusBadge(array $provider, array $status = []): string
    {
        $configured = $status['configured'] ?? $provider['configured'] ?? false;
        $active = $status['active'] ?? $provider['active'] ?? false;

        if ($active) {
            $badge_class = 'badge bg-success';
            $badge_text = __('Active', 'griffinforms-form-builder');
        } elseif ($configured) {
            $badge_class = 'badge bg-info';
            $badge_text = __('Configured', 'griffinforms-form-builder');
        } else {
            $badge_class = 'badge bg-secondary';
            $badge_text = __('Not Configured', 'griffinforms-form-builder');
        }

        return sprintf(
            '<span class="%s">%s</span>',
            $this->escAttr($badge_class),
            $this->escHtml($badge_text)
        );
    }

    /**
     * Render integration icon
     *
     * @param array $provider Provider metadata
     * @param bool $dark Use dark icon variant?
     * @return string Image HTML
     */
    protected function renderIcon(array $provider, bool $dark = false): string
    {
        $icon = $dark ? ($provider['icon_dark'] ?? $provider['icon']) : $provider['icon'];
        $name = $this->escAttr($provider['name']);
        $url = $this->escUrl($icon);

        return sprintf(
            '<img src="%s" alt="%s" class="gf-integration-icon" loading="lazy">',
            $url,
            $name
        );
    }

    /**
     * Render loading spinner
     *
     * @return string Spinner HTML
     */
    protected function renderSpinner(): string
    {
        return '<div class="spinner-border spinner-border-sm ms-2" role="status">
                    <span class="visually-hidden">' . esc_html__('Loading...', 'griffinforms-form-builder') . '</span>
                </div>';
    }

    /**
     * Render error message
     *
     * @param string $message Error message
     * @return string Alert HTML
     */
    protected function renderError(string $message): string
    {
        return sprintf(
            '<div class="alert alert-danger alert-dismissible fade show" role="alert">%s<button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>',
            $this->escHtml($message)
        );
    }

    /**
     * Render success message
     *
     * @param string $message Success message
     * @return string Alert HTML
     */
    protected function renderSuccess(string $message): string
    {
        return sprintf(
            '<div class="alert alert-success alert-dismissible fade show" role="alert">%s<button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>',
            $this->escHtml($message)
        );
    }

    /**
     * Render info message
     *
     * @param string $message Info message
     * @return string Alert HTML
     */
    protected function renderInfo(string $message): string
    {
        return sprintf(
            '<div class="alert alert-info alert-dismissible fade show" role="alert">%s<button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>',
            $this->escHtml($message)
        );
    }

    /**
     * Render a button
     *
     * @param string $text Button text
     * @param string $class Button class (gf-btn gf-btn-primary, etc.)
     * @param array $attrs Additional HTML attributes
     * @return string Button HTML
     */
    protected function renderButton(string $text, string $class = 'gf-btn gf-btn-primary', array $attrs = []): string
    {
        $attrs_str = '';
        foreach ($attrs as $key => $value) {
            $attrs_str .= ' ' . $this->escAttr($key) . '="' . $this->escAttr($value) . '"';
        }

        return sprintf(
            '<button type="button" class="%s"%s>%s</button>',
            $this->escAttr($class),
            $attrs_str,
            $this->escHtml($text)
        );
    }

    /**
     * Get root URL for assets
     *
     * @return string Root URL of plugin
     */
    protected function getRootUrl(): string
    {
        return $this->config->getRootUrl();
    }
}
