<?php

namespace EIS\Component\EIS\Administrator\Helper;

\defined('_JEXEC') or die;

use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\Database\DatabaseDriver;

class TreeHelper
{
    /** Lädt #__eis_documents, gruppiert nach parent_id und sortiert */
    public static function getItems(): array
    {
        /** @var DatabaseDriver $db */
        $db = Factory::getDbo();

        $query = $db->getQuery(true)
            ->select('*')
            ->from($db->quoteName('#__eis_documents'))
            ->order($db->quoteName('ordering') . ' ASC');

        $rows = $db->setQuery($query)->loadAssocList();

        $grouped = [];
        foreach ($rows as $row) {
            $pid = $row['parent_id'] === null ? null : (int) $row['parent_id'];
            $grouped[$pid][] = $row;
        }

        // alphabetisch nach name
        foreach ($grouped as &$group) {
            usort($group, static fn($a, $b) => strcasecmp((string)$a['name'], (string)$b['name']));
        }

        return $grouped;
    }

    /**
     * Kombiniert: Virtueller Ordner "Neue Dokumente" (falls $newIds vorhanden) + normaler Baum
     */
    public static function renderTreeWithNew(array $items, array $newIds = []): string
    {
        $html = '';

        // 1) Virtueller Ordner "Neue Dokumente"
        $newFiles = self::collectFilesByIds($items, $newIds);
        if (!empty($newFiles)) {
            $label = Text::_('COM_EIS_VIRTUAL_NEW') ?: 'Neue Dokumente';

            $html .= '<ul class="pdf-tree">';
            $html .= '<li class="folder" data-id="new" data-title="' . htmlspecialchars($label, ENT_QUOTES, 'UTF-8') . '" data-name="' . htmlspecialchars($label, ENT_QUOTES, 'UTF-8') . '" data-count="' . count($newFiles) . '">';
            $html .= '<span class="toggle" role="button" aria-label="Ordner umschalten" tabindex="0">▼</span> ';
            $html .= '<span class="folder-label">🆕 ' . htmlspecialchars($label, ENT_QUOTES, 'UTF-8') . ' <small class="count">(' . (int) count($newFiles) . ')</small></span>';

            // Kinder sichtbar
            $html .= '<ul style="display:block">';
            foreach ($newFiles as $row) {
                $html .= self::renderSingleFileLi($row);
            }
            $html .= '</ul>';

            $html .= '</li>';
            $html .= '</ul>';
        }

        // 2) Normaler Baum
        $html .= self::renderTree($items, null);

        return $html;
    }

    /** Baum rendern (nutzt title als alternativen Anzeigenamen) */
    public static function renderTree(array $items, ?int $parentId = null): string
    {
        if (!isset($items[$parentId])) {
            return '';
        }

        $html = '<ul class="pdf-tree">';

        foreach ($items[$parentId] as $item) {
            $isFolder = !empty($item['is_folder']);
            $rawName  = (string)($item['title'] ?? '') !== '' ? (string)$item['title'] : (string)$item['name'];
            $display  = preg_replace('/\.pdf$/i', '', $rawName);
            $display  = htmlspecialchars((string)$display, ENT_QUOTES, 'UTF-8');
            $id       = (int)$item['id'];

            if ($isFolder) {
                $fileCount = self::countFilesRecursive($items, $id);

                $html .= '<li class="folder"'
                    .  ' data-id="'    . $id . '"'
                    .  ' data-title="' . htmlspecialchars((string)($item['title'] ?? ''), ENT_QUOTES, 'UTF-8') . '"'
                    .  ' data-name="'  . htmlspecialchars((string)$item['name'], ENT_QUOTES, 'UTF-8') . '"'
                    .  ' data-count="' . (int)$fileCount . '"'
                    .  '>'
                    .  '<span class="toggle" role="button" aria-label="Ordner umschalten" tabindex="0">▶</span> '
                    .  '<span class="folder-label">📁 ' . $display . ' <small class="count">(' . (int)$fileCount . ')</small></span>'
                    .  self::renderTree($items, $id)
                    .  '</li>';
            } else {
                $html .= self::renderSingleFileLi($item, $display);
            }
        }

        $html .= '</ul>';
        return $html;
    }

    /** Einzelnes <li> für Datei (wird auch vom virtuellen Ordner genutzt) */
    private static function renderSingleFileLi(array $item, ?string $displayAlreadyEscaped = null): string
    {
        $rawName   = (string)($item['title'] ?? '') !== '' ? (string)$item['title'] : (string)$item['name'];
        $display   = $displayAlreadyEscaped ?? htmlspecialchars(preg_replace('/\.pdf$/i', '', $rawName), ENT_QUOTES, 'UTF-8');
        $id        = (int)$item['id'];

        // Dateigröße ermitteln (optional)
        $sizeStr   = '';
        $sizeBytes = '';
        if (!empty($item['path']) && is_file((string)$item['path'])) {
            $bytes = @filesize((string)$item['path']); // @ unterdrückt Warnungen bei Zugriffsproblemen
            if ($bytes !== false) {
                $sizeBytes = (string)(int)$bytes;
                $sizeStr   = self::formatFileSize((int)$bytes);
            }
        }

        $html = '<li class="file"'
              . ' data-id="'    . $id . '"'
              . ' data-title="' . htmlspecialchars((string)($item['title'] ?? ''), ENT_QUOTES, 'UTF-8') . '"'
              . ' data-name="'  . htmlspecialchars((string)$item['name'], ENT_QUOTES, 'UTF-8') . '"'
              . ' data-size="'  . htmlspecialchars($sizeStr, ENT_QUOTES, 'UTF-8') . '"'
              . ' data-bytes="' . htmlspecialchars($sizeBytes, ENT_QUOTES, 'UTF-8') . '"'
              . '>'
              . '<span class="file-label">📄 ' . $display
              . ($sizeStr !== '' ? ' <small class="meta">(' . $sizeStr . ')</small>' : '')
              . '</span>'
              . '</li>';

        return $html;
    }

    /** Dateien zu gegebenen IDs einsammeln (nur is_folder = 0) */
    private static function collectFilesByIds(array $items, array $ids): array
    {
        if (empty($ids)) {
            return [];
        }
        $ids = array_map('intval', $ids);

        // Flat-Index aller Rows
        $idx = [];
        foreach ($items as $group) {
            foreach ($group as $row) {
                $idx[(int)$row['id']] = $row;
            }
        }

        $out = [];
        foreach ($ids as $id) {
            if (isset($idx[$id]) && empty($idx[$id]['is_folder'])) {
                $out[] = $idx[$id];
            }
        }
        return $out;
    }

    private static function countFilesRecursive(array $items, int $parentId): int
    {
        $count = 0;
        if (!isset($items[$parentId])) {
            return 0;
        }
        foreach ($items[$parentId] as $item) {
            if (!empty($item['is_folder'])) {
                $count += self::countFilesRecursive($items, (int)$item['id']);
            } else {
                $count++;
            }
        }
        return $count;
    }

    private static function formatFileSize(int $bytes): string
    {
        if ($bytes >= 1073741824) return number_format($bytes / 1073741824, 2) . ' GB';
        if ($bytes >= 1048576)    return number_format($bytes / 1048576, 1) . ' MB';
        if ($bytes >= 1024)       return number_format($bytes / 1024, 0) . ' KB';
        return $bytes . ' B';
    }
}
