<?php

declare(strict_types=1);

class AdminAlbumCategoryController
{
    public static function routes(): void
    {
        Router::get('/admin/albums/categories', [self::class, 'index']);
        Router::get('/admin/albums/categories/create', [self::class, 'create']);
        Router::post('/admin/albums/categories/store', [self::class, 'store']);
        Router::get('/admin/albums/categories/{id}/edit', [self::class, 'edit']);
        Router::post('/admin/albums/categories/{id}/update', [self::class, 'update']);
        Router::post('/admin/albums/categories/{id}/delete', [self::class, 'destroy']);
        Router::post('/admin/albums/categories/bulk-delete', [self::class, 'bulkDelete']);
        Router::post('/admin/albums/categories/{id}/update-thumbnail', [self::class, 'updateThumbnail']);
        Router::post('/admin/albums/categories/{id}/translations', [self::class, 'saveTranslations']);
        Router::post('/admin/albums/categories/ajax-create', [self::class, 'ajaxCreate']);
    }

    public static function index(): void
    {
        Auth::requireAdmin();
        $videoFilter = $_GET['videos'] ?? '';
        $sort = $_GET['sort'] ?? 'name';

         
        $typeRows = Database::fetchAll('SELECT video_type, COUNT(*) as cnt FROM album_categories GROUP BY video_type ORDER BY ' . Video::typeFieldOrder());
        $availableTypes = array_column($typeRows, 'video_type');
        $typeCounts = array_column($typeRows, 'cnt', 'video_type');
        $showTypeFilter = count($availableTypes) > 1;
        $typeFilter = '';
        if ($showTypeFilter) {
            $typeFilter = $_GET['type'] ?? '';
            if ($typeFilter !== '' && !in_array($typeFilter, Video::VALID_TYPES, true)) {
                $typeFilter = '';
            }
        }

        $where = [];
        $params = [];
        if ($typeFilter !== '') {
            $where[] = 'c.video_type = ?';
            $params[] = $typeFilter;
        }
        $whereClause = !empty($where) ? 'WHERE ' . implode(' AND ', $where) : '';

        $having = '';
        if ($videoFilter === 'with') $having = 'HAVING album_count > 0';
        elseif ($videoFilter === 'empty') $having = 'HAVING album_count = 0';

        $orderBy = match ($sort) {
            'videos' => 'album_count DESC, c.name ASC',
            'newest' => 'c.id DESC',
            default => 'c.sort_order ASC, c.name ASC',
        };

        $countRow = Database::fetchOne(
            "SELECT COUNT(*) as cnt FROM (
                SELECT c.id, COUNT(ac.album_id) as album_count
                FROM album_categories c LEFT JOIN album_category_map ac ON c.id = ac.category_id
                {$whereClause}
                GROUP BY c.id {$having}
            ) sub",
            $params
        );
        $total = (int) ($countRow['cnt'] ?? 0);
        $pagination = Pagination::fromRequest($total, 100);

        $categories = Database::fetchAll(
            "SELECT c.*, COUNT(ac.album_id) as album_count
            FROM album_categories c
            LEFT JOIN album_category_map ac ON c.id = ac.category_id
            {$whereClause}
            GROUP BY c.id {$having}
            ORDER BY {$orderBy}
            LIMIT ? OFFSET ?",
            array_merge($params, [$pagination->perPage, $pagination->offset])
        );

         
        $catTranslations = [];
        $catIds = array_column($categories, 'id');
        if (!empty($catIds)) {
            $ph = implode(',', array_fill(0, count($catIds), '?'));
            $tRows = Database::fetchAll(
                "SELECT category_id, lang_code, name FROM album_category_translations WHERE category_id IN ({$ph}) ORDER BY category_id, lang_code",
                $catIds
            );
            foreach ($tRows as $tr) {
                $catTranslations[(int) $tr['category_id']][$tr['lang_code']] = $tr['name'];
            }
        }

         
         
        AlbumAsset::assignEntityCovers($categories, 'album_category_map', 'category_id', 'thumbnail');

        Router::render('admin/album_categories', [
            'pageTitle' => 'Album Categories', 'activeMenu' => 'album_categories', 'contentTemplate' => '_album_categories',
            'headerAction' => ['url' => '/admin/albums/categories/create' . ($typeFilter !== '' ? '?type=' . $typeFilter : ''), 'label' => 'New Album Category'],
            'categories' => $categories,
            'pagination' => $pagination,
            'currentVideoFilter' => $videoFilter,
            'currentSort' => $sort,
            'showTypeFilter' => $showTypeFilter,
            'availableTypes' => $availableTypes,
            'typeCounts' => $typeCounts,
            'currentType' => $typeFilter,
            'catTranslations' => $catTranslations,
        ]);
    }

    public static function create(): void
    {
        Auth::requireAdmin();
        Router::render('admin/album_category_form', [
            'pageTitle' => 'New Album Category', 'activeMenu' => 'album_categories', 'contentTemplate' => '_album_category_form',
            'category' => null, 'error' => null,
        ]);
    }

    public static function store(): void
    {
        Auth::requireAdmin();
        if (!Router::verifyCsrf()) { Router::redirect('/admin/albums/categories'); }

        $videoType = in_array($_POST['video_type'] ?? '', Video::VALID_TYPES, true) ? $_POST['video_type'] : Video::DEFAULT_TYPE;
        $data = [
            'name' => trim($_POST['name'] ?? ''),
            'slug' => Slug::unique('album_categories', $_POST['name'] ?? '', null, ['video_type' => $videoType]),
            'description' => trim($_POST['description'] ?? ''),
            'sort_order' => (int) ($_POST['sort_order'] ?? 0),
            'video_type' => $videoType,
        ];

        if (!empty($_FILES['thumbnail']['name'])) {
            $upload = FileUpload::image($_FILES['thumbnail'], 'thumbnails');
            if ($upload['success']) { $data['thumbnail'] = $upload['path']; }
        }

        AlbumCategory::create($data);
        $_SESSION['flash'] = ['type' => 'success', 'message' => 'Album category created successfully.'];
        SitemapController::markDirty();
        Router::redirect('/admin/albums/categories');
    }

    public static function edit(): void
    {
        Auth::requireAdmin();
        $cat = AlbumCategory::find((int) Router::param('id'));
        if (!$cat) { Router::redirect('/admin/albums/categories'); }

        $translations = AlbumCategory::translations((int) $cat['id']);
        $languages = Translator::available();
        $defaultLang = Translator::getDefaultCode();

        Router::render('admin/album_category_form', [
            'pageTitle' => 'Edit Album Category', 'activeMenu' => 'album_categories', 'contentTemplate' => '_album_category_form',
            'category' => $cat, 'error' => null,
            'entityTranslations' => $translations,
            'entityLanguages' => $languages,
            'defaultLang' => $defaultLang,
        ]);
    }

    public static function update(): void
    {
        Auth::requireAdmin();
        if (!Router::verifyCsrf()) { Router::redirect('/admin/albums/categories'); }

        $id = (int) Router::param('id');
        $videoType = in_array($_POST['video_type'] ?? '', Video::VALID_TYPES, true) ? $_POST['video_type'] : Video::DEFAULT_TYPE;
        $data = [
            'name' => trim($_POST['name'] ?? ''),
            'slug' => Slug::unique('album_categories', $_POST['name'] ?? '', $id, ['video_type' => $videoType]),
            'description' => trim($_POST['description'] ?? ''),
            'sort_order' => (int) ($_POST['sort_order'] ?? 0),
            'video_type' => $videoType,
        ];

        if (!empty($_FILES['thumbnail']['name'])) {
            $upload = FileUpload::image($_FILES['thumbnail'], 'thumbnails');
            if ($upload['success']) { $data['thumbnail'] = $upload['path']; }
        }

        AlbumCategory::update($id, $data);
        $_SESSION['flash'] = ['type' => 'success', 'message' => 'Album category updated successfully.'];
        SitemapController::markDirty();
        Router::redirect('/admin/albums/categories');
    }

    public static function destroy(): void
    {
        Auth::requireAdmin();
        if (!Router::verifyCsrf()) { Router::redirect('/admin/albums/categories'); }
        AlbumCategory::delete((int) Router::param('id'));
        $_SESSION['flash'] = ['type' => 'success', 'message' => 'Album category deleted successfully.'];
        SitemapController::markDirty();
        Router::redirect('/admin/albums/categories');
    }

    public static function updateThumbnail(): void
    {
        Auth::requireAdmin();
        if (!Router::verifyCsrf()) { http_response_code(403); echo json_encode(['error' => 'CSRF token expired.']); return; }
        header('Content-Type: application/json');
        $id = (int) Router::param('id');
        $cat = AlbumCategory::find($id);
        if (!$cat) { http_response_code(404); echo json_encode(['error' => 'Album category not found']); return; }

        if (empty($_FILES['thumbnail']['name'])) {
            http_response_code(400); echo json_encode(['error' => 'No file uploaded']); return;
        }

        $upload = FileUpload::image($_FILES['thumbnail'], 'thumbnails');
        if (!$upload['success']) {
            http_response_code(400); echo json_encode(['error' => $upload['error'] ?? 'Upload failed']); return;
        }

        AlbumCategory::update($id, ['thumbnail' => $upload['path']]);
        echo json_encode(['success' => true, 'thumbnail' => $upload['path']]);
    }

    public static function bulkDelete(): void
    {
        Auth::requireAdmin();
        if (!Router::verifyCsrf()) { http_response_code(403); echo json_encode(['error' => 'CSRF']); return; }
        $input = json_decode(file_get_contents('php://input'), true);
        $ids = array_filter(array_map('intval', $input['ids'] ?? []), fn($id) => $id > 0);
        foreach ($ids as $id) { AlbumCategory::delete($id); }
        $_SESSION['flash'] = ['type' => 'success', 'message' => count($ids) . ' album category(ies) deleted.'];
        echo json_encode(['deleted' => count($ids)]);
    }

    public static function saveTranslations(): void
    {
        Auth::requireAdmin();
        if (!Router::verifyCsrf()) { Router::json(['error' => 'Invalid CSRF token'], 403); }
        $id = (int) Router::param('id');
        $entity = AlbumCategory::find($id);
        if (!$entity) { Router::json(['error' => 'Not found'], 404); }
        $videoType = $entity['video_type'] ?? '';

        $input = json_decode(file_get_contents('php://input'), true) ?: [];
        $translations = $input['translations'] ?? [];

        foreach ($translations as $langCode => $fields) {
            $langCode = preg_replace('/[^a-z]/', '', strtolower($langCode));
            if ($langCode === '' || strlen($langCode) > 5) continue;

            $name = mb_substr(trim($fields['name'] ?? ''), 0, 200);
            $description = trim($fields['description'] ?? '');

            if ($name === '') {
                Database::query('DELETE FROM album_category_translations WHERE category_id = ? AND lang_code = ?', [$id, $langCode]);
            } else {
                $slug = Slug::uniqueEntityTranslation('album_category_translations', 'category_id', 'album_categories', $name, $langCode, $id, $videoType);
                $existing = Database::fetchOne('SELECT id FROM album_category_translations WHERE category_id = ? AND lang_code = ?', [$id, $langCode]);
                if ($existing) {
                    Database::query(
                        'UPDATE album_category_translations SET name = ?, slug = ?, description = ? WHERE category_id = ? AND lang_code = ?',
                        [$name, $slug, $description, $id, $langCode]
                    );
                } else {
                    Database::query(
                        'INSERT INTO album_category_translations (category_id, lang_code, name, slug, description) VALUES (?, ?, ?, ?, ?)',
                        [$id, $langCode, $name, $slug, $description]
                    );
                }
            }
        }

        SitemapController::markDirty();
        Router::json(['success' => true]);
    }

    

    public static function ajaxCreate(): void
    {
        Auth::requireAdmin();
        if (!Router::verifyCsrf()) { Router::json(['error' => 'Invalid CSRF token'], 403); }

        $input = json_decode(file_get_contents('php://input'), true) ?: [];
        $name = trim((string) ($input['name'] ?? $_POST['name'] ?? ''));
        if ($name === '') { Router::json(['error' => 'Name is required'], 400); }

        $rawType = (string) ($input['video_type'] ?? $_POST['video_type'] ?? '');
        $videoType = in_array($rawType, Video::VALID_TYPES, true) ? $rawType : Video::DEFAULT_TYPE;

        $existing = Database::fetchOne('SELECT * FROM album_categories WHERE name = ? AND video_type = ? LIMIT 1', [$name, $videoType]);
        if ($existing) {
            Router::json(['success' => true, 'id' => (int) $existing['id'], 'name' => $existing['name'], 'slug' => $existing['slug'], 'video_type' => $existing['video_type'], 'created' => false]);
        }

        $id = AlbumCategory::create([
            'name' => $name,
            'slug' => Slug::unique('album_categories', $name, null, ['video_type' => $videoType]),
            'video_type' => $videoType,
        ]);
        $row = AlbumCategory::find($id);
        SitemapController::markDirty();
        Router::json(['success' => true, 'id' => (int) $id, 'name' => $row['name'], 'slug' => $row['slug'], 'video_type' => $row['video_type'], 'created' => true]);
    }
}
