<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use App\Models\Batch\BatchLog;
use App\Models\SettlementTransaction;
use App\Services\ShjFourBService;

/**
 * SHJ-4B 決済トランザクション処理ジョブ
 * 
 * SHJ-4Aで登録された決済情報を基に定期契約の更新処理を行う
 */
class ProcessSettlementJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * ジョブの実行可能回数
     *
     * @var int
     */
    public $tries = 3;

    /**
     * ジョブの実行間隔（秒）
     *
     * @var array
     */
    public $backoff = [60, 300, 900];

    /**
     * 使用するキュー名
     *
     * @var string
     */
    public $queue = 'settlement';

    /**
     * 決済トランザクションID
     *
     * @var int
     */
    protected $settlementTransactionId;

    /**
     * 追加のコンテキスト情報
     *
     * @var array
     */
    protected $context;

    /**
     * コンストラクタ
     *
     * @param int $settlementTransactionId 決済トランザクションID
     * @param array $context 追加のコンテキスト情報
     */
    public function __construct(int $settlementTransactionId, array $context = [])
    {
        $this->settlementTransactionId = $settlementTransactionId;
        $this->context = $context;
    }

    /**
     * ジョブを実行
     * 
     * SHJ-4Bサービスを使用して決済トランザクション処理を実行
     *
     * @return void
     */
    public function handle()
    {
        $startTime = now();
        
        // バッチログの開始記録
        $batch = BatchLog::createBatchLog(
            'shj4b',
            BatchLog::STATUS_START,
            [
                'settlement_transaction_id' => $this->settlementTransactionId,
                'context' => $this->context,
                'job_id' => $this->job->getJobId(),
            ],
            'SHJ-4B ProcessSettlementJob start'
        );

        try {
            Log::info('SHJ-4B ProcessSettlementJob開始', [
                'settlement_transaction_id' => $this->settlementTransactionId,
                'context' => $this->context,
                'start_time' => $startTime,
            ]);

            // SHJ-4Bサービスを使用して決済トランザクション処理を実行
            $shjFourBService = app(ShjFourBService::class);
            $result = $shjFourBService->processSettlementTransaction(
                $this->settlementTransactionId,
                $this->context
            );

            // 処理結果に基づいてバッチログを更新
            if ($result['success']) {
                $batch->update([
                    'status' => BatchLog::STATUS_SUCCESS,
                    'end_time' => now(),
                    'message' => 'SHJ-4B ProcessSettlementJob completed successfully',
                    'success_count' => 1,
                    'parameters' => json_encode([
                        'result' => $result,
                    ]),
                ]);
                
                Log::info('SHJ-4B ProcessSettlementJob完了', [
                    'settlement_transaction_id' => $this->settlementTransactionId,
                    'execution_time' => now()->diffInSeconds($startTime),
                    'result' => $result,
                ]);
            } else {
                // ビジネスロジック上の問題（エラーではない）
                $batch->update([
                    'status' => BatchLog::STATUS_SUCCESS,
                    'end_time' => now(),
                    'message' => 'SHJ-4B ProcessSettlementJob completed with issues: ' . $result['reason'],
                    'success_count' => 0,
                    'parameters' => json_encode([
                        'result' => $result,
                        'requires_manual_action' => true,
                    ]),
                ]);
                
                Log::warning('SHJ-4B ProcessSettlementJob要手動対応', [
                    'settlement_transaction_id' => $this->settlementTransactionId,
                    'result' => $result,
                ]);
            }

        } catch (\Throwable $e) {
            Log::error('SHJ-4B ProcessSettlementJob失敗', [
                'settlement_transaction_id' => $this->settlementTransactionId,
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
            ]);

            // バッチログのエラー記録
            $batch->update([
                'status' => BatchLog::STATUS_ERROR,
                'end_time' => now(),
                'message' => 'SHJ-4B ProcessSettlementJob failed: ' . $e->getMessage(),
                'error_details' => $e->getTraceAsString(),
                'error_count' => 1,
            ]);

            // ジョブを失敗させて再試行を促す
            throw $e;
        }
    }

    /**
     * ジョブが失敗した場合の処理
     *
     * @param \Throwable $exception
     * @return void
     */
    public function failed(\Throwable $exception)
    {
        Log::error('SHJ-4B ProcessSettlementJob最終失敗', [
            'settlement_transaction_id' => $this->settlementTransactionId,
            'context' => $this->context,
            'error' => $exception->getMessage(),
            'attempts' => $this->attempts(),
        ]);

        // 最終失敗時の追加処理があればここに記述
        // 例：管理者への通知、障害キューへの登録など
    }
}
