<?php

namespace App\Models;

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

class Lead extends Model
{
    use HasFactory;

    public const STATUSES = [
        'New Lead',             // Fresh Enquiry
        'Contacted',            // Baat ho gayi hai
        'Requirement Received', // Brief mil gaya hai (Size, Show Name, etc.)
        'Design in Progress',   // 3D Rendering ho rahi hai
        'Proposal Sent',        // Design aur Quotation bhej diya hai
        'Follow-up',            // Client ke feedback ka intezar
        'Negotiation',          // Price/Design par behas chal rahi hai
        'Shortlisted',          // Client humein final 2-3 mein rakh chuka hai
        'Won/Ongoing',          // Order Confirm (Project Start)
        'On Hold',              // Plan delay ho gaya
        'Lost',                 // Client ne mana kar diya
        'Out of Budget',        // Hamare rates match nahi hue
        'Dead/Garbage'          // Fake enquiry ya show cancel
    ];

    public const DESIGN_TASK_STATUSES = [
        'Pending',
        'In Progress',
        'Awaiting Review',
        'Revision Required',
        'Completed',
        'On Hold',
    ];

    protected $fillable = [
        'tradefair_id',
        'source_location',
        'contact_person_name',
        'fair_name',
        'city',
        'country',
        'fair_start_date',
        'fair_end_date',
        'booth_area_sqm',
        'booth_area_sqft',
        'lead_budget',
        'company_name',
        'email_id',
        'phone_number',
        'description',
        'lead_status',
        'assigned_to_user_id',
        'assigned_by_user_id',
        'assigned_at',
        'design_assigned_to_user_id',
        'design_assigned_by_user_id',
        'design_assigned_at',
        'design_task_status',
        'design_due_date',
    ];

    protected $casts = [
        'fair_start_date' => 'date:Y-m-d',
        'fair_end_date' => 'date:Y-m-d',
        'assigned_at' => 'datetime',
        'design_assigned_at' => 'datetime',
        'design_due_date' => 'date:Y-m-d',
    ];

    public function tradefair()
    {
        return $this->belongsTo(Tradefair::class);
    }

    public function vendorQuotes()
    {
        return $this->hasMany(VendorQuote::class);
    }

    public function displayFairName(): string
    {
        $tradefair = $this->tradefair;
        if ($tradefair && $tradefair->fair_name !== null && $tradefair->fair_name !== '') {
            return (string) $tradefair->fair_name;
        }

        return (string) ($this->fair_name ?? '');
    }

    public function displayVenue(): string
    {
        $venue = optional($this->tradefair)->eventvenue ?: $this->city;

        return $venue !== null && $venue !== '' ? (string) $venue : '-';
    }

    /**
     * Prefer sqm; otherwise sqft; otherwise dash.
     */
    public function displayArea(): string
    {
        if ($this->booth_area_sqm !== null && (float) $this->booth_area_sqm > 0) {
            return number_format((float) $this->booth_area_sqm, 2) . ' sqm';
        }
        if ($this->booth_area_sqft !== null && (float) $this->booth_area_sqft > 0) {
            return number_format((float) $this->booth_area_sqft, 2) . ' sqft';
        }

        return '-';
    }

    public function effectiveFairStartDate()
    {
        $tradefair = $this->tradefair;

        return $tradefair ? $tradefair->event_start_date : $this->fair_start_date;
    }

    public function effectiveFairEndDate()
    {
        $tradefair = $this->tradefair;

        return $tradefair ? $tradefair->event_end_date : $this->fair_end_date;
    }

    public function leadViews()
    {
        return $this->hasMany(LeadView::class);
    }

    public function remarks()
    {
        return $this->hasMany(LeadRemark::class)->latest();
    }

    public function designRemarks()
    {
        return $this->hasMany(LeadRemark::class)->where('type', 'design')->latest();
    }

    public function getCleanDesignTaskStatusAttribute(): string
    {
        return trim((string) ($this->design_task_status ?: 'Pending'));
    }

    public function isDesignOverdue(): bool
    {
        if (!$this->design_due_date || $this->clean_design_task_status === 'Completed') {
            return false;
        }

        return $this->design_due_date->isPast();
    }

    public function assignedTo()
    {
        return $this->belongsTo(User::class, 'assigned_to_user_id');
    }

    public function assignedBy()
    {
        return $this->belongsTo(User::class, 'assigned_by_user_id');
    }

    public function isAssignedTo(User $user): bool
    {
        return (int) $this->assigned_to_user_id === (int) $user->id;
    }

    public function designAssignedTo()
    {
        return $this->belongsTo(User::class, 'design_assigned_to_user_id');
    }

    public function designAssignedBy()
    {
        return $this->belongsTo(User::class, 'design_assigned_by_user_id');
    }

    public function isDesignAssignedTo(User $user): bool
    {
        return (int) $this->design_assigned_to_user_id === (int) $user->id;
    }

    public function getCleanLeadStatusAttribute(): string
    {
        return trim(strip_tags((string) $this->lead_status));
    }

    public function maskedEmail(): string
    {
        $email = (string) $this->email_id;

        if ($email === '' || strpos($email, '@') === false) {
            return $this->maskValue($email);
        }

        [$local, $domain] = explode('@', $email, 2);
        $visibleLocalLength = max(1, (int) ceil(strlen($local) / 2));
        $visibleDomainLength = min(3, max(1, (int) ceil(strlen($domain) / 3)));

        return substr($local, 0, $visibleLocalLength)
            . str_repeat('*', max(1, strlen($local) - $visibleLocalLength))
            . '@'
            . substr($domain, 0, $visibleDomainLength)
            . str_repeat('*', max(1, strlen($domain) - $visibleDomainLength));
    }

    public function maskedPhone(): string
    {
        return $this->maskValue((string) $this->phone_number);
    }

    public function whatsappPhoneNumber(): string
    {
        return preg_replace('/\D+/', '', (string) $this->phone_number);
    }

    private function maskValue(string $value): string
    {
        if ($value === '') {
            return '-';
        }

        $visibleLength = max(1, (int) ceil(strlen($value) / 2));

        return substr($value, 0, $visibleLength) . str_repeat('*', max(1, strlen($value) - $visibleLength));
    }
}
