<?php

namespace App\Models;

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

class MessageTemplate extends Model
{
    use HasFactory;

    /**
     * Template types.
     */
    const TYPE_AUTO_REPLY = 'auto_reply';
    const TYPE_PROMOTION = 'promotion';

    /**
     * Call types.
     */
    const CALL_TYPE_INCOMING = 'incoming';
    const CALL_TYPE_OUTGOING = 'outgoing';
    const CALL_TYPE_MISSED = 'missed';
    const CALL_TYPE_ALL = 'all';

    /**
     * Channels.
     */
    const CHANNEL_SMS = 'sms';
    const CHANNEL_WHATSAPP = 'whatsapp';
    const CHANNEL_BOTH = 'both';

    /**
     * Media types.
     */
    const MEDIA_TYPE_IMAGE = 'image';
    const MEDIA_TYPE_VIDEO = 'video';

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'user_id',
        'client_id',
        'name',
        'type',
        'call_type',
        'content',
        'is_default',
        'is_active',
        'is_global',
        'priority',
        // Channel and media fields
        'channel',
        'media_type',
        'media_url',
        'automation_mode',
        // Tracking fields
        'created_from_template_id',
        'created_by_admin',
        'created_by_client_admin',
        'last_modified_by',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'is_default' => 'boolean',
        'is_active' => 'boolean',
        'is_global' => 'boolean',
        'priority' => 'integer',
    ];

    // ============ RELATIONSHIPS ============

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

    /**
     * Get the client this template belongs to.
     */
    public function client()
    {
        return $this->belongsTo(Client::class);
    }

    /**
     * Get the original template this was created from.
     */
    public function createdFrom()
    {
        return $this->belongsTo(MessageTemplate::class, 'created_from_template_id');
    }

    /**
     * Get templates created from this template.
     */
    public function derivedTemplates()
    {
        return $this->hasMany(MessageTemplate::class, 'created_from_template_id');
    }

    /**
     * Get the admin who created this template.
     */
    public function createdByAdmin()
    {
        return $this->belongsTo(Admin::class, 'created_by_admin');
    }

    /**
     * Get the client admin who created this template.
     */
    public function createdByClientAdmin()
    {
        return $this->belongsTo(ClientAdmin::class, 'created_by_client_admin');
    }

    // ============ SCOPES ============

    /**
     * Scope a query to only include active templates.
     */
    public function scopeActive($query)
    {
        return $query->where('is_active', true);
    }

    /**
     * Scope a query to only include the default template.
     */
    public function scopeDefault($query)
    {
        return $query->where('is_default', true);
    }

    /**
     * Scope for auto-reply templates.
     */
    public function scopeAutoReply($query)
    {
        return $query->where('type', self::TYPE_AUTO_REPLY);
    }

    /**
     * Scope for promotion templates.
     */
    public function scopePromotion($query)
    {
        return $query->where('type', self::TYPE_PROMOTION);
    }

    /**
     * Scope for specific call type.
     */
    public function scopeForCallType($query, string $callType)
    {
        return $query->where(function ($q) use ($callType) {
            $q->where('call_type', $callType)
                ->orWhere('call_type', self::CALL_TYPE_ALL);
        });
    }

    /**
     * Scope for global templates.
     */
    public function scopeGlobal($query)
    {
        return $query->where('is_global', true);
    }

    /**
     * Scope for specific channel (sms/whatsapp).
     */
    public function scopeForChannel($query, string $channel)
    {
        return $query->where('channel', $channel);
    }

    /**
     * Scope for SMS templates.
     */
    public function scopeSms($query)
    {
        return $query->where('channel', self::CHANNEL_SMS);
    }

    /**
     * Scope for WhatsApp templates.
     */
    public function scopeWhatsApp($query)
    {
        return $query->where('channel', self::CHANNEL_WHATSAPP);
    }

    /**
     * Scope for templates belonging to a specific client.
     */
    public function scopeForClient($query, $clientId)
    {
        return $query->where('client_id', $clientId);
    }

    /**
     * Scope for SuperAdmin global templates (no client).
     */
    public function scopeSuperAdminGlobal($query)
    {
        return $query->where('is_global', true)->whereNull('client_id');
    }

    // ============ TEMPLATE METHODS ============

    /**
     * Set this template as the default and unset others.
     */
    public function setAsDefault()
    {
        // Unset all other defaults for this user
        static::where('user_id', $this->user_id)
            ->where('id', '!=', $this->id)
            ->where('type', $this->type)
            ->where('call_type', $this->call_type)
            ->update(['is_default' => false]);

        // Set this as default
        $this->update(['is_default' => true, 'is_active' => true]);
    }

    /**
     * Get the processed content with placeholders replaced.
     */
    public function getProcessedContent(array $placeholders = []): string
    {
        $content = $this->content;

        foreach ($placeholders as $key => $value) {
            $content = str_replace("{{{$key}}}", $value, $content);
        }

        return $content;
    }

    /**
     * Get formatted template data for API response.
     */
    public function toApiResponse(): array
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'type' => $this->type,
            'call_type' => $this->call_type,
            'content' => $this->content,
            'is_active' => $this->is_active,
            'is_default' => $this->is_default,
            'priority' => $this->priority,
            // Channel and media fields
            'channel' => $this->channel ?? self::CHANNEL_SMS,
            'media_type' => $this->media_type,
            'media_url' => $this->media_url,
            'automation_mode' => $this->automation_mode,
        ];
    }

    /**
     * Duplicate this template to a client.
     * Used by SuperAdmin to assign global templates to clients.
     */
    public function duplicateToClient(Client $client, ?Admin $admin = null): static
    {
        $newTemplate = $this->replicate();
        $newTemplate->client_id = $client->id;
        $newTemplate->user_id = null;
        $newTemplate->is_global = false;
        $newTemplate->created_from_template_id = $this->id;
        $newTemplate->created_by_admin = $admin?->id;
        $newTemplate->created_by_client_admin = null;
        $newTemplate->last_modified_by = $admin ? "admin:{$admin->id}" : null;
        $newTemplate->save();

        return $newTemplate;
    }

    /**
     * Check if this template was derived from another template.
     */
    public function isDerived(): bool
    {
        return $this->created_from_template_id !== null;
    }

    /**
     * Sync changes from this global template to all client copies.
     * Called when a SuperAdmin edits a global template.
     */
    public function syncGlobalChangesToClients(): int
    {
        if (!$this->isSuperAdminGlobal()) {
            return 0;
        }

        $syncFields = ['name', 'content', 'type', 'call_type', 'is_active', 'priority', 'channel', 'media_type', 'media_url', 'automation_mode'];
        $updates = [];
        foreach ($syncFields as $field) {
            $updates[$field] = $this->$field;
        }
        $updates['last_modified_by'] = $this->last_modified_by;

        return static::where('created_from_template_id', $this->id)
            ->update($updates);
    }

    /**
     * Check if this is a SuperAdmin global template.
     */
    public function isSuperAdminGlobal(): bool
    {
        return $this->is_global && $this->client_id === null;
    }

    /**
     * Check if this is a client-specific template.
     */
    public function isClientTemplate(): bool
    {
        return $this->client_id !== null;
    }

    /**
     * Record modification by admin.
     */
    public function recordModification(Admin $admin): void
    {
        $this->update(['last_modified_by' => "admin:{$admin->id}"]);
    }

    /**
     * Record modification by client admin.
     */
    public function recordModificationByClientAdmin(ClientAdmin $clientAdmin): void
    {
        $this->update(['last_modified_by' => "client_admin:{$clientAdmin->id}"]);
    }
}
