<?php

/**
 * Simple class to wrap logging functionality
 */

namespace Mtc\Plugins\Clinic\Src;

use App\Models\EventLog;

class Logger
{

    private $loggable;
    private $actor;
    private $memberID;

    const MEMBER = 'member';
    const MEMBER_ATTRIBUTES = 'member_attributes';
    const MEMBER_NOTE = 'member_note';
    const MEMBER_FLAG = 'member_flag';
    const REFUND = 'refund';
    const ORDER = 'order';
    const ORDER_STATUS = 'order_status';
    const ORDER_ITEM_APPROVAL = 'order_item_approval';
    const TREATMENT = 'treatment';
    const PATIENT_ID = 'patient_id';
    const BP_TRACK = 'bp_track';
    const WEIGHT_TRACK = 'weight_track';
    const FILE = 'file';
    const REVIEW = 'review';

    public static array $types = [
        self::MEMBER => 'Patient',
        self::MEMBER_ATTRIBUTES => 'Medical Card',
        self::MEMBER_NOTE => 'Patient Notes',
        self::MEMBER_FLAG => 'Flags',
        self::REFUND => 'Refunds',
        self::ORDER => 'Orders',
        self::ORDER_STATUS => 'Order Status',
        self::ORDER_ITEM_APPROVAL => 'Approvals',
        self::TREATMENT => 'Treatments',
        self::PATIENT_ID => 'Patient ID',
        self::BP_TRACK => 'BP Track',
        self::WEIGHT_TRACK => 'Weight Track',
        self::FILE => 'File',
        self::REVIEW => 'Review',
    ];

    const ACTION_CREATED = 'created';
    const ACTION_UPDATED = 'updated';
    const ACTION_DELETED = 'deleted';
    const ACTION_PAID = 'paid';
    const ACTION_CONFIRMED = 'confirmed';

    /**
     * @param $loggable
     * @param $actor
     * @param $memberID
     */
    public function __construct($loggable, $actor, $memberID = null)
    {
        $this->loggable = $loggable;
        $this->actor = $actor;
        $this->memberID = $memberID;
    }

    /**
     * Logs event
     *
     * @param string $subject
     * @param string|null $value
     * @param array $details
     * @return array
     */
    public function log(string $subject, ?string $value, array $details = []): array
    {

        // Log some information about the actor. Keep it in DB in case the actual actor is deleted from DB
        if (!empty($this->actor->id)) {
            $details['actor_name'] = !empty($this->actor->name) ?
                $this->actor->name :
                $this->actor->firstname . ' ' . $this->actor->lastname;
            $details['actor_email'] = $this->actor->email;
        } else {
            $details['actor_name'] = 'System';
        }

        $loggableID = null;
        if (is_string($this->loggable)) {
            // Can pass class name as loggable
            $loggable = $this->loggable;
        } else {
            $loggable = get_class($this->loggable);
            $loggableID = $this->loggable->id;
        }

        $data = [
            'member_id' => $this->memberID,
            'loggable' => $loggable,
            'loggable_id' => $loggableID,
            'subject' => $subject,
            'value' => $value ?? '',
            'actor' => !empty($this->actor) ? get_class($this->actor) : '',
            'actor_id' => !empty($this->actor->id) ? $this->actor->id : null,
            'details' => json_encode($details),
            'ip_address' => request()->ip(),
        ];

        EventLog::query()
            ->create($data);

        return $data;
    }
}
