<?php
/**
 * Klasa EntityNotes - notatki per encja (urządzenie, użytkownik, playlista)
 * Kompatybilna z różnymi wersjami struktury tabeli
 */

class EntityNotes
{
    private Database $db;
    private ?array $columns = null;
    
    const ENTITY_USER = 'user';
    const ENTITY_DEVICE = 'device';
    const ENTITY_PLAYLIST = 'playlist';
    
    const COLORS = ['default', 'red', 'orange', 'yellow', 'green', 'blue', 'purple', 'pink'];
    
    public function __construct()
    {
        $this->db = Database::getInstance();
        $this->detectColumns();
    }
    
    /**
     * Wykryj dostępne kolumny w tabeli
     */
    private function detectColumns(): void
    {
        if ($this->columns !== null) return;
        
        $this->columns = [];
        try {
            $result = $this->db->fetchAll("PRAGMA table_info(entity_notes)");
            foreach ($result as $col) {
                $this->columns[$col['name']] = true;
            }
        } catch (Exception $e) {
            $this->columns = [];
        }
    }
    
    /**
     * Sprawdź czy kolumna istnieje
     */
    private function hasColumn(string $name): bool
    {
        return isset($this->columns[$name]);
    }
    
    /**
     * Pobierz nazwę kolumny treści (content lub note)
     */
    private function getContentColumn(): string
    {
        return $this->hasColumn('content') ? 'content' : 'note';
    }
    
    /**
     * Dodaj notatkę
     */
    public function add(string $entityType, int $entityId, int $userId, array $data): array
    {
        // Pobierz treść - obsłuż oba nazwy pól
        $content = trim($data['content'] ?? $data['note'] ?? '');
        
        if (empty($content)) {
            return ['success' => false, 'error' => 'Treść notatki jest wymagana.'];
        }
        
        // Buduj dynamicznie zapytanie w zależności od struktury tabeli
        $contentCol = $this->getContentColumn();
        $columns = ['entity_type', 'entity_id', 'user_id', $contentCol, 'created_at'];
        $values = [':entity_type', ':entity_id', ':user_id', ':content', "datetime('now')"];
        $params = [
            'entity_type' => $entityType,
            'entity_id' => $entityId,
            'user_id' => $userId,
            'content' => $content
        ];
        
        // Dodaj opcjonalne kolumny jeśli istnieją
        if ($this->hasColumn('title')) {
            $columns[] = 'title';
            $values[] = ':title';
            $params['title'] = trim($data['title'] ?? '');
        }
        
        if ($this->hasColumn('is_pinned')) {
            $columns[] = 'is_pinned';
            $values[] = ':is_pinned';
            $params['is_pinned'] = !empty($data['is_pinned']) ? 1 : 0;
        }
        
        if ($this->hasColumn('color')) {
            $columns[] = 'color';
            $values[] = ':color';
            $color = in_array($data['color'] ?? 'default', self::COLORS) ? $data['color'] : 'default';
            $params['color'] = $color;
        }
        
        if ($this->hasColumn('updated_at')) {
            $columns[] = 'updated_at';
            $values[] = "datetime('now')";
        }
        
        $sql = "INSERT INTO entity_notes (" . implode(', ', $columns) . ") VALUES (" . implode(', ', $values) . ")";
        
        $id = $this->db->insert($sql, $params);
        
        return ['success' => true, 'id' => $id];
    }
    
    /**
     * Aktualizuj notatkę
     */
    public function update(int $id, int $userId, array $data): array
    {
        $note = $this->getById($id);
        
        if (!$note) {
            return ['success' => false, 'error' => 'Notatka nie istnieje.'];
        }
        
        if ($note['user_id'] != $userId && !$this->isAdmin($userId)) {
            return ['success' => false, 'error' => 'Brak uprawnień do edycji tej notatki.'];
        }
        
        $updates = [];
        $params = ['id' => $id];
        $contentCol = $this->getContentColumn();
        
        // Tytuł (jeśli kolumna istnieje)
        if (isset($data['title']) && $this->hasColumn('title')) {
            $updates[] = "title = :title";
            $params['title'] = trim($data['title']);
        }
        
        // Treść
        if (isset($data['content']) || isset($data['note'])) {
            $content = trim($data['content'] ?? $data['note'] ?? '');
            if (empty($content)) {
                return ['success' => false, 'error' => 'Treść notatki jest wymagana.'];
            }
            $updates[] = "{$contentCol} = :content";
            $params['content'] = $content;
        }
        
        // Przypięcie (jeśli kolumna istnieje)
        if (isset($data['is_pinned']) && $this->hasColumn('is_pinned')) {
            $updates[] = "is_pinned = :is_pinned";
            $params['is_pinned'] = $data['is_pinned'] ? 1 : 0;
        }
        
        // Kolor (jeśli kolumna istnieje)
        if (isset($data['color']) && $this->hasColumn('color') && in_array($data['color'], self::COLORS)) {
            $updates[] = "color = :color";
            $params['color'] = $data['color'];
        }
        
        if (empty($updates)) {
            return ['success' => false, 'error' => 'Brak danych do aktualizacji.'];
        }
        
        if ($this->hasColumn('updated_at')) {
            $updates[] = "updated_at = datetime('now')";
        }
        
        $this->db->execute(
            "UPDATE entity_notes SET " . implode(', ', $updates) . " WHERE id = :id",
            $params
        );
        
        return ['success' => true];
    }
    
    /**
     * Usuń notatkę
     */
    public function delete(int $id, int $userId): array
    {
        $note = $this->getById($id);
        
        if (!$note) {
            return ['success' => false, 'error' => 'Notatka nie istnieje.'];
        }
        
        if ($note['user_id'] != $userId && !$this->isAdmin($userId)) {
            return ['success' => false, 'error' => 'Brak uprawnień do usunięcia tej notatki.'];
        }
        
        $this->db->execute("DELETE FROM entity_notes WHERE id = :id", ['id' => $id]);
        
        return ['success' => true];
    }
    
    /**
     * Pobierz notatkę po ID
     */
    public function getById(int $id): ?array
    {
        $contentCol = $this->getContentColumn();
        $note = $this->db->fetchOne(
            "SELECT n.*, u.username FROM entity_notes n LEFT JOIN users u ON n.user_id = u.id WHERE n.id = :id",
            ['id' => $id]
        );
        
        // Normalizuj nazwę pola treści
        if ($note && isset($note['note']) && !isset($note['content'])) {
            $note['content'] = $note['note'];
        }
        
        return $note;
    }
    
    /**
     * Pobierz notatki dla encji
     */
    public function getByEntity(string $entityType, int $entityId): array
    {
        $orderBy = $this->hasColumn('is_pinned') 
            ? "n.is_pinned DESC, " 
            : "";
        $orderBy .= $this->hasColumn('updated_at') 
            ? "n.updated_at DESC" 
            : "n.created_at DESC";
        
        $notes = $this->db->fetchAll(
            "SELECT n.*, u.username FROM entity_notes n LEFT JOIN users u ON n.user_id = u.id
             WHERE n.entity_type = :entity_type AND n.entity_id = :entity_id
             ORDER BY {$orderBy}",
            ['entity_type' => $entityType, 'entity_id' => $entityId]
        );
        
        // Normalizuj nazwę pola treści
        foreach ($notes as &$note) {
            if (isset($note['note']) && !isset($note['content'])) {
                $note['content'] = $note['note'];
            }
        }
        
        return $notes;
    }
    
    /**
     * Zlicz notatki dla encji
     */
    public function countByEntity(string $entityType, int $entityId): int
    {
        $result = $this->db->fetchOne(
            "SELECT COUNT(*) as count FROM entity_notes WHERE entity_type = :entity_type AND entity_id = :entity_id",
            ['entity_type' => $entityType, 'entity_id' => $entityId]
        );
        return $result['count'] ?? 0;
    }
    
    /**
     * Przełącz przypięcie
     */
    public function togglePin(int $id, int $userId): array
    {
        if (!$this->hasColumn('is_pinned')) {
            return ['success' => false, 'error' => 'Funkcja przypinania notatek niedostępna.'];
        }
        
        $note = $this->getById($id);
        if (!$note) return ['success' => false, 'error' => 'Notatka nie istnieje.'];
        if ($note['user_id'] != $userId && !$this->isAdmin($userId)) return ['success' => false, 'error' => 'Brak uprawnień.'];
        
        $newPinned = ($note['is_pinned'] ?? 0) ? 0 : 1;
        
        $sql = "UPDATE entity_notes SET is_pinned = :p";
        if ($this->hasColumn('updated_at')) {
            $sql .= ", updated_at = datetime('now')";
        }
        $sql .= " WHERE id = :id";
        
        $this->db->execute($sql, ['p' => $newPinned, 'id' => $id]);
        return ['success' => true, 'is_pinned' => $newPinned];
    }
    
    private function isAdmin(int $userId): bool
    {
        $user = $this->db->fetchOne("SELECT role FROM users WHERE id = :id", ['id' => $userId]);
        return $user && $user['role'] === 'admin';
    }
    
    public function deleteByEntity(string $entityType, int $entityId): void
    {
        $this->db->execute("DELETE FROM entity_notes WHERE entity_type = :t AND entity_id = :id", ['t' => $entityType, 'id' => $entityId]);
    }
    
    /**
     * Pobierz informacje o strukturze tabeli (do debugowania)
     */
    public function getTableInfo(): array
    {
        return [
            'columns' => array_keys($this->columns),
            'content_column' => $this->getContentColumn(),
            'has_title' => $this->hasColumn('title'),
            'has_color' => $this->hasColumn('color'),
            'has_is_pinned' => $this->hasColumn('is_pinned'),
        ];
    }
}
