<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class CallLog extends Model
{
    use HasFactory;

    const STATUS_NEW = 'new';
    const STATUS_CALLBACK = 'callback';
    const STATUS_FOLLOW_UP = 'follow_up';
    const STATUS_INTERESTED = 'interested';
    const STATUS_NOT_INTERESTED = 'not_interested';

    /**
     * Supported CRM-style statuses for call annotations.
     */
    public const STATUS_OPTIONS = [
        self::STATUS_NEW,
        self::STATUS_CALLBACK,
        self::STATUS_FOLLOW_UP,
        self::STATUS_INTERESTED,
        self::STATUS_NOT_INTERESTED,
    ];

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'user_id',
        'device_id',
        'device_name',
        'phone_number',
        'call_type',
        'status_key',
        'status_note',
        'status_updated_at',
        'call_time',
        'call_duration',
        'sms_sent',
        'synced_at',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'call_time' => 'datetime',
        'status_updated_at' => 'datetime',
        'synced_at' => 'datetime',
        'sms_sent' => 'boolean',
        'call_duration' => 'integer',
    ];

    /**
     * Get the allowed status keys.
     */
    public static function allowedStatusKeys(): array
    {
        return self::STATUS_OPTIONS;
    }

    /**
     * Get the display label for a status key.
     */
    public static function labelForStatus(?string $statusKey): ?string
    {
        if (!$statusKey) {
            return null;
        }

        return match ($statusKey) {
            self::STATUS_CALLBACK => 'Callback',
            self::STATUS_FOLLOW_UP => 'Follow Up',
            self::STATUS_INTERESTED => 'Interested',
            self::STATUS_NOT_INTERESTED => 'Not Interested',
            default => 'New',
        };
    }

    /**
     * Get status options keyed by value with human labels.
     */
    public static function statusOptions(): array
    {
        return collect(self::allowedStatusKeys())
            ->mapWithKeys(fn (string $statusKey) => [$statusKey => self::labelForStatus($statusKey)])
            ->all();
    }

    /**
     * Get status label for display.
     */
    public function getStatusLabelAttribute(): ?string
    {
        return self::labelForStatus($this->status_key);
    }

    /**
     * Get Bootstrap color hint for status badges.
     */
    public function getStatusBadgeClassAttribute(): string
    {
        return match ($this->status_key) {
            self::STATUS_CALLBACK => 'info',
            self::STATUS_FOLLOW_UP => 'warning',
            self::STATUS_INTERESTED => 'success',
            self::STATUS_NOT_INTERESTED => 'danger',
            default => 'secondary',
        };
    }

    /**
     * Get the user that owns the call log.
     */
    public function user()
    {
        return $this->belongsTo(User::class);
    }

    /**
     * Get the SMS log associated with this call.
     */
    public function smsLog()
    {
        return $this->hasOne(SmsLog::class);
    }

    /**
     * Scope a query to only include incoming calls.
     */
    public function scopeIncoming($query)
    {
        return $query->where('call_type', 'incoming');
    }

    /**
     * Scope a query to only include outgoing calls.
     */
    public function scopeOutgoing($query)
    {
        return $query->where('call_type', 'outgoing');
    }

    /**
     * Scope a query to only include missed calls.
     */
    public function scopeMissed($query)
    {
        return $query->where('call_type', 'missed');
    }

    /**
     * Scope a query to only include calls where SMS was sent.
     */
    public function scopeWithSmsSent($query)
    {
        return $query->where('sms_sent', true);
    }

    /**
     * Scope a query to filter by date range.
     */
    public function scopeDateRange($query, $startDate, $endDate)
    {
        return $query->whereBetween('call_time', [$startDate, $endDate]);
    }

    /**
     * Get formatted call type for display.
     */
    public function getCallTypeFormattedAttribute()
    {
        return ucfirst($this->call_type);
    }

    /**
     * Get call type badge class.
     */
    public function getCallTypeBadgeAttribute()
    {
        return 'badge-' . $this->call_type;
    }
}
