<?php

/**
 * Structured application logger for form submissions.
 *
 * Writes JSON-lines to a log file in storage/logs/.
 * Each entry contains: timestamp, source (admin|partage), action,
 * status (success|error), context (IP, UA, thesis ID, error message, etc.).
 */
class AppLogger
{
    private string $logDir;
    private string $logFile;

    public function __construct(?string $logDir = null)
    {
        $this->logDir = $logDir ?? (defined('STORAGE_ROOT') ? STORAGE_ROOT . '/logs' : __DIR__ . '/../storage/logs');

        if (!is_dir($this->logDir)) {
            mkdir($this->logDir, 0755, true);
        }

        $this->logFile = $this->logDir . '/form-submissions.log';
    }

    /**
     * Log a successful thesis submission.
     *
     * @param string  $source   'admin' or 'partage'
     * @param int     $thesisId
     * @param string  $identifier  e.g. "2025-003"
     * @param string  $authorName
     * @param array   $extras   Additional context (e.g. share link slug)
     */
    public function logSubmission(string $source, int $thesisId, string $identifier, string $authorName, array $extras = []): void
    {
        $this->write(array_merge([
            'source'      => $source,
            'action'      => 'submit',
            'status'      => 'success',
            'thesis_id'   => $thesisId,
            'identifier'  => $identifier,
            'author'      => $authorName,
        ], $extras));
    }

    /**
     * Log a duplicate-submission attempt.
     *
     * @param string $source             'admin' or 'partage'
     * @param string $authorName         Author name from the incoming form
     * @param int    $existingThesisId   ID of the matched existing thesis
     * @param string $existingIdentifier Identifier of the matched thesis (e.g. "2025-003")
     * @param array  $extras             Additional context (e.g. share_slug)
     */
    public function logDuplicate(
        string $source,
        string $authorName,
        int    $existingThesisId,
        string $existingIdentifier,
        array  $extras = []
    ): void {
        $this->write(array_merge([
            'source'              => $source,
            'action'              => 'submit',
            'status'              => 'duplicate',
            'author'              => $authorName,
            'existing_thesis_id'  => $existingThesisId,
            'existing_identifier' => $existingIdentifier,
        ], $extras));
    }

    /**
     * Log a failed thesis submission.
     *
     * @param string    $source
     * @param string    $errorMessage
     * @param array     $extras
     */
    public function logError(string $source, string $errorMessage, array $extras = []): void
    {
        $this->write(array_merge([
            'source' => $source,
            'action' => 'submit',
            'status' => 'error',
            'error'  => $errorMessage,
        ], $extras));
    }

    /**
     * Write a structured log line.
     */
    private function write(array $entry): void
    {
        $entry['timestamp'] = date('c');
        $entry['ip']        = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
        $entry['user_agent'] = $_SERVER['HTTP_USER_AGENT'] ?? '';

        $line = json_encode($entry, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . "\n";
        error_log($line, 3, $this->logFile);
    }
}
