<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\Activitylog\LogOptions;

class Contact extends Model
{
	use LogsActivity;

	protected $table = 'contacts';

	protected $fillable = [
		'name',
		'contact_person',
		'phone',
		'email',
		'cnic',
		'gender',
		'address',
		'rating',
		'term_type',
		'term_value',
		'value_unit',
		'term_description',
		'status',
		'is_active',
		'type',
		'account_id',
		'user_id',
		'shop_id',
		'employee_account_id',
		'pay_amount',
		'incentive_amount',
		'holidays_per_week',
		'is_daily_wager',
		'per_day_amount',
		'per_hour_amount',
	];

	protected $casts = [
		'rating' => 'decimal:2',
		'term_value' => 'decimal:2',
		'is_active' => 'boolean',
		'account_id' => 'integer',
		'user_id' => 'integer',
		'shop_id' => 'integer',
		'employee_account_id' => 'integer',
		'pay_amount' => 'decimal:2',
		'incentive_amount' => 'decimal:2',
		'holidays_per_week' => 'integer',
		'is_daily_wager' => 'boolean',
		'per_day_amount' => 'decimal:2',
		'per_hour_amount' => 'decimal:2',
	];

	public function purchaseRequests(): HasMany
	{
		return $this->hasMany(PurchaseRequest::class, 'contact_id');
	}

	public function gatePasses(): HasMany
	{
		return $this->hasMany(GatePass::class, 'contact_id');
	}

	public function isLinkedToTransactions(): bool
	{
		return $this->purchaseOrders()->exists()
			|| method_exists($this, 'purchaseRequests') && $this->purchaseRequests()->exists()
			|| method_exists($this, 'gatePasses') && $this->gatePasses()->exists();
	}

	// Relationships
	public function itemSuppliers(): HasMany
	{
		return $this->hasMany(ItemSupplier::class, 'contact_id');
	}

	public function purchaseOrders(): HasMany
	{
		return $this->hasMany(PurchaseOrder::class, 'contact_id');
	}

	public function account(): BelongsTo
	{
		return $this->belongsTo(Account::class);
	}

	public function employeeAccount(): BelongsTo
	{
		return $this->belongsTo(Account::class, 'employee_account_id');
	}

	public function user(): BelongsTo
	{
		return $this->belongsTo(User::class);
	}

	public function shop(): BelongsTo
	{
		return $this->belongsTo(Shop::class);
	}

	public function managedShop(): HasOne
	{
		return $this->hasOne(Shop::class, 'manager_contact_id');
	}

	// Scopes
	public function scopeActive($query)
	{
		return $query->where('is_active', true);
	}

	public function scopeVendor($query)
	{
		return $query->where('type', 'supplier');
	}

	public function scopeVendors($query)
	{
		return $query->where('type', 'supplier');
	}

	public function scopeCustomers($query)
	{
		return $query->where('type', 'customer');
	}

	public function scopeEmployees($query)
	{
		return $query->where('type', 'employee');
	}

	public function scopeShopManagers($query)
	{
		return $query->where('type', 'shop_manager');
	}

	public function scopeShopEmployees($query)
	{
		return $query->where('type', 'shop_employee');
	}

	public function scopeByType($query, $type)
	{
		return $query->where('type', $type);
	}

	// Helper methods
	public function getIsVendorAttribute()
	{
		return $this->type === 'supplier';
	}

	public function getIsCustomerAttribute()
	{
		return $this->type === 'customer';
	}

	public function getIsEmployeeAttribute()
	{
		return $this->type === 'employee';
	}

	public function getIsShopManagerAttribute()
	{
		return $this->type === 'shop_manager';
	}

	public function getIsShopEmployeeAttribute()
	{
		return $this->type === 'shop_employee';
	}

	public function getTypeLabelAttribute()
	{
		return ucwords(str_replace('_', ' ', $this->type));
	}

	public function getGenderLabelAttribute()
	{
		return ucfirst($this->gender ?? 'Not specified');
	}

	public function getFormattedCnicAttribute()
	{
		if (!$this->cnic) {
			return '-';
		}

		// Format CNIC as XXXXX-XXXXXXX-X
		$cnic = preg_replace('/[^0-9]/', '', $this->cnic);
		if (strlen($cnic) === 13) {
			return substr($cnic, 0, 5) . '-' . substr($cnic, 5, 7) . '-' . substr($cnic, 12, 1);
		}

		return $this->cnic;
	}

	public function getFormattedRatingAttribute()
	{
		return $this->rating ? number_format($this->rating, 1) . '/5' : '-';
	}

	public function getFormattedTermsAttribute()
	{
		if (!$this->term_type || !$this->term_value) {
			return '-';
		}

		return $this->term_value . ' ' . $this->value_unit . ' ' . ucfirst($this->term_type);
	}

	public function getTotalPurchaseOrdersAttribute()
	{
		return $this->purchaseOrders()->count();
	}

	public function getSuppliedItemsAttribute()
	{
		return $this->itemSuppliers()
					->with('item')
					->where('is_active', true)
					->where('approval_status', 'approved')
					->get()
					->pluck('item');
	}

	public function getAccountBalanceAttribute()
	{
		return $this->account ? $this->account->balance : 0;
	}

	public function getFormattedAccountBalanceAttribute()
	{
		return format_currency($this->account_balance);
	}

	public function hasUser()
	{
		return !is_null($this->user_id);
	}

	public function syncUserStatus()
	{
		if ($this->hasUser() && $this->user) {
			$this->user->update(['is_active' => $this->is_active]);
		}
	}

	public function getActivitylogOptions(): LogOptions
	{
		return LogOptions::defaults()
			->useLogName('contact')
			->logFillable()
			->logOnlyDirty()
			->dontSubmitEmptyLogs();
	}
}
