<?php

namespace Mtc\Modules\Members\Models;

use App\Casts\OptionalEncrypted;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Mtc\Core\AdminUser;
use Mtc\Shop\Order;

/**
 * Accessors
 *
 * @property int $wisebee_id
 * @property int $member_id
 * @property int $admin_user_id
 * @property int $order_id
 * @property string $content
 * @property string $status
 * @property bool $is_flag
 * @property string $flag_due
 * @property Carbon $created_at
 * @property Carbon $updated_at
 *
 * @property Member $member
 * @property Order|null $order
 * @property AdminUser $admin_user
 */
class MemberNote extends Model
{
    protected $table = 'member_notes';

    protected $fillable = [
        'content',
        'admin_user_id',
        'order_id',
        'member_id',
        'status',
        'is_flag',
        'flag_due',
    ];

    protected $casts = [
        'is_flag' => 'bool',
        'content' => OptionalEncrypted::class,
    ];

    const STATUS_TODO = 'todo';
    const STATUS_COMPLETE = 'complete';

    const TYPE_FLAG = 'flag';
    const TYPE_TASK = 'task';

    public function admin_user(): BelongsTo
    {
        return $this->belongsTo(AdminUser::class, 'admin_user_id');
    }

    public function order(): BelongsTo
    {
        return $this->belongsTo(Order::class, 'order_id');
    }

    public function member(): BelongsTo
    {
        return $this->belongsTo(Member::class, 'member_id');
    }

    /**
     * More details on each note
     *
     * @return string
     */
    public function getNoteDetails(): string
    {
        $details = '<em>';
        if (! empty($this->admin_user)) {
            $details .= 'Created by: '.$this->admin_user->name.'<br />';
        }
        $details .= 'Date & Time: '.$this->created_at->format('d.m.Y H:i:s').'<br /><br /></em>';
        $details .= 'Note: '.strip_tags($this->content, ['<br>', '<hr>']).'<hr />';

        return $details;
    }

    /**
     * Gets Order notes HTML
     *
     * @param $orderID
     * @return string
     */
    public static function getOrderNotesHTML($orderID): string
    {
        $notesHTML = '';
        $notes = self::query()
            ->where('order_id', $orderID)
            ->orderByDesc('created_at')
            ->get();
        /** @var self $note */
        foreach ($notes as $note) {
            $notesHTML .= $note->getNoteDetails();
        }

        return $notesHTML;
    }

    /**
     * Validates member note input
     *
     * @param $note
     * @return array|string[]
     */
    public static function validate($note): array
    {
        if (empty($note)) {
            return [
                'general' => 'Please enter the note!',
            ];
        }

        return [];
    }

    /**
     * Gets flag alerts for dashboard
     *
     * @return Collection
     */
    public static function getFlagAlerts(): Collection
    {
        return self::query()
            ->with('member.addressBilling')
            ->where('is_flag', true)
            ->where(function (Builder $query): void {
                $query
                    ->where('status', self::STATUS_TODO)
                    ->orWhere(function (Builder $query): void {
                        $query
                            ->whereNotNull('flag_due')
                            ->where('flag_due', '<', Carbon::now()->format('Y-m-d'))
                            ->where(function (Builder $query): void {
                                $query->where('status', '!=', self::STATUS_COMPLETE)->orWhereNull('status');
                            });
                    });
            })
            ->get();
    }
}
