<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class IdentityVerificationLog extends Model
{
	protected $table = 'identity_verification_logs';
	
	/**
	 * Action type constants
	 */
	const ACTION_SUBMITTED = 'submitted';
	const ACTION_APPROVED = 'approved';
	const ACTION_REJECTED = 'rejected';
	const ACTION_RESUBMITTED = 'resubmitted';
	const ACTION_AUTO_CANCELLED = 'auto_cancelled';
	const ACTION_DOCUMENT_UPDATED = 'document_updated';
	
	/**
	 * The attributes that are mass assignable.
	 *
	 * @var array
	 */
	protected $fillable = [
		'user_id',
		'order_id',
		'action',
		'status_before',
		'status_after',
		'document_type',
		'driver_license_front',
		'driver_license_back',
		'my_number_card_front',
		'admin_id',
		'admin_name',
		'rejection_reason',
		'rejection_count',
		'notes',
		'ip_address',
		'user_agent',
	];
	
	/**
	 * The attributes that should be cast to native types.
	 *
	 * @var array
	 */
	protected $casts = [
		'rejection_count' => 'integer',
		'created_at'      => 'datetime',
		'updated_at'      => 'datetime',
	];
	
	/**
	 * Get the user that owns this log
	 */
	public function user()
	{
		return $this->belongsTo(User::class, 'user_id', 'id');
	}
	
	/**
	 * Get the order associated with this log
	 */
	public function order()
	{
		return $this->belongsTo(Order::class, 'order_id', 'id');
	}
	
	/**
	 * Get the admin who performed the action
	 */
	public function admin()
	{
		return $this->belongsTo(User::class, 'admin_id', 'id');
	}
	
	/**
	 * Get action label in Japanese
	 *
	 * @return string
	 */
	public function getActionLabel(): string
	{
		$labels = [
			self::ACTION_SUBMITTED        => '本人確認書類提出',
			self::ACTION_APPROVED         => '承認',
			self::ACTION_REJECTED         => '却下',
			self::ACTION_RESUBMITTED      => '再提出',
			self::ACTION_AUTO_CANCELLED   => '自動キャンセル',
			self::ACTION_DOCUMENT_UPDATED => '書類更新',
		];
		
		return $labels[$this->action] ?? '不明';
	}
	
	/**
	 * Get status label in Japanese
	 *
	 * @param string|null $status
	 * @return string
	 */
	public static function getStatusLabel(?string $status): string
	{
		$labels = [
			User::IDENTITY_STATUS_NOT_SUBMITTED => '未提出',
			User::IDENTITY_STATUS_PENDING       => '審査中',
			User::IDENTITY_STATUS_APPROVED      => '承認済み',
			User::IDENTITY_STATUS_REJECTED      => '却下',
		];
		
		return $labels[$status] ?? '不明';
	}
	
	/**
	 * Get document type label in Japanese
	 *
	 * @return string|null
	 */
	public function getDocumentTypeLabel(): ?string
	{
		$labels = [
			User::IDENTITY_DOC_DRIVER_LICENSE => '運転免許証',
			User::IDENTITY_DOC_MY_NUMBER_CARD => 'マイナンバーカード',
		];
		
		return $labels[$this->document_type] ?? null;
	}
	
	/**
	 * Scope for logs by user
	 *
	 * @param \Illuminate\Database\Eloquent\Builder $query
	 * @param int $userId
	 * @return \Illuminate\Database\Eloquent\Builder
	 */
	public function scopeByUser($query, int $userId)
	{
		return $query->where('user_id', $userId);
	}
	
	/**
	 * Scope for logs by action
	 *
	 * @param \Illuminate\Database\Eloquent\Builder $query
	 * @param string $action
	 * @return \Illuminate\Database\Eloquent\Builder
	 */
	public function scopeByAction($query, string $action)
	{
		return $query->where('action', $action);
	}
	
	/**
	 * Scope for recent logs
	 *
	 * @param \Illuminate\Database\Eloquent\Builder $query
	 * @param int $days
	 * @return \Illuminate\Database\Eloquent\Builder
	 */
	public function scopeRecent($query, int $days = 30)
	{
		return $query->where('created_at', '>=', now()->subDays($days));
	}
	
	/**
	 * Create a log entry for submission
	 *
	 * @param User $user
	 * @param Order|null $order
	 * @param string $documentType
	 * @param array $documents
	 * @param string|null $ipAddress
	 * @param string|null $userAgent
	 * @return self
	 */
	public static function logSubmission(
		$user,
		?Order $order,
		string $documentType,
		array $documents,
		?string $ipAddress = null,
		?string $userAgent = null
	): self
	{
		return self::create([
			'user_id'              => $user->id,
			'order_id'             => $order ? $order->id : null,
			'action'               => self::ACTION_SUBMITTED,
			'status_before'        => User::IDENTITY_STATUS_NOT_SUBMITTED,
			'status_after'         => User::IDENTITY_STATUS_PENDING,
			'document_type'        => $documentType,
			'driver_license_front' => $documents['driver_license_front'] ?? null,
			'driver_license_back'  => $documents['driver_license_back'] ?? null,
			'my_number_card_front' => $documents['my_number_card_front'] ?? null,
			'rejection_count'      => 0,
			'ip_address'           => $ipAddress,
			'user_agent'           => $userAgent,
		]);
	}
	
	/**
	 * Create a log entry for approval
	 *
	 * @param User $user
	 * @param mixed $admin
	 * @param string|null $notes
	 * @return self
	 */
	public static function logApproval($user, $admin, ?string $notes = null): self
	{
		return self::create([
			'user_id'              => $user->id,
			'action'               => self::ACTION_APPROVED,
			'status_before'        => User::IDENTITY_STATUS_PENDING,
			'status_after'         => User::IDENTITY_STATUS_APPROVED,
			'document_type'        => $user->identity_document_type,
			'driver_license_front' => $user->driver_license_front,
			'driver_license_back'  => $user->driver_license_back,
			'my_number_card_front' => $user->my_number_card_front,
			'admin_id'             => $admin->id,
			'admin_name'           => $admin->name ?? $admin->username,
			'notes'                => $notes,
		]);
	}
	
	/**
	 * Create a log entry for rejection
	 *
	 * @param User $user
	 * @param mixed $admin
	 * @param string $reason
	 * @param string|null $notes
	 * @return self
	 */
	public static function logRejection($user, $admin, string $reason, ?string $notes = null): self
	{
		return self::create([
			'user_id'              => $user->id,
			'action'               => self::ACTION_REJECTED,
			'status_before'        => User::IDENTITY_STATUS_PENDING,
			'status_after'         => User::IDENTITY_STATUS_REJECTED,
			'document_type'        => $user->identity_document_type,
			'driver_license_front' => $user->driver_license_front,
			'driver_license_back'  => $user->driver_license_back,
			'my_number_card_front' => $user->my_number_card_front,
			'admin_id'             => $admin->id,
			'admin_name'           => $admin->name ?? $admin->username,
			'rejection_reason'     => $reason,
			'rejection_count'      => $user->identity_rejection_count,
			'notes'                => $notes,
		]);
	}
	
	/**
	 * Create a log entry for resubmission
	 *
	 * @param User $user
	 * @param Order|null $order
	 * @param string $documentType
	 * @param array $documents
	 * @param string|null $ipAddress
	 * @param string|null $userAgent
	 * @return self
	 */
	public static function logResubmission(
		$user,
		?Order $order,
		string $documentType,
		array $documents,
		?string $ipAddress = null,
		?string $userAgent = null
	): self
	{
		return self::create([
			'user_id'              => $user->id,
			'order_id'             => $order ? $order->id : null,
			'action'               => self::ACTION_RESUBMITTED,
			'status_before'        => User::IDENTITY_STATUS_REJECTED,
			'status_after'         => User::IDENTITY_STATUS_PENDING,
			'document_type'        => $documentType,
			'driver_license_front' => $documents['driver_license_front'] ?? null,
			'driver_license_back'  => $documents['driver_license_back'] ?? null,
			'my_number_card_front' => $documents['my_number_card_front'] ?? null,
			'rejection_count'      => $user->identity_rejection_count,
			'ip_address'           => $ipAddress,
			'user_agent'           => $userAgent,
		]);
	}
	
	/**
	 * Create a log entry for auto cancellation
	 *
	 * @param User $user
	 * @param Order $order
	 * @param string $reason
	 * @return self
	 */
	public static function logAutoCancellation($user, Order $order, string $reason): self
	{
		return self::create([
			'user_id'       => $user->id,
			'order_id'      => $order->id,
			'action'        => self::ACTION_AUTO_CANCELLED,
			'status_before' => $user->identity_status,
			'status_after'  => $user->identity_status,
			'document_type' => $user->identity_document_type,
			'notes'         => $reason,
		]);
	}
}
