<?php

namespace App\Models;

use App\Models\Traits\HasAuditFields;
use App\Models\Traits\HasScopes;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class CustomerVendor extends Model
{
    use HasFactory, SoftDeletes, HasAuditFields, HasScopes;

    /**
     * Role constants
     */
    public const ROLE_CUSTOMER = 'Customer';
    public const ROLE_VENDOR = 'Vendor';
    public const ROLE_BOTH = 'Both';

    /**
     * Status constants
     */
    public const STATUS_ACTIVE = 'active';
    public const STATUS_INACTIVE = 'inactive';

    protected $fillable = [
        'company_role',
        'company',
        'email',
        'company_nickname',
        'image',
        'mobile',
        'secondary_mobile',
        'company_type',
        'gstno',
        'panno',
        'msmeno',
        'iecno',
        'billing_address',
        'shipping_address',
        'url',
        'bank_name',
        'branch_name',
        'account_number',
        'account_type',
        'account_holder_name',
        'account_currency',
        'ifsc_code',
        'swift_code',
        'status',
        'created_by',
        'updated_by',
    ];

    protected $casts = [
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
    ];

    // ──────────────────────────────────────────────────────────────────────────
    // RELATIONSHIPS
    // ──────────────────────────────────────────────────────────────────────────

    /**
     * Contact persons for this company
     */
    public function contactPersons()
    {
        return $this->hasMany(ContactPerson::class, 'customer_vendor_id');
    }

    /**
     * Purchase RFQs sent to this vendor
     */
    public function rfqs()
    {
        return $this->hasMany(PurchaseRFQ::class, 'vendor_id', 'id');
    }

    /**
     * Tax invoices for this customer
     */
    public function invoices()
    {
        return $this->hasMany(TaxInvoice::class, 'company_id');
    }

    /**
     * Quotations for this customer
     */
    public function quotations()
    {
        return $this->hasMany(Quotation::class, 'customer_name', 'id');
    }

    /**
     * Sales orders for this customer
     */
    public function salesOrders()
    {
        return $this->hasMany(SalesOrder::class, 'company_name', 'id');
    }

    /**
     * Purchase orders to this vendor
     */
    public function purchaseOrders()
    {
        return $this->hasMany(PurchaseOrder::class, 'vendor_id');
    }

    /**
     * Purchase quotations from this vendor
     */
    public function purchaseQuotations()
    {
        return $this->hasMany(PurchaseQuotation::class, 'vendor_id');
    }

    /**
     * Sales payments from this customer
     */
    public function salesPayments()
    {
        return $this->hasMany(SalesPayment::class, 'company_id');
    }

    /**
     * Credit notes for this customer
     */
    public function creditNotes()
    {
        return $this->hasMany(SalesCreditNote::class, 'company_id');
    }

    /**
     * Debit notes for this customer
     */
    public function debitNotes()
    {
        return $this->hasMany(SalesDebitNote::class, 'company_id');
    }

    // ──────────────────────────────────────────────────────────────────────────
    // SCOPES
    // ──────────────────────────────────────────────────────────────────────────

    /**
     * Filter customers only
     */
    public function scopeCustomers(Builder $query): Builder
    {
        return $query->whereIn('company_role', [self::ROLE_CUSTOMER, self::ROLE_BOTH]);
    }

    /**
     * Filter vendors only
     */
    public function scopeVendors(Builder $query): Builder
    {
        return $query->whereIn('company_role', [self::ROLE_VENDOR, self::ROLE_BOTH]);
    }

    /**
     * Filter by active status
     */
    public function scopeActive(Builder $query): Builder
    {
        return $query->where('status', self::STATUS_ACTIVE);
    }

    /**
     * Filter by company type
     */
    public function scopeOfType(Builder $query, string $type): Builder
    {
        return $query->where('company_type', $type);
    }

    /**
     * Search by company name or email
     */
    public function scopeSearchCompany(Builder $query, string $term): Builder
    {
        return $query->where(function ($q) use ($term) {
            $q->where('company', 'LIKE', "%{$term}%")
              ->orWhere('email', 'LIKE', "%{$term}%")
              ->orWhere('company_nickname', 'LIKE', "%{$term}%");
        });
    }

    /**
     * Order by company name
     */
    public function scopeOrderByName(Builder $query): Builder
    {
        return $query->orderBy('company', 'asc');
    }

    // ──────────────────────────────────────────────────────────────────────────
    // ACCESSORS & HELPERS
    // ──────────────────────────────────────────────────────────────────────────

    /**
     * Check if this is a customer
     */
    public function isCustomer(): bool
    {
        return in_array($this->company_role, [self::ROLE_CUSTOMER, self::ROLE_BOTH]);
    }

    /**
     * Check if this is a vendor
     */
    public function isVendor(): bool
    {
        return in_array($this->company_role, [self::ROLE_VENDOR, self::ROLE_BOTH]);
    }

    /**
     * Get primary contact person
     */
    public function getPrimaryContact()
    {
        return $this->contactPersons()->first();
    }

    /**
     * Get total invoice amount
     */
    public function getTotalInvoiceAmount(): float
    {
        return $this->invoices()->sum('total_amount') ?? 0;
    }

    /**
     * Get total paid amount
     */
    public function getTotalPaidAmount(): float
    {
        return $this->salesPayments()->sum('amount') ?? 0;
    }

    /**
     * Get outstanding balance
     */
    public function getOutstandingBalance(): float
    {
        return $this->getTotalInvoiceAmount() - $this->getTotalPaidAmount();
    }
}
