<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use NotificationChannels\WebPush\HasPushSubscriptions;

class User extends Authenticatable
{
    use HasFactory, HasApiTokens, HasPushSubscriptions, Notifiable;

    protected $fillable = [
        'name',
        'email',
        'password',
        'role',
        'phone',
        'avatar_url',
        'is_active',
    ];

    protected $hidden = [
        'password',
        'remember_token',
    ];

    protected $casts = [
        'is_active' => 'boolean',
        'email_verified_at' => 'datetime',
        'password' => 'hashed',
    ];

    public function barber()
    {
        return $this->hasOne(Barber::class);
    }

    public function clientAppointments()
    {
        return $this->hasMany(Appointment::class, 'client_id');
    }

    /**
     * Tokens Expo Push de la app WABiz (admin); usados para avisos de campana / modo humano.
     *
     * @return \Illuminate\Database\Eloquent\Relations\HasMany<MobileExpoPushToken, $this>
     */
    public function mobileExpoPushTokens()
    {
        return $this->hasMany(MobileExpoPushToken::class);
    }

    /**
     * Busca cliente por el número que envía WhatsApp (solo dígitos, ej. 50688393130).
     * Coincide con phone guardado como +506…, espacios, 506… o 8 dígitos locales (CR).
     */
    public static function findClientByWhatsAppDigits(string $digits): ?self
    {
        $digits = preg_replace('/\D/', '', $digits) ?? '';
        if ($digits === '') {
            return null;
        }

        $phoneDigitsExpr = "REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(COALESCE(phone,''),' ',''),'+',''),'-',''),'(',''),')',''),'.','')";

        return static::query()
            ->where('role', 'client')
            ->where(function (Builder $q) use ($digits, $phoneDigitsExpr) {
                $q->whereRaw("{$phoneDigitsExpr} = ?", [$digits])
                    ->orWhere('phone', $digits)
                    ->orWhere('phone', '+'.$digits);

                if (strlen($digits) === 11 && str_starts_with($digits, '506')) {
                    $local8 = substr($digits, 3);
                    $q->orWhereRaw("{$phoneDigitsExpr} = ?", [$local8]);
                }
            })
            ->first();
    }

    /**
     * Match name, email, or phone; phone also matches when formats differ (spaces, +506, pasted full number vs local).
     */
    public function scopeWhereClientSearch(Builder $query, string $q): Builder
    {
        $q = trim($q);
        if ($q === '') {
            return $query;
        }

        $like = '%' . addcslashes($q, '%_\\') . '%';
        $digitsOnly = preg_replace('/\D+/', '', $q);

        return $query->where(function (Builder $w) use ($like, $digitsOnly) {
            $w->where('name', 'like', $like)
                ->orWhere('email', 'like', $like)
                ->orWhere('phone', 'like', $like);

            if (strlen($digitsOnly) >= 3) {
                $phoneDigitsExpr = "REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(COALESCE(phone,''),' ',''),'+',''),'-',''),'(',''),')',''),'.','')";
                $w->orWhereRaw("{$phoneDigitsExpr} LIKE ?", ['%' . $digitsOnly . '%']);
                $w->orWhereRaw(
                    '(LENGTH(TRIM(COALESCE(phone,\'\'))) > 0 AND ? LIKE CONCAT(\'%\', ' . $phoneDigitsExpr . ', \'%\'))',
                    [$digitsOnly]
                );
            }
        });
    }
}
