<?php

namespace Ignite\Core\Models\Grid;

use Carbon\Carbon;
use Ignite\Core\Entities\Audit;
use Ignite\Core\Entities\User;
use Illuminate\Support\HtmlString;

class HistoryFormatter extends Formatter
{
    /**
     * Format the full name of the user that added the note.
     *
     * @param  object $model
     *
     * @return string
     */
    public function user(object $model): string
    {
        if (! $model->user) {
            return 'System';
        }

        if ($model->user instanceof User) {
            return $model->user->fullName();
        }

        return "{$model->first} {$model->last}";
    }

    /**
     * Format the created at timestamp.
     *
     * @param  object  $model
     *
     * @return HtmlString
     */
    public function createdAt(object $model): HtmlString
    {
        return $this->formatDate($model, 'created_at', 'Y-m-d H:i:s');
    }

    /**
     * Format the type of event.
     *
     * @param  object $model
     *
     * @return HtmlString
     */
    public function event(object $model): HtmlString|string
    {
        $events = [
            'deleted' => 'danger',
            'updated' => 'warning',
            'created' => 'success',
            'restored' => 'primary',
        ];

        $event = sprintf(
            '<span class="label label-%s">%s</span>',
            $events[$model->event],
            ucwords(title_case($model->event))
        );

        return $this->html($event);
    }

    /**
     * Format the note message.
     *
     * @param  Audit  $history
     *
     * @return HtmlString|string
     */
    public function message(Audit $history): HtmlString|string
    {
        $entity = $history->getReadableEntityName();
        $identifier = $history->getReadableIdentifier();

        if ($history->event === 'deleted') {
            return $this->html(sprintf('%s %s <strong>%s</strong>', ucwords($history->event), $entity, $identifier));
        }

        if ($history->event !== 'updated') {
            return $this->html(sprintf('%s %s <strong>%s</strong>', ucwords($history->event), $entity, $identifier));
        }

        $history->unsetRelation('user');
        $modifications = $history->getModified();
        if (count($modifications) > 5) {
            return $this->html(view('Core::partials.audit', compact('history')));
        }

        $messages = [];
        foreach ($modifications as $attribute => $values) {
            $messages[] = sprintf(
                '<p>%s %s value %s from <strong>%s</strong> to <strong>%s</strong></p>',
                ucwords($history->event),
                $entity,
                $attribute,
                empty($values['old']) ? '""' : $this->getStringValues($values['old']),
                empty($values['new']) ? '""' : $this->getStringValues($values['new'])
            );
        }

        return $this->html(implode('', $messages));
    }

    /**
     * Get the string values.
     *
     * @param  mixed $values
     *
     * @return string|static
     */
    protected function getStringValues($value)
    {
        if (is_string($value)) {
            return $value;
        }

        return json_encode($value);
    }
}
