<?php

declare(strict_types=1);

namespace App\Models;

use App\Contracts\OwnedByUser;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

/**
 * General account profile. Contact and presentation details only -- nothing
 * here participates in a marketplace transaction.
 */
class Profile extends Model implements OwnedByUser
{
    use HasFactory;

    /** @var list<string> */
    protected $fillable = [
        'display_name',
        'avatar_path',
        'bio',
        'country_code',
        'city',
        'address_line1',
        'address_line2',
        'postal_code',
        'website_url',
        'company_name',
        'tax_id',
        'notification_preferences',
        'whatsapp_number',
        'marketing_opt_in',
    ];

    /** Tax identifiers are never returned to anyone but the owner and admins. */
    protected $hidden = ['tax_id'];

    /** @return array<string, string> */
    protected function casts(): array
    {
        return [
            'notification_preferences' => 'array',
            'marketing_opt_in' => 'boolean',
        ];
    }

    /** @return BelongsTo<User, $this> */
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

    /** Read from the foreign key, so authorization costs no query. */
    public function ownerId(): ?int
    {
        return $this->user_id === null ? null : (int) $this->user_id;
    }

    /**
     * Default channel preferences. Transactional marketplace events (an offer
     * accepted, a transfer started) are not opt-out: a user who has money in
     * flight must be reachable, so only digests and marketing are switchable.
     *
     * @return array<string, bool>
     */
    public static function defaultNotificationPreferences(): array
    {
        return [
            'email_offers' => true,
            'email_orders' => true,
            'email_transfers' => true,
            'email_watchlist' => true,
            'email_weekly_digest' => true,
            'inapp_offers' => true,
            'inapp_orders' => true,
            'inapp_watchlist' => true,
            'push_offers' => true,
            'push_orders' => true,
            'whatsapp_orders' => false,
        ];
    }

    /** @return array<string, bool> */
    public function preferences(): array
    {
        return array_merge(
            self::defaultNotificationPreferences(),
            $this->notification_preferences ?? []
        );
    }

    public function prefers(string $key): bool
    {
        return (bool) ($this->preferences()[$key] ?? false);
    }
}
