<?php

namespace App\Laravue\Models;

use App\Counseling;
use App\IdentityVerificationLog;
use App\UserCard;
use App\UserType;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Spatie\Permission\Traits\HasRoles;
use Laravel\Sanctum\HasApiTokens;

/**
 * Class User
 *
 * @property string $name
 * @property string $email
 * @property string $password
 * @property Role[] $roles
 *
 * @method static User create(array $user)
 * @package App
 */
class User extends Authenticatable
{
    use Notifiable, HasRoles, HasApiTokens;

    /**
     * Identity verification status constants
     */
    const IDENTITY_STATUS_NOT_SUBMITTED = 'not_submitted';
    const IDENTITY_STATUS_PENDING = 'pending';
    const IDENTITY_STATUS_APPROVED = 'approved';
    const IDENTITY_STATUS_REJECTED = 'rejected';

    /**
     * Identity document type constants
     */
    const IDENTITY_DOC_DRIVER_LICENSE = 'driver_license';
    const IDENTITY_DOC_MY_NUMBER_CARD = 'my_number_card';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
	    'name', 'slug', 'first_name', 'last_name', 'full_name', 'furigana_name', 'furigana_first_name', 'furigana_last_name',
	    'username', 'email', 'email2', 'password', 'avatar', 'gender', 'career', 'date_of_birth', 'age', 'post_code', 'city', 'district', 'address', 'address2',
	    'phone_number', 'fax_number', 'mobile_tel', 'emg_tel', 'introduction', 'reminder_question', 'reminder_answer', 'line_id', 'point', 'point_rate',
	    'driver_license', 'insurance_card', 'number_card', 'shipping_post_code', 'shipping_city', 'shipping_district', 'shipping_address', 'shipping_address2',
	    'height', 'sleeve', 'waist', 'bank_name', 'bank_code', 'bank_branch_name', 'bank_branch_code', 'bank_account_type', 'bank_account_number', 'bank_holder_name',
	    'reset_password_code', 'reset_password_time', 'email_verified_at', 'verify_code', 'verify_card', 'verify_created_at', 'email_subscribe', 'email_format', 'login_url',
	    'is_temp', 'is_activated', 'is_deleted', 'created_by', 'created_at', 'updated_at',
	    'payjp_customer_id',
	    // Identity verification fields
	    'identity_status', 'identity_submitted_at', 'identity_approved_at', 'identity_rejected_at',
	    'identity_rejection_count', 'identity_rejection_reason',
	    'driver_license_front', 'driver_license_back', 'my_number_card_front', 'identity_document_type',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    /**
     * Set permissions guard to API by default
     * @var string
     */
    protected $guard_name = 'api';

    /**
     * @inheritdoc
     */
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    /**
     * @inheritdoc
     */
    public function getJWTCustomClaims()
    {
        return [];
    }

    /**
     * Check if user has a permission
     * @param String
     * @return bool
     */
    public function hasPermission($permission): bool
    {
        foreach ($this->roles as $role) {
            if (in_array($permission, $role->permissions->toArray())) {
                return true;
            }
        }
        return false;
    }

    /**
     * @return bool
     */
    public function isAdmin(): bool
    {
        foreach ($this->roles as $role) {
            if ($role->isAdmin()) {
                return true;
            }
        }

        return false;
    }
	
	public function cards ()
	{
		return $this->hasMany(UserCard::class, 'user_id', 'id')
			->select('id', 'user_id', 'card_number', 'card_name', 'card_brand', 'card_brand_logo', 'card_exp_month', 'card_exp_year', 'card_last_four', 'is_default')
			->where('is_deleted', 0)
			->where('is_activated', 1)
			->orderBy('id');
	}
	
	public function types()
	{
		return $this->hasMany(UserType::class)
			->select('id', 'user_id', 'type')
			->orderBy('id');
	}

    /**
     * Get identity verification logs for this user
     */
    public function identityVerificationLogs()
    {
        return $this->hasMany(IdentityVerificationLog::class, 'user_id', 'id')
            ->orderBy('created_at', 'desc');
    }

    /**
     * Check if user's identity is verified
     *
     * @return bool
     */
    public function isIdentityVerified(): bool
    {
        return $this->identity_status === self::IDENTITY_STATUS_APPROVED;
    }

    /**
     * Check if user's identity verification is pending
     *
     * @return bool
     */
    public function isIdentityPending(): bool
    {
        return $this->identity_status === self::IDENTITY_STATUS_PENDING;
    }

    /**
     * Check if user's identity was rejected
     *
     * @return bool
     */
    public function isIdentityRejected(): bool
    {
        return $this->identity_status === self::IDENTITY_STATUS_REJECTED;
    }

    /**
     * Check if user needs to submit identity documents
     *
     * @return bool
     */
    public function needsIdentitySubmission(): bool
    {
        return $this->identity_status === self::IDENTITY_STATUS_NOT_SUBMITTED;
    }

    /**
     * Check if user can resubmit identity documents (max 1 resubmission allowed)
     *
     * @return bool
     */
    public function canResubmitIdentity(): bool
    {
        return $this->identity_status === self::IDENTITY_STATUS_REJECTED
            && $this->identity_rejection_count < 2;
    }

    /**
     * Get the document type label in Japanese
     *
     * @return string|null
     */
    public function getIdentityDocumentTypeLabel(): ?string
    {
        $labels = [
            self::IDENTITY_DOC_DRIVER_LICENSE => '運転免許証',
            self::IDENTITY_DOC_MY_NUMBER_CARD => 'マイナンバーカード',
        ];

        return $labels[$this->identity_document_type] ?? null;
    }

    /**
     * Get the identity status label in Japanese
     *
     * @return string
     */
    public function getIdentityStatusLabel(): string
    {
        $labels = [
            self::IDENTITY_STATUS_NOT_SUBMITTED => '未提出',
            self::IDENTITY_STATUS_PENDING => '審査中',
            self::IDENTITY_STATUS_APPROVED => '承認済み',
            self::IDENTITY_STATUS_REJECTED => '却下',
        ];

        return $labels[$this->identity_status] ?? '不明';
    }
}
