<?php
declare(strict_types=1);

namespace App\Modules\Archive\Models;

use App\Core\App;
use App\Core\Pagination;

class ArchiveSnapshot
{
    public static function create(array $data): int
    {
        $db = App::getInstance()->db();
        return $db->insert('archive_snapshots', $data);
    }

    public static function find(int $id): ?array
    {
        $db = App::getInstance()->db();
        return $db->selectOne("SELECT * FROM archive_snapshots WHERE id = ?", [$id]);
    }

    public static function getForEntity(string $entityType, int $entityId): array
    {
        $db = App::getInstance()->db();
        return $db->select(
            "SELECT * FROM archive_snapshots WHERE entity_type = ? AND entity_id = ? ORDER BY snapshot_taken_at DESC",
            [$entityType, $entityId]
        );
    }

    public static function getByMembershipNumber(string $number): array
    {
        $db = App::getInstance()->db();
        return $db->select(
            "SELECT * FROM archive_snapshots WHERE membership_number = ? ORDER BY snapshot_taken_at DESC",
            [$number]
        );
    }

    public static function search(array $filters, int $perPage = 25, int $page = 1): array
    {
        $db = App::getInstance()->db();
        $where = '1=1';
        $params = [];

        if (!empty($filters['entity_type'])) {
            $where .= ' AND a.entity_type = ?';
            $params[] = $filters['entity_type'];
        }

        if (!empty($filters['membership_number'])) {
            $where .= ' AND a.membership_number = ?';
            $params[] = $filters['membership_number'];
        }

        if (!empty($filters['snapshot_reason'])) {
            $where .= ' AND a.snapshot_reason = ?';
            $params[] = $filters['snapshot_reason'];
        }

        if (!empty($filters['date_from'])) {
            $where .= ' AND a.snapshot_taken_at >= ?';
            $params[] = $filters['date_from'] . ' 00:00:00';
        }

        if (!empty($filters['date_to'])) {
            $where .= ' AND a.snapshot_taken_at <= ?';
            $params[] = $filters['date_to'] . ' 23:59:59';
        }

        if (!empty($filters['search'])) {
            $where .= ' AND (a.membership_number LIKE ? OR a.entity_type LIKE ? OR a.notes LIKE ?)';
            $s = '%' . $filters['search'] . '%';
            $params[] = $s;
            $params[] = $s;
            $params[] = $s;
        }

        $countRow = $db->selectOne("SELECT COUNT(*) as cnt FROM archive_snapshots a WHERE {$where}", $params);
        $total = (int) ($countRow['cnt'] ?? 0);

        $offset = ($page - 1) * $perPage;
        $rows = $db->select(
            "SELECT a.* FROM archive_snapshots a WHERE {$where} ORDER BY a.snapshot_taken_at DESC LIMIT {$perPage} OFFSET {$offset}",
            $params
        );

        $pagination = Pagination::paginate($total, $perPage, $page);

        return ['data' => $rows, 'pagination' => $pagination];
    }

    public static function getDistinctEntityTypes(): array
    {
        $db = App::getInstance()->db();
        $rows = $db->select("SELECT DISTINCT entity_type FROM archive_snapshots ORDER BY entity_type");
        return array_column($rows, 'entity_type');
    }

    public static function getDistinctReasons(): array
    {
        $db = App::getInstance()->db();
        $rows = $db->select("SELECT DISTINCT snapshot_reason FROM archive_snapshots ORDER BY snapshot_reason");
        return array_column($rows, 'snapshot_reason');
    }
}