<?php

declare(strict_types=1);

namespace App\Services;

use App\Core\Auth;
use App\Core\Database;
use App\Core\Request;

/**
 * ActivityLogger
 *
 * Writes to two different tables depending on intent:
 *   - activity_logs: the SYSTEM-WIDE audit trail (Activity Logs page —
 *     User Action / System / Security / Admin categories).
 *   - activities: a per-ENTITY timeline (the "Activity Timeline" shown
 *     on Lead Details / Customer Details).
 *
 * A single meaningful event (e.g. "lead moved to Quoted") is usually
 * logged to BOTH — logAction() does that in one call so future modules
 * don't have to remember to call both tables themselves.
 */
final class ActivityLogger
{
    public static function logAction(
        string $action,
        string $category = 'user_action',
        ?string $entityType = null,
        ?int $entityId = null,
        ?Request $request = null
    ): void {
        $stmt = Database::connection()->prepare(
            'INSERT INTO activity_logs (user_id, category, action, entity_type, entity_id, ip_address, user_agent, created_at)
             VALUES (:user_id, :category, :action, :entity_type, :entity_id, :ip, :ua, NOW())'
        );

        $stmt->execute([
            'user_id' => Auth::id(),
            'category' => $category,
            'action' => $action,
            'entity_type' => $entityType,
            'entity_id' => $entityId,
            'ip' => $request?->ip(),
            'ua' => $request?->userAgent(),
        ]);
    }

    /** Adds one row to a specific record's visible timeline (Lead Details, Customer Details, ...). */
    public static function logEntityActivity(
        string $entityType,
        int $entityId,
        string $type,
        string $description,
        array $metadata = []
    ): void {
        $stmt = Database::connection()->prepare(
            'INSERT INTO activities (entity_type, entity_id, type, description, metadata, caused_by, created_at)
             VALUES (:entity_type, :entity_id, :type, :description, :metadata, :caused_by, NOW())'
        );

        $stmt->execute([
            'entity_type' => $entityType,
            'entity_id' => $entityId,
            'type' => $type,
            'description' => $description,
            'metadata' => $metadata === [] ? null : json_encode($metadata),
            'caused_by' => Auth::id(),
        ]);
    }

    /** Convenience: log to both the entity timeline AND the system-wide audit trail in one call. */
    public static function record(
        string $entityType,
        int $entityId,
        string $type,
        string $description,
        array $metadata = [],
        string $category = 'user_action'
    ): void {
        self::logEntityActivity($entityType, $entityId, $type, $description, $metadata);
        self::logAction($description, $category, $entityType, $entityId);
    }

    /** @return array The most recent activity rows for one entity, newest first. */
    public static function timelineFor(string $entityType, int $entityId, int $limit = 50): array
    {
        $stmt = Database::connection()->prepare(
            'SELECT a.*, CONCAT(u.first_name, " ", u.last_name) AS caused_by_name
             FROM activities a
             LEFT JOIN users u ON u.id = a.caused_by
             WHERE a.entity_type = :type AND a.entity_id = :id
             ORDER BY a.created_at DESC
             LIMIT :limit'
        );
        $stmt->bindValue('type', $entityType);
        $stmt->bindValue('id', $entityId, \PDO::PARAM_INT);
        $stmt->bindValue('limit', $limit, \PDO::PARAM_INT);
        $stmt->execute();

        return $stmt->fetchAll();
    }
}
