<?php

namespace App\Console\Commands;

use App\StorageContract;
use App\Traits\SendsTemplateEmail;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;

class NotifyStorageRenewalCommand extends Command
{
    use SendsTemplateEmail;

    protected $signature = 'storage:notify-renewal
                            {--dry-run : 実行せずに対象を表示}';

    protected $description = '保管料更新1ヶ月前の案内メールを送信する';

    public function handle()
    {
        $dryRun = $this->option('dry-run');

        $this->info('保管料更新案内メール送信' . ($dryRun ? ' [DRY-RUN]' : ''));

        // 更新1ヶ月前で未通知の契約を取得
        $contracts = StorageContract::dueForRenewalNotice()
            ->with(['user', 'product'])
            ->get();

        if ($contracts->isEmpty()) {
            $this->info('通知対象の契約はありません。');
            return 0;
        }

        $this->info("通知対象: {$contracts->count()}件");

        if ($dryRun) {
            foreach ($contracts as $contract) {
                $userName = $contract->user->full_name ?? $contract->user->name ?? 'ID:' . $contract->user_id;
                $this->line("  [DRY-RUN] 契約ID:{$contract->id} ユーザー:{$userName} 次回更新日:{$contract->next_renewal_date->format('Y-m-d')}");
            }
            return 0;
        }

        // ユーザーごとにグループ化してメール統合
        $groupedByUser = $contracts->groupBy('user_id');
        $successCount = 0;
        $failCount = 0;
        $emailCount = 0;

        foreach ($groupedByUser as $userId => $userContracts) {
            try {
                $firstContract = $userContracts->first();
                $user = $firstContract->user;

                if ($userContracts->count() === 1) {
                    // 1件: 通常メール
                    $this->sendTemplateEmail('email_storage_renewal_notice', $user->email, [
                        'user_name' => $user->full_name ?? $user->name,
                        'product_name' => $firstContract->product->name ?? '',
                        'amount' => number_format($firstContract->amount),
                        'next_renewal_date' => $firstContract->next_renewal_date->format('Y年m月d日'),
                        'cancel_deadline' => $firstContract->next_renewal_date->copy()->subWeeks(2)->format('Y年m月d日'),
                    ]);
                } else {
                    // 複数件: まとめメール
                    $productLines = [];
                    $totalAmount = 0;
                    foreach ($userContracts as $c) {
                        $productLines[] = "・" . ($c->product->name ?? '商品ID:' . $c->product_id) . "（¥" . number_format($c->amount) . "）";
                        $totalAmount += $c->amount;
                    }

                    $this->sendTemplateEmail('email_storage_renewal_notice', $user->email, [
                        'user_name' => $user->full_name ?? $user->name,
                        'product_name' => implode("\n", $productLines),
                        'amount' => number_format($totalAmount) . "（" . $userContracts->count() . "セット分）",
                        'next_renewal_date' => $firstContract->next_renewal_date->format('Y年m月d日'),
                        'cancel_deadline' => $firstContract->next_renewal_date->copy()->subWeeks(2)->format('Y年m月d日'),
                    ]);
                }

                // 全契約を通知済みに更新
                foreach ($userContracts as $contract) {
                    $contract->update(['renewal_notified_at' => now()]);
                    $successCount++;
                    $this->line("  [OK] 契約ID:{$contract->id}");
                }
                $emailCount++;

            } catch (\Exception $e) {
                foreach ($userContracts as $contract) {
                    $failCount++;
                    $this->error("  [NG] 契約ID:{$contract->id} エラー:{$e->getMessage()}");
                }
                Log::error("storage:notify-renewal 送信失敗 user_id={$userId}, error={$e->getMessage()}");
            }
        }

        $this->info("完了: 契約={$successCount}件成功/{$failCount}件失敗, メール={$emailCount}通送信");

        return $failCount > 0 ? 1 : 0;
    }
}
