<?php

namespace App\Models\SRO_VT_SHARD;

use Illuminate\Database\Eloquent\Model;
use App\Models\SRO_VT_SHARD\RefObjCommon;

class RefObjChar extends Model
{
    /**
     * The Database connection name for the model.
     *
     * @var string
     */
    protected $connection = 'sqlsrv_shard';

    /**
     * Indicates if the model should be timestamped.
     *
     * @var bool
     */
    public $timestamps = false;

    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'dbo._RefObjChar';

    /**
     * The table primary Key
     *
     * @var string
     */
    protected $primaryKey = 'ID';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'Lvl',
        'CharGender',
        'MaxHP',
        'MaxMP',
        'ResistFrozen',
        'ResistFrostbite',
        'ResistBurn',
        'ResistEShock',
        'ResistPoison',
        'ResistZombie',
        'ResistSleep',
        'ResistRoot',
        'ResistSlow',
        'ResistFear',
        'ResistMyopia',
        'ResistBlood',
        'ResistStone',
        'ResistDark',
        'ResistStun',
        'ResistDisea',
        'ResistChaos',
        'ResistCsePD',
        'ResistCseMD',
        'ResistCseSTR',
        'ResistCseINT',
        'ResistCseHP',
        'ResistCseMP',
        'Resist24',
        'ResistBomb',
        'Resist26',
        'Resist27',
        'Resist28',
        'Resist29',
        'Resist30',
        'Resist31',
        'Resist32',
        'InventorySize',
        'CanStore_TID1',
        'CanStore_TID2',
        'CanStore_TID3',
        'CanStore_TID4',
        'CanBeVehicle',
        'CanControl',
        'DamagePortion',
        'MaxPassenger',
        'AssocTactics',
        'PD',
        'MD',
        'PAR',
        'MAR',
        'ER',
        'BR',
        'HR',
        'CHR',
        'ExpToGive',
        'CreepType',
        'Knockdown',
        'KO_RecoverTime',
        'DefaultSkill_1',
        'DefaultSkill_2',
        'DefaultSkill_3',
        'DefaultSkill_4',
        'DefaultSkill_5',
        'DefaultSkill_6',
        'DefaultSkill_7',
        'DefaultSkill_8',
        'DefaultSkill_9',
        'DefaultSkill_10',
        'TextureType',
        'Except_1',
        'Except_2',
        'Except_3',
        'Except_4',
        'Except_5',
        'Except_6',
        'Except_7',
        'Except_8',
        'Except_9',
        'Except_10'
    ];

    /**
     * The attributes that should be casted to native types.
     *
     * @var array
     */
    protected $casts = [
        // Basic info
        'ID' => 'integer',
        'Lvl' => 'integer',
        'CharGender' => 'integer',
        'MaxHP' => 'integer',
        'MaxMP' => 'integer',

        // Resistances
        'ResistFrozen' => 'integer',
        'ResistFrostbite' => 'integer',
        'ResistBurn' => 'integer',
        'ResistEShock' => 'integer',
        'ResistPoison' => 'integer',
        'ResistZombie' => 'integer',
        'ResistSleep' => 'integer',
        'ResistRoot' => 'integer',
        'ResistSlow' => 'integer',
        'ResistFear' => 'integer',
        'ResistMyopia' => 'integer',
        'ResistBlood' => 'integer',
        'ResistStone' => 'integer',
        'ResistDark' => 'integer',
        'ResistStun' => 'integer',
        'ResistDisea' => 'integer',
        'ResistChaos' => 'integer',
        'ResistCsePD' => 'integer',
        'ResistCseMD' => 'integer',
        'ResistCseSTR' => 'integer',
        'ResistCseINT' => 'integer',
        'ResistCseHP' => 'integer',
        'ResistCseMP' => 'integer',
        'Resist24' => 'integer',
        'ResistBomb' => 'integer',
        'Resist26' => 'integer',
        'Resist27' => 'integer',
        'Resist28' => 'integer',
        'Resist29' => 'integer',
        'Resist30' => 'integer',
        'Resist31' => 'integer',
        'Resist32' => 'integer',

        // Storage and control
        'InventorySize' => 'integer',
        'CanStore_TID1' => 'integer',
        'CanStore_TID2' => 'integer',
        'CanStore_TID3' => 'integer',
        'CanStore_TID4' => 'integer',
        'CanBeVehicle' => 'integer',
        'CanControl' => 'integer',
        'DamagePortion' => 'integer',
        'MaxPassenger' => 'integer',
        'AssocTactics' => 'integer',

        // Combat stats
        'PD' => 'integer',  // Physical Defense
        'MD' => 'integer',  // Magic Defense
        'PAR' => 'integer', // Physical Attack Rate
        'MAR' => 'integer', // Magic Attack Rate
        'ER' => 'integer',  // Evade Rate
        'BR' => 'integer',  // Block Rate
        'HR' => 'integer',  // Hit Rate
        'CHR' => 'integer', // Critical Hit Rate

        // Experience and type
        'ExpToGive' => 'integer',
        'CreepType' => 'integer',
        'Knockdown' => 'integer',
        'KO_RecoverTime' => 'integer',

        // Skills
        'DefaultSkill_1' => 'integer',
        'DefaultSkill_2' => 'integer',
        'DefaultSkill_3' => 'integer',
        'DefaultSkill_4' => 'integer',
        'DefaultSkill_5' => 'integer',
        'DefaultSkill_6' => 'integer',
        'DefaultSkill_7' => 'integer',
        'DefaultSkill_8' => 'integer',
        'DefaultSkill_9' => 'integer',
        'DefaultSkill_10' => 'integer',

        // Texture and exceptions
        'TextureType' => 'integer',
        'Except_1' => 'integer',
        'Except_2' => 'integer',
        'Except_3' => 'integer',
        'Except_4' => 'integer',
        'Except_5' => 'integer',
        'Except_6' => 'integer',
        'Except_7' => 'integer',
        'Except_8' => 'integer',
        'Except_9' => 'integer',
        'Except_10' => 'integer',
    ];

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

    /**
     * Get the common object definition for this character
     * ID -> RefObjCommon.Link
     *
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
     */
    public function refObjCommon()
    {
        return $this->hasOne(RefObjCommon::class, 'Link', 'ID');
    }

    // =========================================================================
    // HELPER METHODS
    // =========================================================================

    /**
     * Check if character is male
     *
     * @return bool
     */
    public function isMale()
    {
        return $this->CharGender == 1;
    }

    /**
     * Check if character is female
     *
     * @return bool
     */
    public function isFemale()
    {
        return $this->CharGender == 0;
    }

    /**
     * Get gender name
     *
     * @return string
     */
    public function getGenderName()
    {
        return $this->isMale() ? 'Male' : 'Female';
    }

    /**
     * Check if can be used as vehicle
     *
     * @return bool
     */
    public function canBeVehicle()
    {
        return $this->CanBeVehicle == 1;
    }

    /**
     * Check if can be controlled
     *
     * @return bool
     */
    public function canControl()
    {
        return $this->CanControl == 1;
    }

    /**
     * Get all resistances as array
     *
     * @return array
     */
    public function getResistances()
    {
        return [
            'frozen' => $this->ResistFrozen,
            'frostbite' => $this->ResistFrostbite,
            'burn' => $this->ResistBurn,
            'shock' => $this->ResistEShock,
            'poison' => $this->ResistPoison,
            'zombie' => $this->ResistZombie,
            'sleep' => $this->ResistSleep,
            'root' => $this->ResistRoot,
            'slow' => $this->ResistSlow,
            'fear' => $this->ResistFear,
            'myopia' => $this->ResistMyopia,
            'blood' => $this->ResistBlood,
            'stone' => $this->ResistStone,
            'dark' => $this->ResistDark,
            'stun' => $this->ResistStun,
            'disease' => $this->ResistDisea,
            'chaos' => $this->ResistChaos,
        ];
    }

    /**
     * Get combat stats as array
     *
     * @return array
     */
    public function getCombatStats()
    {
        return [
            'physical_defense' => $this->PD,
            'magic_defense' => $this->MD,
            'physical_attack_rate' => $this->PAR,
            'magic_attack_rate' => $this->MAR,
            'evade_rate' => $this->ER,
            'block_rate' => $this->BR,
            'hit_rate' => $this->HR,
            'critical_hit_rate' => $this->CHR,
        ];
    }

    /**
     * Get default skills as array
     *
     * @return array
     */
    public function getDefaultSkills()
    {
        $skills = [];
        for ($i = 1; $i <= 10; $i++) {
            $skillField = "DefaultSkill_{$i}";
            if (!is_null($this->{$skillField}) && $this->{$skillField} > 0) {
                $skills[] = $this->{$skillField};
            }
        }
        return $skills;
    }

    /**
     * Get storage capabilities as array
     *
     * @return array
     */
    public function getStorageCapabilities()
    {
        return [
            'inventory_size' => $this->InventorySize,
            'can_store_type1' => $this->CanStore_TID1 == 1,
            'can_store_type2' => $this->CanStore_TID2 == 1,
            'can_store_type3' => $this->CanStore_TID3 == 1,
            'can_store_type4' => $this->CanStore_TID4 == 1,
        ];
    }

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

    /**
     * Scope to get characters by level
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @param int $level
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeByLevel($query, $level)
    {
        return $query->where('Lvl', $level);
    }

    /**
     * Scope to get characters by gender
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @param int $gender
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeByGender($query, $gender)
    {
        return $query->where('CharGender', $gender);
    }

    /**
     * Scope to get vehicular characters
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeVehicles($query)
    {
        return $query->where('CanBeVehicle', 1);
    }

    /**
     * Scope to get controllable characters
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeControllable($query)
    {
        return $query->where('CanControl', 1);
    }

    /**
     * Scope to get characters by minimum level
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @param int $minLevel
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeMinLevel($query, $minLevel)
    {
        return $query->where('Lvl', '>=', $minLevel);
    }
}
