<?php

namespace App\Console\Commands;

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

/**
 * SHJ-10 売上集計処理コマンド
 * 
 * 駐輪場の売上データを財政年度ベースで年次・月次集計する処理を実行する
 * 4月開始の財政年度期間で計算するバックグラウンドバッチ処理
 */
class ShjTenCommand extends Command
{
    /**
     * コンソールコマンドの名前とシグネチャ
     * 
     * 引数:
     * - type: 集計種別 (yearly/monthly) (必須)
     * - target: 集計対象 (必須)
     *   - yearly: 年度 (例: 2019)
     *   - monthly: 年月 (例: 2019/01)
     *
     * @var string
     */
    protected $signature = 'shj:10 {type : 集計種別(yearly/monthly)} {target : 集計対象(yearly:年度, monthly:年月)}';

    /**
     * コンソールコマンドの説明
     *
     * @var string
     */
    protected $description = 'SHJ-10 売上集計処理 - 財政年度ベース年次/月次売上データ集計を実行';

    /**
     * SHJ-10サービスクラス
     *
     * @var ShjTenService
     */
    protected $shjTenService;

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

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

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

            // 財政年度期間設定
            $fiscalPeriod = $this->determineFiscalPeriod($type, $target);
            
            $this->info("集計種別: {$type}");
            $this->info("集計対象: {$target}");
            $this->info("財政期間: {$fiscalPeriod['start_date']} ～ {$fiscalPeriod['end_date']}");

            // SHJ-10処理実行
            $result = $this->shjTenService->executeFiscalEarningsAggregation($type, $target, $fiscalPeriod);

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

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

                return self::FAILURE;
            }

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

            return self::FAILURE;
        }
    }

    /**
     * パラメータの妥当性を検証
     *
     * @param string $type 集計種別
     * @param string $target 集計対象
     * @return bool 検証結果
     */
    private function validateParameters(string $type, string $target): bool
    {
        // 集計種別チェック
        $allowedTypes = ['yearly', 'monthly'];
        if (!in_array($type, $allowedTypes)) {
            $this->error('集計種別は yearly, monthly のいずれかを指定してください。');
            return false;
        }

        // 集計対象形式チェック
        if ($type === 'yearly') {
            // 年度形式チェック (例: 2019)
            if (!preg_match('/^\d{4}$/', $target)) {
                $this->error('年次集計の場合、年度を4桁の数字で指定してください。(例: 2019)');
                return false;
            }
        } elseif ($type === 'monthly') {
            // 年月形式チェック (例: 2019/01)
            if (!preg_match('/^\d{4}\/\d{2}$/', $target)) {
                $this->error('月次集計の場合、年月をYYYY/MM形式で指定してください。(例: 2019/01)');
                return false;
            }
            
            // 月の範囲チェック (01-12)
            $parts = explode('/', $target);
            $month = (int)$parts[1];
            if ($month < 1 || $month > 12) {
                $this->error('月は01から12までの範囲で指定してください。');
                return false;
            }
        }

        return true;
    }

    /**
     * 財政年度期間を決定
     * 
     * 財政年度は4月開始（Config設定可能）
     * - yearly 2019: 2019年4月1日 ～ 2020年3月31日
     * - monthly 2019/01: 2019年1月1日 ～ 2019年1月31日
     * 
     * @param string $type 集計種別
     * @param string $target 集計対象
     * @return array 財政期間情報
     */
    private function determineFiscalPeriod(string $type, string $target): array
    {
        $fiscalStartMonth = 4; // 財政年度開始月（4月）

        if ($type === 'yearly') {
            $year = (int)$target;
            
            // 財政年度期間計算
            $startDate = sprintf('%04d-%02d-01', $year, $fiscalStartMonth);
            $endDate = sprintf('%04d-%02d-%02d', $year + 1, $fiscalStartMonth - 1, 
                date('t', strtotime(sprintf('%04d-%02d-01', $year + 1, $fiscalStartMonth - 1))));
            
            return [
                'type' => 'yearly',
                'fiscal_year' => $year,
                'start_date' => $startDate,
                'end_date' => $endDate,
                'summary_type' => 1, // 年次
                'target_label' => "{$year}年度"
            ];
            
        } elseif ($type === 'monthly') {
            $parts = explode('/', $target);
            $year = (int)$parts[0];
            $month = (int)$parts[1];
            
            // 指定月の期間計算
            $startDate = sprintf('%04d-%02d-01', $year, $month);
            $endDate = sprintf('%04d-%02d-%02d', $year, $month, 
                date('t', strtotime($startDate)));
            
            // 該当する財政年度を計算
            $fiscalYear = $month >= $fiscalStartMonth ? $year : $year - 1;
            
            return [
                'type' => 'monthly',
                'fiscal_year' => $fiscalYear,
                'target_year' => $year,
                'target_month' => $month,
                'start_date' => $startDate,
                'end_date' => $endDate,
                'summary_type' => 2, // 月次
                'target_label' => "{$year}年{$month}月"
            ];
        }

        throw new \InvalidArgumentException("不正な集計種別: {$type}");
    }
}
