<?php

declare(strict_types=1);

namespace App\Repositories;

use App\Core\Database;
use PDO;

final class ServiceRepository
{
    public function paginate(array $filters, int $perPage = 25): array
    {
        $where = ['1=1']; $params = [];
        if (($filters['search'] ?? '') !== '') {
            $where[] = '(s.name LIKE :search_name OR s.description LIKE :search_description)';
            $search = '%' . trim((string)$filters['search']) . '%';
            $params['search_name'] = $search;
            $params['search_description'] = $search;
        }
        if (($filters['status'] ?? '') !== '') { $where[] = 's.status = :status'; $params['status'] = $filters['status']; }
        $whereSql = 'WHERE ' . implode(' AND ', $where);
        $pdo = Database::connection();
        $count = $pdo->prepare("SELECT COUNT(*) FROM services s $whereSql");
        $count->execute($params);
        $total = (int)$count->fetchColumn();
        $pages = max(1, (int)ceil($total / $perPage));
        $page = min(max(1, (int)($filters['page'] ?? 1)), $pages);
        $offset = ($page - 1) * $perPage;
        $stmt = $pdo->prepare("SELECT s.* FROM services s $whereSql ORDER BY s.status ASC, s.name ASC, s.id DESC LIMIT :limit OFFSET :offset");
        foreach ($params as $k => $v) $stmt->bindValue(':' . $k, $v);
        $stmt->bindValue(':limit', $perPage, PDO::PARAM_INT);
        $stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
        $stmt->execute();
        return ['items'=>$stmt->fetchAll(), 'total'=>$total, 'page'=>$page, 'pages'=>$pages, 'perPage'=>$perPage];
    }

    public function find(int $id): ?array
    {
        $stmt = Database::connection()->prepare('SELECT * FROM services WHERE id=:id LIMIT 1');
        $stmt->execute(['id'=>$id]);
        $row = $stmt->fetch();
        return is_array($row) ? $row : null;
    }

    public function create(array $data): int
    {
        $stmt = Database::connection()->prepare('INSERT INTO services (name,description,price,status) VALUES (:name,:description,:price,:status)');
        $stmt->execute($data);
        return (int)Database::connection()->lastInsertId();
    }

    public function update(int $id, array $data): void
    {
        $data['id'] = $id;
        $stmt = Database::connection()->prepare('UPDATE services SET name=:name,description=:description,price=:price,status=:status,updated_at=NOW() WHERE id=:id');
        $stmt->execute($data);
    }

    public function delete(int $id): void
    {
        $stmt = Database::connection()->prepare('DELETE FROM services WHERE id=:id');
        $stmt->execute(['id'=>$id]);
    }

    public function usageCount(int $id): int
    {
        $stmt = Database::connection()->prepare('SELECT COUNT(*) FROM therapy_sessions WHERE service_id=:id');
        $stmt->execute(['id'=>$id]);
        return (int)$stmt->fetchColumn();
    }

    public function audit(int $userId, string $action, int $entityId, array $metadata=[]): void
    {
        $stmt = Database::connection()->prepare('INSERT INTO audit_logs (user_id,action,entity_type,entity_id,ip_address,metadata,created_at) VALUES (:user_id,:action,:entity_type,:entity_id,:ip,:metadata,NOW())');
        $stmt->execute(['user_id'=>$userId,'action'=>$action,'entity_type'=>'service','entity_id'=>$entityId,'ip'=>$_SERVER['REMOTE_ADDR']??null,'metadata'=>json_encode($metadata, JSON_THROW_ON_ERROR)]);
    }
}
