<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use App\Services\ShjNineService;

/**
 * SHJ-9 売上集計処理コマンド
 * 
 * 駐輪場の売上データを日次で集計する処理を実行する
 * バックグラウンドで実行される定期バッチ処理
 */
class ShjNineCommand extends Command
{
    /**
     * コンソールコマンドの名前とシグネチャ
     * 
     * 引数:
     * - type: 集計種別 (daily のみ) (必須)
     * - target_date: 集計対象日 (オプション、YYYY-MM-DD形式)
     *
     * @var string
     */
    protected $signature = 'shj:9 {type : 集計種別(daily)} {target_date? : 集計対象日(YYYY-MM-DD)}';

    /**
     * コンソールコマンドの説明
     *
     * @var string
     */
    protected $description = 'SHJ-9 売上集計処理 - 日次売上データ集計を実行';

    /**
     * SHJ-9サービスクラス
     *
     * @var ShjNineService
     */
    protected $shjNineService;

    /**
     * コンストラクタ
     *
     * @param ShjNineService $shjNineService
     */
    public function __construct(ShjNineService $shjNineService)
    {
        parent::__construct();
        $this->shjNineService = $shjNineService;
    }

    /**
     * コンソールコマンドを実行
     * 
     * 処理フロー:
     * 1. パラメータ取得と検証
     * 2. 集計対象日設定
     * 3. 売上集計処理実行
     * 4. バッチログ作成
     * 5. 処理結果返却
     *
     * @return int
     */
    public function handle()
    {
        try {
            // 開始ログ出力
            $startTime = now();
            $this->info('SHJ-9 売上集計処理を開始します。');
            
            // 引数取得
            $type = $this->argument('type');
            $targetDate = $this->argument('target_date');
            
            Log::info('SHJ-9 売上集計処理開始', [
                'start_time' => $startTime,
                'type' => $type,
                'target_date' => $targetDate
            ]);

            // パラメータ検証
            if (!$this->validateParameters($type, $targetDate)) {
                $this->error('パラメータが不正です。');
                return self::FAILURE;
            }

            // 集計対象日設定
            $aggregationDate = $this->determineAggregationDate($type, $targetDate);
            
            $this->info("集計種別: {$type}");
            $this->info("集計対象日: {$aggregationDate}");

            // SHJ-9処理実行
            $result = $this->shjNineService->executeEarningsAggregation($type, $aggregationDate);

            // 処理結果確認
            if ($result['success']) {
                $endTime = now();
                $this->info('SHJ-9 売上集計処理が正常に完了しました。');
                $this->info("処理時間: {$startTime->diffInSeconds($endTime)}秒");
                $this->info("処理結果: 駐輪場数 {$result['processed_parks']}, 集計レコード数 {$result['summary_records']}");
                
                Log::info('SHJ-9 売上集計処理完了', [
                    'end_time' => $endTime,
                    'duration_seconds' => $startTime->diffInSeconds($endTime),
                    'result' => $result
                ]);

                return self::SUCCESS;
            } else {
                $this->error('SHJ-9 売上集計処理でエラーが発生しました: ' . $result['message']);
                Log::error('SHJ-9 売上集計処理エラー', [
                    'error' => $result['message'],
                    'details' => $result['details'] ?? null
                ]);

                return self::FAILURE;
            }

        } catch (\Exception $e) {
            $this->error('SHJ-9 売上集計処理で予期しないエラーが発生しました: ' . $e->getMessage());
            Log::error('SHJ-9 売上集計処理例外エラー', [
                'exception' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);

            return self::FAILURE;
        }
    }

    /**
     * パラメータの妥当性を検証
     *
     * @param string $type 集計種別
     * @param string|null $targetDate 対象日
     * @return bool 検証結果
     */
    private function validateParameters(string $type, ?string $targetDate): bool
    {
        // 集計種別チェック（SHJ-9 は日次のみ対応）
        if ($type !== 'daily') {
            $this->error('SHJ-9 は日次集計（daily）のみ対応しています。月次/年次は SHJ-10 を使用してください。');
            return false;
        }

        // 対象日形式チェック（指定されている場合）
        if ($targetDate && !$this->isValidDateFormat($targetDate)) {
            $this->error('対象日の形式が正しくありません（YYYY-MM-DD形式で指定してください）。');
            return false;
        }

        return true;
    }

    /**
     * 集計対象日を決定
     * 
     * @param string $type 集計種別（daily 固定）
     * @param string|null $targetDate 指定日
     * @return string 集計対象日
     */
    private function determineAggregationDate(string $type, ?string $targetDate): string
    {
        if ($targetDate) {
            return $targetDate;
        }

        // パラメータ指定がない場合は昨日（本日の1日前）
        return now()->subDay()->format('Y-m-d');
    }

    /**
     * 日付形式の検証
     *
     * @param string $date 日付文字列
     * @return bool 有効な日付形式かどうか
     */
    private function isValidDateFormat(string $date): bool
    {
        // YYYY-MM-DD形式の正規表現チェック
        if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) {
            return false;
        }

        // 実際の日付として有効かチェック
        $dateParts = explode('-', $date);
        return checkdate((int)$dateParts[1], (int)$dateParts[2], (int)$dateParts[0]);
    }
}
