<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Laravel\Sanctum\HasApiTokens;

/**
 * App\Models\Reseller
 *
 * @property int $id
 * @property string $name
 * @property string $email
 * @property string $password
 * @property string|null $phone
 * @property string|null $company_name
 * @property float $balance
 * @property float $commission_rate
 * @property string $status
 * @property string|null $remember_token
 * @property \Illuminate\Support\Carbon|null $created_at
 * @property \Illuminate\Support\Carbon|null $updated_at
 *
 * @method static \Illuminate\Database\Eloquent\Builder|Reseller newModelQuery()
 * @method static \Illuminate\Database\Eloquent\Builder|Reseller newQuery()
 * @method static \Illuminate\Database\Eloquent\Builder|Reseller query()
 * @method static \Illuminate\Database\Eloquent\Builder|Reseller whereId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Reseller whereName($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Reseller whereEmail($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Reseller wherePassword($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Reseller wherePhone($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Reseller whereCompanyName($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Reseller whereBalance($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Reseller whereCommissionRate($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Reseller whereStatus($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Reseller whereCreatedAt($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Reseller whereUpdatedAt($value)
 */
class Reseller extends Authenticatable
{
    use HasFactory, HasApiTokens;

    protected $fillable = [
        'name',
        'email',
        'password',
        'phone',
        'company_name',
        'balance',
        'commission_rate',
        'status',
    ];

    protected $hidden = [
        'password',
        'remember_token',
    ];

    protected $casts = [
        'balance' => 'decimal:2',
        'commission_rate' => 'decimal:2',
    ];

    public function isActive(): bool
    {
        return $this->status === 'active';
    }

    public function users()
    {
        return $this->hasMany(User::class, 'reseller_id');
    }

    public function creditTransactions()
    {
        return $this->hasMany(CreditTransaction::class)->orderBy('created_at', 'desc');
    }

    /**
     * Add credit to reseller balance
     */
    public function addCredit(float $amount, string $type = 'credit', ?string $description = null, ?string $referenceType = null, ?int $referenceId = null, ?string $proofOfPayment = null): CreditTransaction
    {
        $balanceBefore = $this->balance;
        $balanceAfter = $balanceBefore + $amount;

        $this->balance = $balanceAfter;
        $this->save();

        return CreditTransaction::create([
            'reseller_id' => $this->id,
            'type' => $type,
            'amount' => $amount,
            'balance_before' => $balanceBefore,
            'balance_after' => $balanceAfter,
            'reference_type' => $referenceType,
            'reference_id' => $referenceId,
            'description' => $description,
            'proof_of_payment' => $proofOfPayment,
            'status' => 'completed',
        ]);
    }

    /**
     * Deduct from reseller balance
     */
    public function deductCredit(float $amount, string $type = 'debit', ?string $description = null, ?string $referenceType = null, ?int $referenceId = null): ?CreditTransaction
    {
        if ($this->balance < $amount) {
            return null;
        }

        $balanceBefore = $this->balance;
        $balanceAfter = $balanceBefore - $amount;

        $this->balance = $balanceAfter;
        $this->save();

        return CreditTransaction::create([
            'reseller_id' => $this->id,
            'type' => $type,
            'amount' => -$amount,
            'balance_before' => $balanceBefore,
            'balance_after' => $balanceAfter,
            'reference_type' => $referenceType,
            'reference_id' => $referenceId,
            'description' => $description,
            'status' => 'completed',
        ]);
    }

    /**
     * Add commission from an order
     */
    public function addCommission(Order $order, ?float $customRate = null): CreditTransaction
    {
        $rate = $customRate ?? $this->commission_rate;
        $commission = ($order->price * $rate) / 100;

        return $this->addCredit(
            $commission,
            'commission',
            'Commission from Order #' . $order->id,
            Order::class,
            $order->id
        );
    }

    /**
     * Get total earnings from commissions
     */
    public function totalCommissionEarned(): float
    {
        return $this->creditTransactions()
            ->where('type', 'commission')
            ->where('status', 'completed')
            ->sum('amount');
    }

    /**
     * Get total credits added
     */
    public function totalCreditsAdded(): float
    {
        return $this->creditTransactions()
            ->where('type', 'credit')
            ->where('status', 'completed')
            ->sum('amount');
    }

    /**
     * Get total debits
     */
    public function totalDebits(): float
    {
        return abs($this->creditTransactions()
            ->whereIn('type', ['debit', 'refund'])
            ->where('status', 'completed')
            ->sum('amount'));
    }

    /**
     * Get recent transactions
     */
    public function recentTransactions(int $limit = 10)
    {
        return $this->creditTransactions()->limit($limit)->get();
    }
}