<?php

declare(strict_types=1);

class Report
{
    public static function create(array $data): int
    {
        return Database::insert('reports', $data);
    }

    public static function find(int $id): ?array
    {
        return Database::fetchOne(
            'SELECT r.*, v.title AS video_title, v.slug AS video_slug,
                    a.title AS album_title, a.slug AS album_slug, u.username
             FROM reports r
             LEFT JOIN videos v ON v.id = r.video_id
             LEFT JOIN albums a ON a.id = r.album_id
             LEFT JOIN users u ON u.id = r.user_id
             WHERE r.id = ?',
            [$id]
        );
    }

    public static function all(array $filters = [], int $limit = 20, int $offset = 0): array
    {
        $where = [];
        $params = [];

        if (!empty($filters['status'])) {
            $where[] = 'r.status = ?';
            $params[] = $filters['status'];
        }

        if (!empty($filters['reason'])) {
            $where[] = 'r.reason = ?';
            $params[] = $filters['reason'];
        }

        $whereClause = $where ? 'WHERE ' . implode(' AND ', $where) : '';

        $params[] = $limit;
        $params[] = $offset;

        return Database::fetchAll(
            "SELECT r.*, v.title AS video_title, v.slug AS video_slug,
                    a.title AS album_title, a.slug AS album_slug, u.username
             FROM reports r
             LEFT JOIN videos v ON v.id = r.video_id
             LEFT JOIN albums a ON a.id = r.album_id
             LEFT JOIN users u ON u.id = r.user_id
             {$whereClause}
             ORDER BY FIELD(r.status, 'pending', 'reviewed', 'resolved', 'dismissed'), r.created_at DESC
             LIMIT ? OFFSET ?",
            $params
        );
    }

    public static function count(array $filters = []): int
    {
        $where = [];
        $params = [];

        if (!empty($filters['status'])) {
            $where[] = 'status = ?';
            $params[] = $filters['status'];
        }

        if (!empty($filters['reason'])) {
            $where[] = 'reason = ?';
            $params[] = $filters['reason'];
        }

        $whereClause = $where ? implode(' AND ', $where) : '1=1';

        return (int) Database::fetchOne(
            "SELECT COUNT(*) AS cnt FROM reports WHERE {$whereClause}",
            $params
        )['cnt'];
    }

    public static function countPending(): int
    {
        return (int) Database::fetchOne(
            "SELECT COUNT(*) AS cnt FROM reports WHERE status = 'pending'"
        )['cnt'];
    }

    public static function updateStatus(int $id, string $status, ?string $adminNote = null): void
    {
        $data = ['status' => $status, 'updated_at' => date('Y-m-d H:i:s')];
        if ($adminNote !== null) {
            $data['admin_note'] = $adminNote;
        }
        Database::update('reports', $data, 'id = ?', [$id]);
    }

    public static function delete(int $id): void
    {
        Database::delete('reports', 'id = ?', [$id]);
    }

    public static function countForVideo(int $videoId): int
    {
        return (int) Database::fetchOne(
            'SELECT COUNT(*) AS cnt FROM reports WHERE video_id = ?',
            [$videoId]
        )['cnt'];
    }

    public static function hasRecentReport(int $videoId, string $ip): bool
    {
        $existing = Database::fetchOne(
            'SELECT id FROM reports WHERE video_id = ? AND ip_address = ? AND created_at > DATE_SUB(NOW(), INTERVAL 24 HOUR)',
            [$videoId, $ip]
        );
        return $existing !== null;
    }

    public static function countForAlbum(int $albumId): int
    {
        return (int) Database::fetchOne(
            'SELECT COUNT(*) AS cnt FROM reports WHERE album_id = ?',
            [$albumId]
        )['cnt'];
    }

    public static function hasRecentReportAlbum(int $albumId, string $ip): bool
    {
        $existing = Database::fetchOne(
            'SELECT id FROM reports WHERE album_id = ? AND ip_address = ? AND created_at > DATE_SUB(NOW(), INTERVAL 24 HOUR)',
            [$albumId, $ip]
        );
        return $existing !== null;
    }

    public const REASONS = ['illegal', 'copyright', 'spam', 'broken', 'underage', 'other'];

    public const REASON_LABELS = [
        'illegal'   => 'Illegal content',
        'copyright' => 'Copyright violation',
        'spam'      => 'Spam / Misleading',
        'broken'    => 'Broken / Not working',
        'underage'  => 'Underage content',
        'other'     => 'Other',
    ];

    public const STATUS_LABELS = [
        'pending'   => 'Pending',
        'reviewed'  => 'Under Review',
        'resolved'  => 'Resolved',
        'dismissed' => 'Dismissed',
    ];

     
    public static function subject(array $r): array
    {
        if (!empty($r['album_id'])) {
            $slug = (string) ($r['album_slug'] ?? '');
            return [
                'type'     => 'album',
                'id'       => (int) $r['album_id'],
                'title'    => $r['album_title'] ?? 'Deleted gallery',
                'slug'     => $slug,
                'label'    => 'Gallery',
                'view_url' => $slug !== '' ? '/album/' . $slug : '',
                'edit_url' => '/admin/albums/' . (int) $r['album_id'] . '/edit',
            ];
        }
        $slug = (string) ($r['video_slug'] ?? '');
        return [
            'type'     => 'video',
            'id'       => (int) ($r['video_id'] ?? 0),
            'title'    => $r['video_title'] ?? 'Deleted video',
            'slug'     => $slug,
            'label'    => 'Video',
            'view_url' => $slug !== '' ? '/video/' . $slug : '',
            'edit_url' => '/admin/videos/' . (int) ($r['video_id'] ?? 0) . '/edit',
        ];
    }

     
    public static function countForSubject(array $r): int
    {
        return !empty($r['album_id'])
            ? self::countForAlbum((int) $r['album_id'])
            : self::countForVideo((int) ($r['video_id'] ?? 0));
    }
}
