<?php

namespace GriffinForms\Admin\App\Html\Elements;

use \GriffinForms\Traits\Singleton;

class FormTree
{
    use Singleton;

    protected $form_id;

    public function setFormId($form_id)
    {
        $this->form_id = absint($form_id);
    }

    public function getHtml()
    {
        $form = \GriffinForms\Admin\Sql\App::getInstance()->getFormStructure($this->form_id);
        if (!$form || empty($form['pages'])) {
            echo '<div class="gf-form-tree small"><div class="gf-notice gf-notice-warning m-2">' . esc_html__('Form structure not available.', 'griffinforms-form-builder') . '</div></div>';
            return;
        }

        $this->printStructureCounts($form);

        echo '<div class="gf-form-tree">';
        echo '<ul>';
        echo '<li>';
        echo '<div class="gf-form-tree-row">';
        $this->printChevronHtml(!empty($form['pages']));
        echo '<span role="button" class="gf-form-tree-label">' . esc_html($form['name'] ?? __('Untitled Form', 'griffinforms-form-builder')) . '</span>';
        echo '</div>';
        echo '<ul>';
        foreach ($form['pages'] as $page) {
            $this->printPageHtml($page);
        }
        echo '</ul></li>';
        echo '</ul>';
        echo '</div>';
    }

    /**
     * Prints the structure counts for pages, rows, and columns.
     */
    private function printStructureCounts($form)
    {
        $page_count = count($form['pages']);
        $row_count = 0;
        $field_count = 0;

        foreach ($form['pages'] as $page) {
            foreach ($page['rows'] as $row) {
                $row_count++;
                foreach ($row['columns'] as $col) {
                    $field_count += count($col['fields']);
                }
            }
        }

        echo '<div class="gf-formtree-counts">';
        echo '<span class="gf-structure-chip"><span class="material-symbols-rounded">draft</span>' . absint($page_count) . '</span>';
        echo '<span class="gf-structure-chip"><span class="material-symbols-rounded">table_rows</span>' . absint($row_count) . '</span>';
        echo '<span class="gf-structure-chip"><span class="material-symbols-rounded">variables</span>' . absint($field_count) . '</span>';
        echo '</div>';
    }

    private function printPageHtml($page)
    {
        $has_rows = !empty($page['rows']);
        $page_label = !empty($page['heading'])
            ? $page['heading']
            : (!empty($page['name'])
                ? $page['name']
                : sprintf(__('Page %d', 'griffinforms-form-builder'), $page['id']));

        echo '<li data-gf-itemtype="formpage" data-gf-itemid="' . esc_attr($page['id']) . '">';
        echo '<div class="gf-form-tree-row">';
        $this->printChevronHtml($has_rows);
        echo '<span role="button" class="gf-form-tree-label" data-gf-itemtype="formpage" data-gf-itemid="' . esc_attr($page['id']) . '">' . esc_html($page_label) . '</span>';
        $child_count = count($page['rows']);
        echo '<span class="gf-form-tree-count-badge">' . absint($child_count) . '</span>';
        echo '</div>';
        echo '<ul>';
        foreach ($page['rows'] as $row) {
            $this->printRowHtml($row);
        }
        echo '</ul></li>';
    }

    private function printRowHtml($row)
    {
        $has_columns = !empty($row['columns']);
        $row_label = !empty($row['heading'])
            ? $row['heading']
            : (!empty($row['name'])
                ? $row['name']
                : sprintf(__('Row %d', 'griffinforms-form-builder'), $row['id']));

        echo '<li data-gf-itemtype="pagerow" data-gf-itemid="' . esc_attr($row['id']) . '">';
        echo '<div class="gf-form-tree-row">';
        $this->printChevronHtml($has_columns);
        echo '<span role="button" class="gf-form-tree-label" data-gf-itemtype="pagerow" data-gf-itemid="' . esc_attr($row['id']) . '">' . esc_html($row_label) . '</span>';
        $child_count = count($row['columns']);
        echo '<span class="gf-form-tree-count-badge">' . absint($child_count) . '</span>';
        echo '</div>';
        echo '<ul>';
        $start = 0;
        foreach ($row['columns'] as $column) {
            $start_width = isset($column['width']) ? (int) $column['width'] : 0;
            $start += $start_width;
            foreach ($column['fields'] as $field) {
                $this->printFieldHtml($field, $start_width, $start - $start_width);
            }
        }
        echo '</ul></li>';
    }

    private function printColumnHtml($column, $start)
    {
        $name = __('col', 'griffinforms-form-builder');
        $unit_width = isset($column['width']) ? (int) $column['width'] : 0;
        $width = $unit_width ? round(($unit_width / 12) * 100) : null;
        echo '<li data-gf-itemtype="rowcolumn" data-gf-itemid="' . esc_attr($column['id']) . '">';
        // Wrap label and width in a flex container for vertical alignment
        echo '<span class="d-flex gap-1 align-items-center">';
        echo '<span role="button" class="gf-form-tree-label d-inline-block">' . esc_html__('Column', 'griffinforms-form-builder') . '</span>';
        if ($width !== null) {
            echo '<span class="gf-form-tree-meta">· ' . esc_html($width . '%') . '</span>';
        }
        if ($width !== null) {
            $this->printColumnSymbol($start, $unit_width);
        }
        echo '</span>';
        echo '<ul>';
        foreach ($column['fields'] as $field) {
            $this->printFieldHtml($field);
        }
        echo '</ul></li>';
    }

    private function printColumnSymbol($start, $unit_width)
    {
        echo '<div class="gf-form-tree-rowbar-wrapper position-relative">';
        echo '<div class="gf-form-tree-rowbar">';
        for ($i = 0; $i < 12; $i++) {
            $is_active = ($i >= $start && $i < $start + $unit_width);
            $class = $is_active ? 'gf-fill-active' : 'gf-fill-faded';
            echo '<span class="' . esc_attr($class) . '"></span>';
        }
        echo '</div>';
        echo '</div>';
    }

    private function printFieldHtml($field, $unit_width = 0, $start = 0)
    {
        $name = !empty($field['heading']) ? $field['heading'] : ($field['name'] ?? __('Untitled Field', 'griffinforms-form-builder'));
        $type = $field['field_type'] ?? '';
        $icon_url = $this->fieldTypeIcon($type);

        echo '<li data-gf-itemtype="field" data-gf-itemid="' . esc_attr($field['id']) . '">';
        echo '<div class="gf-form-tree-row gf-form-tree-row--field">';
        echo '<span class="gf-form-tree-field-indent"></span>';
        if ($icon_url) {
            echo '<img src="' . esc_url($icon_url) . '" class="gf-form-tree-field-icon" alt="" aria-hidden="true" />';
        }
        echo '<span role="button" class="gf-form-tree-label gf-form-tree-label-text" data-gf-itemtype="field" data-gf-itemid="' . esc_attr($field['id']) . '">' . esc_html($name) . '</span>';
        echo '</div>';
        echo '</li>';
    }

    private function fieldTypeIcon($type)
    {
        $config = \GriffinForms\Config::getInstance();
        static $checked_icons = [];

        if (!isset($checked_icons[$type])) {
            $filename = 'griffinforms_icon_' . preg_replace('/[^a-z0-9]/', '', strtolower($type)) . '.svg';
            $filepath = $config->getRootPath() . 'admin/images/field-icons/' . $filename;
            $checked_icons[$type] = file_exists($filepath) ? $filename : 'griffinforms_icon_fallback.svg';
        }

        return $config->getRootUrl() . 'admin/images/field-icons/' . $checked_icons[$type];
    }

    private function printChevronIcon()
    {
        $config = \GriffinForms\Config::getInstance();
        $chevron_icon = $config->getRootUrl() . 'admin/images/icons/chevron_down.svg';
        echo '<img width="16" height="16" src="' . esc_url($chevron_icon) . '" class="gf-tree-chevron-icon" alt="" aria-hidden="true" />';
    }

    private function printChevronHtml($has_children)
    {
        $classes = 'gf-tree-chevron';
        $style = '';

        if (!$has_children) {
            $classes .= ' gf-tree-chevron-disabled';
            $style = ' style="visibility:hidden;"';
        }

        echo '<span class="' . esc_attr($classes) . '" role="button" tabindex="' . esc_attr($has_children ? '0' : '-1') . '" aria-expanded="' . esc_attr($has_children ? 'true' : 'false') . '"' . $style . '>';
        $this->printChevronIcon();
        echo '</span>';
    }

    private function __construct()
    {
    }
}
