<?php

namespace App\Mail;

use App\Laravue\Models\User;
use App\Mail\Traits\UsesEmailTemplate;
use App\Product;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Collection;

class IdentityVerificationApprovedWithOrders extends Mailable implements ShouldQueue
{
	use Queueable, SerializesModels, UsesEmailTemplate;

	public $user;
	public $orders;
	public $orderResults;

	public function __construct(User $user, Collection $orders, array $orderResults = [])
	{
		$this->user = $user;
		$this->orders = $orders;
		$this->orderResults = $orderResults;
		$this->onConnection(config('queue.default'));
		$this->onQueue(config('queue.connections.redis.queue'));

		$paymentDeadlineDays = (int) config('rental_dates.payment_deadline_days', 11);

		// 最初の着用日・決済期限を計算
		$firstOrder = $orders->first();
		$firstOrderDetail = $firstOrder ? $firstOrder->order_detail->first() : null;
		$firstWearingDate = '未定';
		$firstPaymentDeadline = '未定';

		if ($firstOrderDetail && $firstOrderDetail->wear_date) {
			$firstWearingDate = Carbon::parse($firstOrderDetail->wear_date)->format('Y/m/d');
			$firstPaymentDeadline = Carbon::parse($firstOrderDetail->wear_date)
				->subDays($paymentDeadlineDays)->format('Y/m/d');
		}

		$grandTotal = number_format($orders->sum('total_price'));

		// 動的HTML: 支払い案内
		$paymentInfoHtml = $this->buildPaymentInfoHtml($paymentDeadlineDays, $grandTotal, $firstPaymentDeadline);
		// 動的HTML: 注文一覧（注文内容のみ）
		$ordersDetailHtml = $this->buildOrdersDetailHtml($orders, $user, $paymentDeadlineDays);
		// 動的HTML: レンタルの流れ（確定パターン）
		$rentalFlowHtml = $this->buildRentalFlowConfirmedHtml($orders, $paymentDeadlineDays);

		// 支払方法に応じてテンプレートを分岐（0=クレカ, それ以外=銀行振込）
		// 複数注文で支払方法が混在する場合はクレカ用テンプレートを使用
		// （payment_info HTMLに両方の案内が含まれているため）
		$hasCredit = $orders->contains(fn($o) => $o->payment_method == 0);
		$templateSlug = $hasCredit ? 'u_identity_order_confirmed_credit' : 'u_identity_order_confirmed_bank';

		$this->loadTemplate($templateSlug, [
			'full_name'            => $user->full_name ?? $user->name,
			'first_name'           => $user->first_name,
			'last_name'            => $user->last_name,
			'email'                => $user->email,
			'first_wearing_date'   => $firstWearingDate,
			'first_payment_deadline' => $firstPaymentDeadline,
			'grand_total'          => $grandTotal,
			'payment_deadline_days' => (string) $paymentDeadlineDays,
			'payment_info'         => $paymentInfoHtml,
			'orders_detail'        => $ordersDetailHtml,
			'rental_flow'          => $rentalFlowHtml,
		]);
	}

	public function build()
	{
		return $this->buildFromTemplate();
	}

	protected function buildPaymentInfoHtml(int $paymentDeadlineDays, string $grandTotal, string $paymentDeadline): string
	{
		return '---------------------------------------------------------------------------------------------------------------------------<br>'
			. '【クレジットカード払い】<br>'
			. '<span style="margin-left: 14px;">ご注文時にご登録いただきましたクレジットカード宛てに</span><br>'
			. '<span style="margin-left: 14px;">ご着用予定日の【' . $paymentDeadlineDays . '日前】に当店より引き落としを行います。</span><br>'
			. '<span style="margin-left: 14px;">お支払いの手続きは必要ありません。</span><br><br>'
			. '【銀行振り込み】<br>'
			. '<span style="margin-left: 14px;">ご着用予定日の【' . $paymentDeadlineDays . '日前】までに下記口座にお振込みください。</span><br><br>'
			. '<span style="margin-left: 14px;">銀 行 名：楽天銀行</span><br>'
			. '<span style="margin-left: 14px;">支店番号：253 第三営業支店</span><br>'
			. '<span style="margin-left: 14px;">預金科目：普通預金</span><br>'
			. '<span style="margin-left: 14px;">口座番号：7489335</span><br>'
			. '<span style="margin-left: 14px;">口座名義：株式会社もろふじ キレイ</span><br><br>'
			. '<span style="margin-left: 14px;">ご請求金額：' . $grandTotal . '円</span><br>'
			. '<span style="margin-left: 14px;">お客様のお支払い期限は【 ' . $paymentDeadline . ' 】です。</span><br><br>'
			. '<span style="margin-left: 14px;">お支払期限の1週間前までにお支払の確認がとれていない場合</span><br>'
			. '<span style="margin-left: 14px;">当店より催促のご連絡をさせていただくことがあります。</span><br>'
			. '---------------------------------------------------------------------------------------------------------------------------';
	}

	protected function buildOrdersDetailHtml(Collection $orders, User $user, int $paymentDeadlineDays): string
	{
		$storeShippingDays = (int) config('rental_dates.store_shipping_days', 10);
		$productDeliveryDays = (int) config('rental_dates.product_delivery_days', 3);
		$returnAfterDays = (int) config('rental_dates.return_after_days', 2);
		$storeArrivalAfterReturnDays = (int) config('rental_dates.store_arrival_after_return_days', 1);
		$defaultRentalNights = (int) config('rental_dates.default_rental_nights', 5);
		$userName = $user->full_name ?? $user->name;
		$ordersCount = $orders->count();
		$html = '';

		foreach ($orders as $index => $order) {
			$orderDetail = $order->order_detail->first();
			$product = $orderDetail ? $orderDetail->product : null;

			$wearingDate = $orderDetail && $orderDetail->wear_date ? Carbon::parse($orderDetail->wear_date) : null;
			$wearingDateFormatted = $wearingDate ? $wearingDate->format('Y/m/d') : '未定';

			$rentalStartDate = $wearingDate ? $wearingDate->copy()->subDays($productDeliveryDays) : null;
			$rentalEndDate = $rentalStartDate ? $rentalStartDate->copy()->addDays($defaultRentalNights) : null;
			$rentalPeriod = ($rentalStartDate && $rentalEndDate) ? $rentalStartDate->format('Y/m/d') . ' ～ ' . $rentalEndDate->format('Y/m/d') : '未定';

			$storeShippingDate = $wearingDate ? $wearingDate->copy()->subDays($storeShippingDays)->format('Y/m/d') . ' 頃' : '未定';
			$deliveryDate = $wearingDate ? $wearingDate->copy()->subDays($productDeliveryDays)->format('Y/m/d') : '未定';
			$returnDate = $wearingDate ? $wearingDate->copy()->addDays($returnAfterDays)->format('Y/m/d') : '未定';
			$storeArrivalDate = $wearingDate ? $wearingDate->copy()->addDays($returnAfterDays + $storeArrivalAfterReturnDays)->format('Y/m/d') : '未定';

			$paymentMethodText = $order->payment_method == 0 ? 'クレジットカード' : '銀行振り込み';
			$productPrice = $orderDetail ? number_format($orderDetail->price ?? 0) : '0';
			$optionPrice = number_format($order->option_price ?? 0);
			$shippingCost = number_format($order->shipping_cost ?? 0);
			$totalPrice = number_format($order->total_price ?? 0);
			$productCode = '';
			if ($product && $product->code) {
				$productCode = $product->code;
			} elseif ($orderDetail && $orderDetail->product_id) {
				$productCode = Product::where('id', $orderDetail->product_id)->value('code') ?? '';
			}

			$countLabel = $ordersCount > 1 ? '<span style="color: #666;">(' . ($index + 1) . '/' . $ordersCount . '件)</span>' : '';

			$html .= '■ご注文内容 ' . $countLabel . '<br>'
				. '<span style="margin-left: 14px;">[受注番号] ' . e($order->code) . '</span><br>'
				. '<span style="margin-left: 14px;">[ご注文者] ' . e($userName) . ' 様</span><br><br>'
				. '<span style="margin-left: 14px;">[着用予定日] ' . $wearingDateFormatted . '</span><br>'
				. '<span style="margin-left: 14px;">[レンタル期間：' . $defaultRentalNights . '泊' . ($defaultRentalNights + 1) . '日] ' . $rentalPeriod . '</span><br><br>'
				. '<span style="margin-left: 14px;">[着物番号] ' . $productCode . '</span><br>'
				. '<span style="margin-left: 14px;">[決済方法] ' . $paymentMethodText . '</span><br>'
				. '<span style="margin-left: 14px;">[商品価格] ' . $productPrice . '円</span><br>'
				. '<span style="margin-left: 14px;">[オプション価格] ' . $optionPrice . '円</span><br>'
				. '<span style="margin-left: 14px;">[送料] ' . $shippingCost . '円</span><br>'
				. '<span style="margin-left: 14px;">[合計金額] ' . $totalPrice . '円</span><br><br>'
				. '<span style="margin-left: 20px;">ご注文内容に誤りがございましたら、お手数ですがお問い合わせください。</span><br><br>';

			if ($index < $ordersCount - 1) {
				$html .= '---------------------------------------------------------------------------------------------------------------------------<br><br>';
			}
		}

		return $html;
	}

	protected function buildRentalFlowConfirmedHtml(Collection $orders, int $paymentDeadlineDays): string
	{
		$storeShippingDays = (int) config('rental_dates.store_shipping_days', 10);
		$productDeliveryDays = (int) config('rental_dates.product_delivery_days', 3);
		$returnAfterDays = (int) config('rental_dates.return_after_days', 2);
		$storeArrivalAfterReturnDays = (int) config('rental_dates.store_arrival_after_return_days', 1);

		$firstOrder = $orders->first();
		$orderDetail = $firstOrder ? $firstOrder->order_detail->first() : null;
		$wearingDate = $orderDetail && $orderDetail->wear_date ? Carbon::parse($orderDetail->wear_date) : null;

		$storeShippingDate = $wearingDate ? $wearingDate->copy()->subDays($storeShippingDays)->format('Y/m/d') . ' 頃' : '未定';
		$deliveryDate = $wearingDate ? $wearingDate->copy()->subDays($productDeliveryDays)->format('Y/m/d') : '未定';
		$wearingDateFormatted = $wearingDate ? $wearingDate->format('Y/m/d') : '未定';
		$returnDate = $wearingDate ? $wearingDate->copy()->addDays($returnAfterDays)->format('Y/m/d') : '未定';
		$storeArrivalDate = $wearingDate ? $wearingDate->copy()->addDays($returnAfterDays + $storeArrivalAfterReturnDays)->format('Y/m/d') : '未定';

		return '■レンタルの流れ（現在のステータス：【ご注文確定】）<br>'
			. '<span style="margin-left: 14px;">ご注文確認</span><br>'
			. '<span style="margin-left: 35px;">▼</span><br>'
			. '<span style="margin-left: 14px;">【 ご注文確定 】</span><br>'
			. '<span style="margin-left: 35px;">▼</span><br>'
			. '<span style="margin-left: 14px;">お支払い</span><br>'
			. '<span style="margin-left: 35px;">▼</span><br>'
			. '<span style="margin-left: 14px;">当店発送予定日：' . $storeShippingDate . '</span><br>'
			. '<span style="margin-left: 35px;">▼</span><br>'
			. '<span style="margin-left: 14px;">着物到着日：' . $deliveryDate . '</span><br>'
			. '<span style="margin-left: 35px;">▼</span><br>'
			. '<span style="margin-left: 14px;">ご着用予定日：' . $wearingDateFormatted . '</span><br>'
			. '<span style="margin-left: 35px;">▼</span><br>'
			. '<span style="margin-left: 14px;">返却期日：' . $returnDate . '</span><br>'
			. '<span style="margin-left: 35px;">▼</span><br>'
			. '<span style="margin-left: 14px;">当店到着予定日：' . $storeArrivalDate . '</span><br>'
			. '<span style="margin-left: 35px;">▼</span><br>'
			. '<span style="margin-left: 14px;">お取引完了</span>';
	}
}
