<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Facades\DB;

class UserAddress extends Model
{
    // table name
    protected $table = 'user_addresses';

    // mass-assignable columns
    protected $fillable = [
        'user_id',
        'label',
        'kind',
        'line1',
        'line2',
        'city',
        'state',
        'postal',
        'country',
        'phone',
        'location_id',
        'is_primary',
    ];

    // simple casts
    protected $casts = [
        'is_primary' => 'boolean',
        'is_billing' => 'boolean',
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
    ];

    /* relationships */

    // belongs to a user (users.id is char(26))
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class, 'user_id', 'id');
    }

    // optional normalized/geocoded location row
    public function location(): BelongsTo
    {
        return $this->belongsTo(Location::class, 'location_id');
    }

    /* query scopes */

    // filter by kind (e.g., 'billing', 'shipping', 'home', 'work')
    public function scopeKind($query, string $kind)
    {
        return $query->where('kind', $kind);
    }

    // filter to primary rows
    public function scopePrimary($query)
    {
        return $query->where('is_primary', 1);
    }

    /* helpers */

    // set this address as the single primary of its kind for the user
    public function setAsPrimary(): void
    {
        DB::transaction(function () {
            // clear any existing primary for this user+kind (null is allowed by the unique index)
            static::where('user_id', $this->user_id)
                ->where('kind', $this->kind)
                ->update(['is_primary' => null]);

            // mark this one as primary
            $this->is_primary = 1;
            $this->save();
        });
    }

    // quick one-line label useful for dropdowns and summaries
    public function getOneLineAttribute(): string
    {
        $parts = array_filter([
            $this->label,
            $this->line1,
            $this->line2,
            $this->city,
            $this->state,
            $this->postal,
            $this->country,
        ]);

        return trim(collect($parts)->join(', '));
    }
}
