<?php
namespace App\Models;

use App\Core\DB;

class FolderModel
{
    /** Get subfolders in a parent (non-trashed) */
    public static function allInParent(?int $parentId = null): array
    {
        if ($parentId === null) {
            $stmt = DB::get()->prepare("SELECT * FROM folders WHERE parent_id IS NULL AND trashed_at IS NULL ORDER BY name ASC");
            $stmt->execute();
        } else {
            $stmt = DB::get()->prepare("SELECT * FROM folders WHERE parent_id = ? AND trashed_at IS NULL ORDER BY name ASC");
            $stmt->execute([$parentId]);
        }
        return $stmt->fetchAll();
    }

    /** Get all trashed folders */
    public static function allTrashed(): array
    {
        return DB::get()->query("SELECT * FROM folders WHERE trashed_at IS NOT NULL ORDER BY trashed_at DESC")->fetchAll();
    }

    public static function findById(int $id): ?array
    {
        $stmt = DB::get()->prepare("SELECT * FROM folders WHERE id = ? LIMIT 1");
        $stmt->execute([$id]);
        $row = $stmt->fetch();
        return $row ?: null;
    }

    public static function findByToken(string $token): ?array
    {
        $stmt = DB::get()->prepare("SELECT * FROM folders WHERE shared_token = ? AND shared_enabled = 1 AND trashed_at IS NULL LIMIT 1");
        $stmt->execute([$token]);
        $row = $stmt->fetch();
        return $row ?: null;
    }

    public static function create(string $name, ?int $parentId = null): int
    {
        $stmt = DB::get()->prepare("INSERT INTO folders (name, parent_id) VALUES (?, ?)");
        $stmt->execute([$name, $parentId]);
        return (int)DB::get()->lastInsertId();
    }

    public static function rename(int $id, string $name): void
    {
        $stmt = DB::get()->prepare("UPDATE folders SET name = ?, updated_at = datetime('now') WHERE id = ?");
        $stmt->execute([$name, $id]);
    }

    public static function moveToTrash(int $id): void
    {
        $stmt = DB::get()->prepare("UPDATE folders SET trashed_at = datetime('now'), shared_enabled = 0, updated_at = datetime('now') WHERE id = ?");
        $stmt->execute([$id]);
        // Also trash all files inside
        $stmt2 = DB::get()->prepare("UPDATE files SET trashed_at = datetime('now'), shared_enabled = 0 WHERE folder_id = ? AND trashed_at IS NULL");
        $stmt2->execute([$id]);
        // Trash subfolders recursively
        $subs = DB::get()->prepare("SELECT id FROM folders WHERE parent_id = ? AND trashed_at IS NULL");
        $subs->execute([$id]);
        foreach ($subs->fetchAll() as $sub) {
            self::moveToTrash($sub['id']);
        }
    }

    public static function restoreFromTrash(int $id): void
    {
        $stmt = DB::get()->prepare("UPDATE folders SET trashed_at = NULL, updated_at = datetime('now') WHERE id = ?");
        $stmt->execute([$id]);
        // Restore files in this folder
        $stmt2 = DB::get()->prepare("UPDATE files SET trashed_at = NULL WHERE folder_id = ?");
        $stmt2->execute([$id]);
    }

    public static function delete(int $id): void
    {
        $stmt = DB::get()->prepare("DELETE FROM folders WHERE id = ?");
        $stmt->execute([$id]);
    }

    public static function moveToParent(int $id, ?int $parentId): void
    {
        $stmt = DB::get()->prepare("UPDATE folders SET parent_id = ?, updated_at = datetime('now') WHERE id = ?");
        $stmt->execute([$parentId, $id]);
    }

    public static function updateShare(int $id, bool $enabled, ?string $token): void
    {
        $stmt = DB::get()->prepare("UPDATE folders SET shared_enabled = ?, shared_token = ?, updated_at = datetime('now') WHERE id = ?");
        $stmt->execute([(int)$enabled, $token, $id]);
    }

    /** Get breadcrumb path from root to given folder */
    public static function breadcrumb(int $id): array
    {
        $path = [];
        $current = self::findById($id);
        while ($current) {
            array_unshift($path, $current);
            $current = $current['parent_id'] ? self::findById($current['parent_id']) : null;
        }
        return $path;
    }

    public static function trashedCount(): int
    {
        $row = DB::get()->query("SELECT COUNT(*) as c FROM folders WHERE trashed_at IS NOT NULL")->fetch();
        return (int)$row['c'];
    }

    /** Get all files recursively inside a folder (for shared folder download listing) */
    public static function allFilesRecursive(int $folderId): array
    {
        $files = [];
        $stmt = DB::get()->prepare("SELECT * FROM files WHERE folder_id = ? AND trashed_at IS NULL");
        $stmt->execute([$folderId]);
        $files = array_merge($files, $stmt->fetchAll());
        $subs = DB::get()->prepare("SELECT id FROM folders WHERE parent_id = ? AND trashed_at IS NULL");
        $subs->execute([$folderId]);
        foreach ($subs->fetchAll() as $sub) {
            $files = array_merge($files, self::allFilesRecursive($sub['id']));
        }
        return $files;
    }
}
