<?php

namespace App\Http\Controllers;

use App\Product;
use App\User;
use App\UserCard;
use App\UserPaymentHistory;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\DeliveryAddress;
use App\Order;
use App\OrderDetail;
use App\Payment;
use App\ProductDetail;
use App\ShippingCost;
use App\Events\NotifyEvent;
use App\Notify;
use Validator;
//Payment by PayJP
use Payjp\Charge;
use Payjp\Payjp;
use Payjp\Util;
use Cart;
use Mail;
use function PHPUnit\Framework\logicalOr;


class CartController extends Controller
{
	const ITEM_PER_PAGE = 25;
	
	public function index()
	{
		$cartContentItems = Cart::getContent();
		$cartTotalAmount = Cart::getTotal();
		$totalShipping = 10000;
		
		$cartCollection = $cartContentItems->sortBy(function ($product, $key) {
			return $product->attributes->created_at;
		});
		
		$list = [];
		foreach ($cartCollection as $item) {
			$list[] = $item;
			//$totalShipping += 16500;
		}
		
		return response()->json([
			'status'         => 'success',
			'data'           => $list,
			'total'          => $cartCollection->count(),
			'total_amount'   => $cartTotalAmount + $totalShipping,
			'total_shipping' => $totalShipping,
		], 200);
	}
	
	public function statistic()
	{
		//$cartTotal = Cart::getTotalQuantity();
		//Cart::clear();
		
		$cartCollection = Cart::getContent();
		$cartTotal = $cartCollection->count();
		
		return response()->json(['status' => 'success', 'data' => ['total' => $cartTotal]], 200);
	}
	
	public function show($id = 0)
	{
		$item = Cart::get($id);
		
		return response()->json(['status' => 'success', 'data' => $item], 200);
	}
	
	public function store(Request $request)
	{
		$validator = Validator::make($request->all(), [
			'id'   => ['required'],
			'date' => ['required'],
			/*'height'    => [ 'required' ],
			'hip'       => [ 'required' ],
			'tabi'      => [ 'required' ],
			'towel'     => [ 'required' ],
			'safe_pack' => [ 'required' ],
			'package'   => [ 'required' ],*/
		]);
		
		if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
		$params = $request->all();
		
		$product = Product::with('category', 'color_detail', 'schedule', 'user')
			->isPublished()
			->where('type', '!=', 0)
			->where('id', $params['id'])
			->first();
		
		if (!$product) return response()->json(['status' => 'error', 'errors' => __('messages.product_not_found')], 200);
		
		$cartId = md5($product->id . "_" . $params['package'] . "_" . str_replace("-", "_", str_replace("/", "_", $params['date'])));
		$cItem = Cart::get($cartId);
		
		if (!isset($cItem) || $cItem == null) {
			$package = 0; //$params['package'];
			$productName = $product->name . ' No.CA-' . $product->id . '-' . __('product.size.size_' . $product->size);
			$productOriginPrice = ($params['package'] == 0) ? $product->default_price : $product->regular_price_from;
			$safe_pack = 0; //($package == 0 && $params['safe_pack'] == 1) ? 1100 : 0;
			$tabi = 0; //($package == 0 && $params['tabi'] == 1) ? 660 : 0;
			$towel = 0; //($package == 0 && $params['towel'] == 1) ? 264 : 0;
			$productTax = $productOriginPrice * (10 / 100);
			$productPrice = $productOriginPrice + $productTax;
			$productPrice += $safe_pack + $tabi + $towel;
			
			$shippingDate = $params['date'];
			if ($package == 0) {
				$shippingDate = Carbon::parse($params['date'])->subDays(2);
				$shippingDate = $shippingDate->format('Y-m-d');
			}
			
			$cartData = [
				'id'         => $cartId,
				'name'       => $productName,
				'price'      => $productPrice,
				'quantity'   => 1,
				'attributes' => [
					'id'              => $product->id,
					'name'            => $product->name,
					'type'            => $product->type,
					'package'         => $package,
					'image'           => $product->image,
					'origin_price'    => $productOriginPrice,
					'tax'             => $productTax,
					'price'           => $productOriginPrice + $productTax,
					'shipping_date'   => $shippingDate,
					'wear_date'       => $params['date'],
					'height'          => null, //$params['height'],
					'hip'             => null, //$params['hip'],
					'foot'            => null, //isset($params['foot']) ? $params['foot'] : null,
					'charged_options' => [
						'safe_pack' => ['value' => $params['safe_pack'], 'price' => $safe_pack, 'origin_price' => 1000],
						'tabi'      => ['value' => $params['tabi'], 'price' => $tabi, 'origin_price' => 600],
						'towel'     => ['value' => $params['towel'], 'price' => $towel, 'origin_price' => 240],
					],
					'free_options'    => [
						['name' => '帯枕', 'value' => '変更しない'],
						['name' => 'マジックベルト', 'value' => '変更しない'],
						['name' => '三連紐', 'value' => '追加しない'],
					],
					'created_at'      => date('YmdHis'),
				]
			];
			Cart::add($cartData);
			
			return response()->json(['status' => 'success', 'message' => ''], 200);
		} else {
			/*Cart::update($product->id, [ 'quantity' => 1 ]);*/
			
			return response()->json(['status' => 'error', 'message' => __('messages.product_already_ordered')], 200);
		}
	}
	
	public function update(Request $request, $id)
	{
		//{ type: type, value: val }
		$validator = Validator::make($request->all(), [
			'type'  => ['required'],
			'value' => ['required']
		]);
		if ($validator->fails()) return response()->json(['status' => 'error', 'message' => __('messages.product_not_found')], 200);
		
		$cItem = Cart::get($id);
		
		if ($cItem) {
			$params = $request->all();
			$product = Product::with('category', 'color_detail', 'schedule', 'user')
				->isPublished()
				->where('type', '!=', 0)
				->where('id', $cItem->attributes->id)
				->first();
			
			if (!$product) return response()->json(['status' => 'error', 'message' => __('messages.product_not_found')], 200);
			
			$package = $cItem->attributes->package;
			$shipping_date = $cItem->attributes->shipping_date;
			$wear_date = $cItem->attributes->wear_date;
			$height = $cItem->attributes->height;
			$hip = $cItem->attributes->hip;
			$foot = $cItem->attributes->foot;
			$created_at = $cItem->attributes->created_at;
			$safe_pack = $cItem->attributes->charged_options['safe_pack']['value'];
			$tabi = $cItem->attributes->charged_options['tabi']['value'];
			$towel = $cItem->attributes->charged_options['towel']['value'];
			
			if ($params['type'] == 'safe_pack') {
				$safe_pack = ($params['value'] == 1 || $params['value'] == '1') ? 1 : 0;
			} elseif ($params['type'] == 'tabi') {
				$tabi = ($params['value'] == 1 || $params['value'] == '1') ? 1 : 0;
			} elseif ($params['type'] == 'towel') {
				$towel = ($params['value'] == 1 || $params['value'] == '1') ? 1 : 0;
			}
			$safe_pack_price = ($safe_pack == 1) ? 1100 : 0;
			$tabi_price = ($tabi == 1) ? 660 : 0;
			$towel_price = ($towel == 1) ? 264 : 0;
			
			$productOriginPrice = ($package == 0) ? $product->default_price : $product->regular_price_from;
			$productTax = $productOriginPrice * (10 / 100);
			$productPrice = $productOriginPrice + $productTax;
			$productPrice += $safe_pack_price + $tabi_price + $towel_price;
			
			$cartData = [
				'price'      => $productPrice,
				'attributes' => [
					'id'              => $product->id,
					'name'            => $product->name,
					'type'            => $product->type,
					'package'         => $package,
					'image'           => $product->image,
					'origin_price'    => $productOriginPrice,
					'tax'             => $productTax,
					'price'           => $productOriginPrice + $productTax,
					'shipping_date'   => $shipping_date,
					'wear_date'       => $wear_date,
					'height'          => $height,
					'hip'             => $hip,
					'foot'            => $foot,
					'charged_options' => [
						'safe_pack' => ['value' => $safe_pack, 'price' => $safe_pack_price, 'origin_price' => 1000],
						'tabi'      => ['value' => $tabi, 'price' => $tabi_price, 'origin_price' => 600],
						'towel'     => ['value' => $towel, 'price' => $towel_price, 'origin_price' => 240],
					],
					'free_options'    => [
						['name' => '帯枕', 'value' => '変更しない'],
						['name' => 'マジックベルト', 'value' => '変更しない'],
						['name' => '三連紐', 'value' => '追加しない'],
					],
					'created_at'      => $created_at
				],
				//'quantity' => [ 'relative' => false, 'value'    => $quantity ],
			];
			
			Cart::update($id, $cartData);
			
			return response()->json(['status' => 'success', 'message' => '', 'data' => $cartData], 200);
		} else {
			return response()->json(['status' => 'error', 'message' => __('messages.product_not_found')], 200);
		}
	}
	
	public function updateQuantity(Request $request, $id) {
		$validator = Validator::make($request->all(), [
			'quantity'  => ['required'],
		]);
		if ($validator->fails()) return response()->json(['status' => 'error', 'message' => __('messages.product_not_found')], 200);
		$params = $request->all();
		
		$cItem = Cart::get($id);
		if (isset($cItem) && $cItem != null) {
			Cart::update($id, [
				'quantity' => [
					'relative' => false,
					'value'    => ($params['quantity'] > 0) ? $params['quantity'] : 1
				],
			]);
		}
		
		return response()->json(['status' => 'success', 'message' => ''], 200);
	}
	
	public function order(Request $request)
	{
		$validator = Validator::make($request->all(), [
			'payment_method' => ['required'],
		]);
		if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
		
		$params = $request->all();
		$cartTotalAmount = Cart::getTotal();
		if ($cartTotalAmount <= 0) return response()->json(['status' => 'error', 'code' => null], 200);
		
		do {
			$orderCode = rand(111, 999) . rand(000, 999) . rand(000, 999);
			$checkOrder = Order::where(['code' => $orderCode])->first();
		} while (isset($checkOrder));
		
		$userId = auth('api')->user()->id;
		$user = User::where('id', $userId)->first();
		
		$paymentResult = null;
		$paymentCustomer = null;
		//Payment with Visa
		if ($params['payment_method'] == 0 || $params['payment_method'] == "0") {
			$paymentEmail = $user->email;
			$paymentName = $user->full_name;
			$line = "〒" . $user->post_code . " " . $user->city . " " . $user->district . " " . $user->address . " " . $user->address2;
			$postCode = $user->post_code;
			$city = $user->address . " " . $user->address2;
			
			$stripeToken = null; //$params['payment']['token']['id'];
			Stripe::setApiKey(config('stripe.stripe_secret'));
			$paymentCustomer = Customer::create([
				"address" => [
					"line1"       => $line,
					"postal_code" => $postCode,
					"city"        => $city,
					"state"       => "JP",
					"country"     => "JP",
				],
				"email"   => $paymentEmail,
				"name"    => $paymentName,
				"source"  => $stripeToken
			]);
			
			$paymentResult = Charge::create([
				"amount"      => $cartTotalAmount,
				"currency"    => "jpy",
				"customer"    => $paymentCustomer->id,
				"description" => "KIREIでオーダーインボイス番号#" . $orderCode . "の支払い。",
				"shipping"    => [
					"name"    => $paymentName,
					"address" => [
						"line1"       => $line,
						"postal_code" => $postCode,
						"city"        => $city,
						"state"       => "JP",
						"country"     => "JP",
					],
				]
			]);
			
			/*logger("customer: " . $paymentCustomer);
			logger("rs payment: " . $paymentResult);
			logger("payment: " . json_encode($params['payment']));*/
		}
		
		$paymentStatus = ($params['payment_method'] == 0 && ($paymentResult != null)) ? 1 : 0;

		// Check user identity verification status
		// Status 9: Identity Verification Pending (本人確認待ち)
		$isProvisional = ($user->identity_status !== 'approved');
		$orderStatus = $isProvisional ? Order::STATUS_PROVISIONAL : Order::STATUS_NEW;

		//Order
		$orderData = [
			'code'           => $orderCode,
			'type'           => "user",
			'user_id'        => $userId,
			'total_price'    => $cartTotalAmount,
			'note'           => $params['note'],
			'payment_method' => in_array($params['payment_method'], [0, 1, 2, 3]) ? $params['payment_method'] : 3,
			'payment_status' => $paymentStatus,
			'status'         => $orderStatus, //0: New order and wait confirm, 9: Identity Verification Pending
			'created_at'     => date('Y-m-d H:i:s'),
			'updated_at'     => date('Y-m-d H:i:s'),
		];

		// Set provisional order fields if identity not approved
		if ($isProvisional) {
			$orderData['provisional_created_at'] = now();
			$orderData['provisional_expires_at'] = now()->addDays(3);
			$orderData['identity_verification_required'] = true;
		}

		$order = Order::create($orderData);
		
		//Order Detail
		$cartCollection = Cart::getContent();
		foreach ($cartCollection as $item) {
			$product = Product::where('id', $item['attributes']['id'])->first();
			
			$freeOptions = "";
			foreach ($item['attributes']['free_options'] as $optItem) {
				$freeOptions .= ($freeOptions != "") ? "|" . $optItem['name'] : $optItem['name'];
			}
			
			OrderDetail::create([
				'order_id'      => $order->id,
				'product_id'    => $item['attributes']['id'],
				'product_name'  => $item['name'],
				'product_image' => $item['attributes']['image'],
				'product_type'  => $item['attributes']['type'], //add
				'order_method'  => $item['attributes']['package'],
				'catalog_price' => $item['attributes']['origin_price'],
				'discount'      => $product->discount,
				'price'         => $item['attributes']['price'],
				'tax'           => $item['attributes']['tax'], //add
				'shipping_cost' => 0,
				'shipping_date' => $item['attributes']['shipping_date'], //add
				'wear_date'     => $item['attributes']['wear_date'], //add
				'height'        => $item['attributes']['height'], //add
				'hip'           => $item['attributes']['hip'], //add
				'foot'          => $item['attributes']['foot'], //add
				'safe_pack'     => $item['attributes']['charged_options']['safe_pack']['price'], //add
				'tabi'          => $item['attributes']['charged_options']['tabi']['price'], //add
				'towel'         => $item['attributes']['charged_options']['towel']['price'], //add
				'free_options'  => $freeOptions, //add
				'quantity'      => $item['quantity'],
				'total_price'   => $item['price'],
				'created_at'    => date('Y-m-d H:i:s'),
				'updated_at'    => date('Y-m-d H:i:s'),
			]);
		}
		
		//DeliveryAddress
		DeliveryAddress::create([
			'order_id'            => $order->id,
			'first_name'          => $user->full_name,
			'last_name'           => $user->full_name,
			'furigana_first_name' => $user->furigana_name,
			'furigana_last_name'  => $user->furigana_name,
			'post_code'           => $user->post_code,
			'city'                => $user->city,
			'district'            => $user->district,
			'address'             => $user->address . $user->address2,
			'phone_number'        => $user->phone_number,
			'email'               => $user->email,
			'user_id'             => $userId,
			'is_default'          => 0,
			'created_at'          => date('Y-m-d H:i:s'),
			'updated_at'          => date('Y-m-d H:i:s'),
		]);
		
		//Payment
		$payment = null;
		if ($params['payment_method'] == 0 && $paymentResult != null) {
			$paymentResultJs = json_encode($paymentResult);
			$paymentResultArr = json_decode($paymentResultJs, true);
			
			$payment = Payment::create([
				'order_id'               => $order->id,
				'code'                   => $paymentResultArr['id'],
				'total'                  => $paymentResultArr['amount'],
				'amount_captured'        => $paymentResultArr['amount_captured'],
				'amount_refunded'        => $paymentResultArr['amount_refunded'],
				'application_fee'        => $paymentResultArr['application_fee'],
				'application_fee_amount' => $paymentResultArr['application_fee_amount'],
				'currency'               => $paymentResultArr['currency'],
				'type'                   => $paymentResultArr['payment_method_details']['type'],
				'provider'               => $paymentResultArr['balance_transaction'],
				'customer'               => $paymentResultArr['customer'],
				'payment_method'         => $paymentResultArr['payment_method'],
				'brand'                  => isset($paymentResultArr['payment_method_details']['card']) ? $paymentResultArr['payment_method_details']['card']['brand'] : '',
				'funding'                => isset($paymentResultArr['payment_method_details']['card']) ? $paymentResultArr['payment_method_details']['card']['funding'] : '',
				'network'                => isset($paymentResultArr['payment_method_details']['card']) ? $paymentResultArr['payment_method_details']['card']['network'] : '',
				'country'                => isset($paymentResultArr['payment_method_details']['card']) ? $paymentResultArr['payment_method_details']['card']['country'] : '',
				'last4'                  => isset($paymentResultArr['payment_method_details']['card']) ? $paymentResultArr['payment_method_details']['card']['last4'] : '',
				'exp_month'              => isset($paymentResultArr['payment_method_details']['card']) ? $paymentResultArr['payment_method_details']['card']['exp_month'] : '',
				'exp_year'               => isset($paymentResultArr['payment_method_details']['card']) ? $paymentResultArr['payment_method_details']['card']['exp_year'] : '',
				'failure_code'           => $paymentResultArr['failure_code'],
				'failure_message'        => $paymentResultArr['failure_message'],
				'content'                => json_encode($paymentResult),
				'customer_info'          => json_encode($paymentCustomer),
				/*'error_content'          => $paymentResultArr['amount_refunded'],*/
				'finished_at'            => date('Y-m-d H:i:s', $paymentResultArr['created']),
				'status'                 => ($paymentResultArr['paid'] && $paymentResultArr['status'] == "succeeded") ? 1 : 0,
				'created_at'             => date('Y-m-d H:i:s'),
				'updated_at'             => date('Y-m-d H:i:s'),
			]);
		}
		
		// Prepare email data from cart BEFORE clearing
		// Get product info from order details (already created from cart)
		$orderDetails = OrderDetail::where('order_id', $order->id)->get();
		$productCodes = [];
		$productPrices = [];
		$optionPrices = [];
		$shippingCosts = [];
		$wearDates = [];
		$rentalPeriods = [];

		foreach ($orderDetails as $detail) {
			$productCodes[] = $detail->product_name;
			$productPrices[] = $detail->price;
			$optionPrices[] = ($detail->safe_pack ?? 0) + ($detail->tabi ?? 0) + ($detail->towel ?? 0);
			$shippingCosts[] = $detail->shipping_cost ?? 0;

			// Format wear date
			if ($detail->wear_date) {
				$wearDateFormatted = date('Y/m/d', strtotime($detail->wear_date));
				$wearDates[] = $wearDateFormatted;

				// Calculate rental period (5 nights 6 days: arrival 2 days before wear date, return 3 days after)
				$arrivalDate = date('Y/m/d', strtotime($detail->wear_date . ' -2 days'));
				$returnDate = date('Y/m/d', strtotime($detail->wear_date . ' +3 days'));
				$rentalPeriods[] = $arrivalDate . ' ～ ' . $returnDate;
			}
		}

		//Clear Cart
		Cart::clear();

		//Send Email
		$data = $params;
		$data['site'] = url("/");
		$data['code'] = $orderCode;
		$data['total_amount'] = number_format($cartTotalAmount) . "円";

		// Payment method mapping
		$paymentMethodMap = [
			0 => 'クレジットカード',
			1 => '後払い',
			2 => '銀行振込',
			3 => '代金引換'
		];
		$data['payment_method'] = $paymentMethodMap[$params['payment_method']] ?? '前払い';
		$data['payment_status'] = ($params['payment_method'] == 0 && $payment != null && $payment->status == 1) ? "有料" : "未払い";
		$data['note'] = $params['note'];
		$data['name'] = $user->full_name;
		$data['furigana'] = $user->furigana_name;
		$data['address'] = "〒" . $user->post_code . " " . $user->city . " " . $user->district . " " . $user->address . " " . $user->address2;
		$data['phone_number'] = $user->phone_number;
		$data['email'] = $user->email;

		// Additional data for provisional order email template
		$data['product_code'] = implode(', ', $productCodes);
		$data['product_price'] = number_format(array_sum($productPrices)) . "円";
		$data['option_price'] = number_format(array_sum($optionPrices)) . "円";
		$data['shipping_cost'] = number_format(array_sum($shippingCosts)) . "円";
		$data['wear_date'] = !empty($wearDates) ? implode(', ', $wearDates) : '未定';
		$data['rental_period'] = !empty($rentalPeriods) ? implode(', ', $rentalPeriods) : '未定';

		// Calculate dates for rental flow
		if (!empty($wearDates)) {
			$firstWearDate = $orderDetails->first()->wear_date;
			$data['arrival_date'] = date('Y/m/d', strtotime($firstWearDate . ' -2 days'));
			$data['shipping_date'] = date('Y/m/d', strtotime($firstWearDate . ' -3 days'));
			$data['return_date'] = date('Y/m/d', strtotime($firstWearDate . ' +3 days'));
			$data['store_arrival_date'] = date('Y/m/d', strtotime($firstWearDate . ' +5 days'));
		} else {
			$data['arrival_date'] = '未定';
			$data['shipping_date'] = '未定';
			$data['return_date'] = '未定';
			$data['store_arrival_date'] = '未定';
		}

		$userEmail = $user->email;
		$notifyContent = ['code' => $orderCode];
		
		try {
			Notify::create([
				'content'      => "[Order] a new order #" . $orderCode,
				'module'       => 'order',
				'item_id'      => $orderCode,
				'item_content' => json_encode($notifyContent),
				'created_at'   => date('Y-m-d H:i:s'),
				'updated_at'   => date('Y-m-d H:i:s'),
			]);
			event(new NotifyEvent());
			
			//admin
			//hunters2fujiyoshi@gmail.com
			/*Mail::send('emails.new_order_admin', $data, function ($message) use ($orderCode) {
				$message->from(config('mail.from.address'), config('mail.from.name'));
				$message->to(config('settings.admin_email'));
				$message->subject("【" . config('mail.from.name') . "】新しい注文があります #" . $orderCode);
			});
			logger("[Email] Sent admin order email to: " . config('settings.admin_email'));*/
			
			//user
			// Use different email template for provisional orders (identity verification pending)
			if ($isProvisional) {
				// Email for provisional order - identity verification pending
				// Subject theo yêu cầu khách hàng: ご注文ありがとうございます。「KIREI」(着物レンタル）
				$emailSubject = "ご注文ありがとうございます。「" . config('mail.from.name') . "」(着物レンタル）";
				Mail::send('emails.new_order_provisional_user', $data, function ($message) use ($userEmail, $emailSubject) {
					$message->from(config('mail.from.address'), config('mail.from.name'));
					$message->to($userEmail);
					$message->subject($emailSubject);
				});
				logger("[Email] Sent provisional order email to: " . $userEmail);
			} else {
				// Normal order email
				Mail::send('emails.new_order_user', $data, function ($message) use ($userEmail, $orderCode) {
					$message->from(config('mail.from.address'), config('mail.from.name'));
					$message->to($userEmail);
					$message->subject("【" . config('mail.from.name') . "】お申し込みありがとうございます #" . $orderCode);
				});
				logger("[Email] Sent user order email to: " . $userEmail);
			}
		} catch (\Exception $exception) {
			logger($exception->getMessage());
		} finally {
			return response()->json(['status' => 'success', 'code' => $orderCode], 200);
		}
	}
	
	public function destroy($id)
	{
		$cItem = Cart::get($id);
		if ($cItem) {
			Cart::remove($id);
			return response()->json(['status' => 'success', 'message' => ''], 200);
		}
		
		return response()->json(['status' => 'error', 'message' => __('messages.product_not_found')], 200);
	}
	
	public function clear()
	{
		Cart::clear();
		
		return response()->json(['status' => 'success', 'message' => ''], 200);
	}
	
	public function payment(Request $request)
	{
		$cartTotalAmount = Cart::getTotal();
		if ($cartTotalAmount <= 0) return response()->json(['errors' => __('messages.product_not_compatible')], 403);

		$params = $request->all();
		$cartData = $params['cart'] ?? [];

		// Lấy shipping address từ request
		$shippingAddress = $cartData['shipping_address'] ?? null;
		if (!$shippingAddress) {
			return response()->json(['errors' => '配送先住所を選択してください。'], 403);
		}

		// Lấy shipping cost từ request hoặc tính mặc định
		$totalShipping = isset($cartData['shipping_cost']) && is_numeric($cartData['shipping_cost'])
			? (int) $cartData['shipping_cost']
			: 10000;

		$sum = $cartTotalAmount + $totalShipping;
		$totalAmount = (int) $sum;

		// Xác định phương thức thanh toán
		$paymentMethod = $cartData['payment_method'] ?? 1;
		$paymentCardId = $cartData['payment_card_id'] ?? null;
		$token = $params['token'] ?? null;

		do {
			$orderCode = rand(111, 999) . rand(000, 999) . rand(000, 999);
			$checkOrder = Order::where(['code' => $orderCode])->first();
		} while (isset($checkOrder));

		$userId = auth('api')->user()->id;
		$user = User::where('id', $userId)->first();

		// Kiểm tra user đã xác thực hay chưa
		$isUserVerified = $user->identity_status === 'approved';
		$isProvisionalOrder = !$isUserVerified;

		$paymentResult = null;
		$chargeCardId = null;
		$payjpCustomer = null;

		// Nếu thanh toán bằng thẻ tín dụng (payment_method = 0)
		if ($paymentMethod == 0) {
			Payjp::setApiKey(config('payjp.secret_key'));

			// Kiểm tra customer PayJP
			if (!$user->payjp_customer_id) {
				return response()->json(['errors' => 'お客様情報が見つかりません。カードを登録してください。'], 403);
			}

			try {
				$payjpCustomer = \Payjp\Customer::retrieve($user->payjp_customer_id);
			} catch (\Exception $e) {
				return response()->json(['errors' => 'お客様情報が見つかりません。'], 403);
			}

			// Xác định card ID để charge
			if ($paymentCardId) {
				// Lấy payjp_card_id từ UserCard
				$userCard = UserCard::where('id', $paymentCardId)
					->where('user_id', $userId)
					->where('is_activated', 1)
					->where('is_deleted', 0)
					->first();

				if (!$userCard) {
					return response()->json(['errors' => 'カードが見つかりません。'], 403);
				}

				$chargeCardId = $userCard->payjp_card_id;
			}

			// Nếu không có card cụ thể, dùng default card của customer
			if (!$chargeCardId) {
				$chargeCardId = $payjpCustomer->default_card;
			}

			if (!$chargeCardId) {
				return response()->json(['errors' => 'カードが登録されていません。'], 403);
			}

			// Chỉ thực hiện thanh toán ngay nếu user đã xác thực
			if ($isUserVerified) {
				$paymentResult = \Payjp\Charge::create([
					"customer"    => $payjpCustomer->id,
					"card"        => $chargeCardId,
					"amount"      => $totalAmount,
					"currency"    => 'jpy',
					"description" => "Payment for #" . $orderCode,
				]);
			}
			// Nếu user chưa xác thực, chỉ lưu thông tin thẻ để charge sau
		}

		// Xác định trạng thái đơn hàng và thanh toán
		// Status: 0 = New, 9 = Identity Verification Pending (仮予約)
		$orderStatus = $isProvisionalOrder ? 9 : 0;
		$paymentStatus = ($paymentMethod == 0 && $paymentResult != null) ? 1 : 0;

		//Order
		$orderData = [
			'code'           => $orderCode,
			'type'           => "user",
			'user_id'        => $userId,
			'total_price'    => $totalAmount,
			'note'           => '',
			'payment_method' => $paymentMethod,
			'payment_status' => $paymentStatus,
			'status'         => $orderStatus,
			'created_at'     => date('Y-m-d H:i:s'),
			'updated_at'     => date('Y-m-d H:i:s'),
		];

		// Nếu là đơn hàng tạm thời (user chưa xác thực)
		if ($isProvisionalOrder) {
			$orderData['provisional_created_at'] = now();
			$orderData['provisional_expires_at'] = now()->addDays(3);
			$orderData['identity_verification_required'] = true;
			// Lưu card ID để charge sau khi xác thực (nếu thanh toán bằng thẻ)
			if ($paymentMethod == 0 && $chargeCardId) {
				$orderData['payment_token'] = $chargeCardId;
			}
		}

		$order = Order::create($orderData);
		
		//Order Detail
		$cartCollection = Cart::getContent();
		foreach ($cartCollection as $item) {
			$product = Product::where('id', $item['attributes']['id'])->first();
			OrderDetail::create([
				'order_id'      => $order->id,
				'product_id'    => $item['attributes']['id'],
				'product_name'  => $item['name'],
				'product_image' => $item['attributes']['image'],
				'product_type'  => $item['attributes']['type'], //add
				'order_method'  => $item['attributes']['package'],
				'catalog_price' => $item['attributes']['origin_price'],
				'discount'      => $product->discount,
				'price'         => $item['attributes']['price'],
				'tax'           => $item['attributes']['tax'], //add
				'shipping_cost' => 0,
				'shipping_date' => $item['attributes']['shipping_date'], //add
				'wear_date'     => $item['attributes']['wear_date'], //add
				'height'        => $item['attributes']['height'], //add
				'hip'           => $item['attributes']['hip'], //add
				'foot'          => $item['attributes']['foot'], //add
				'safe_pack'     => $item['attributes']['charged_options']['safe_pack']['price'], //add
				'tabi'          => $item['attributes']['charged_options']['tabi']['price'], //add
				'towel'         => $item['attributes']['charged_options']['towel']['price'], //add
				'free_options'  => "", //add
				'quantity'      => $item['quantity'],
				'total_price'   => $item['price'],
				'created_at'    => date('Y-m-d H:i:s'),
				'updated_at'    => date('Y-m-d H:i:s'),
			]);
		}

		//DeliveryAddress - Sử dụng địa chỉ từ checkout form
		DeliveryAddress::create([
			'order_id'            => $order->id,
			'first_name'          => $shippingAddress['first_name'] ?? $user->full_name,
			'last_name'           => $shippingAddress['last_name'] ?? '',
			'furigana_first_name' => $shippingAddress['furigana_first_name'] ?? $user->furigana_name,
			'furigana_last_name'  => $shippingAddress['furigana_last_name'] ?? '',
			'post_code'           => $shippingAddress['postal_code'] ?? $shippingAddress['post_code'] ?? $user->post_code,
			'city'                => $shippingAddress['city'] ?? $user->city,
			'district'            => $shippingAddress['province'] ?? $shippingAddress['district'] ?? $user->district,
			'address'             => trim(($shippingAddress['street_address'] ?? '') . ' ' . ($shippingAddress['building_name'] ?? '')),
			'phone_number'        => $shippingAddress['phone_number'] ?? $user->phone_number,
			'email'               => $shippingAddress['email'] ?? $user->email,
			'user_id'             => $userId,
			'is_default'          => 0,
			'created_at'          => date('Y-m-d H:i:s'),
			'updated_at'          => date('Y-m-d H:i:s'),
		]);

		//Payment
		//$paymentResult = Util\Util::convertPayjpObjectToArray($paymentResult);
		$payment = null;
		if ($paymentResult != null) {
			$paymentResultArr = $paymentResult;
			$payment = Payment::create([
				'order_id'               => $order->id,
				'code'                   => $paymentResultArr->id,
				'total'                  => $paymentResultArr->amount,
				'amount_captured'        => $paymentResultArr->captured,
				'amount_refunded'        => $paymentResultArr->amount_refunded,
				'application_fee'        => $paymentResultArr->fee_rate,
				'application_fee_amount' => $paymentResultArr->fee_rate,
				'currency'               => $paymentResultArr->currency,
				'type'                   => $paymentResultArr->card->brand,
				'provider'               => $paymentResultArr->card->brand,
				'customer'               => $paymentResultArr->customer,
				'payment_method'         => $paymentResultArr->card->brand,
				'brand'                  => $paymentResultArr->card->brand,
				'funding'                => '',
				'network'                => '',
				'country'                => $paymentResultArr->card->country,
				'last4'                  => $paymentResultArr->card->last4,
				'exp_month'              => $paymentResultArr->card->exp_month,
				'exp_year'               => $paymentResultArr->card->exp_year,
				'failure_code'           => $paymentResultArr->failure_code,
				'failure_message'        => $paymentResultArr->failure_message,
				'content'                => $paymentResultArr->card->id,
				'customer_info'          => '',
				/*'error_content'        => $paymentResultArr->amount_refunded',*/
				'finished_at'            => date('Y-m-d H:i:s', $paymentResultArr->created),
				'status'                 => ($paymentResultArr['paid']) ? 1 : 0,
				'created_at'             => date('Y-m-d H:i:s'),
				'updated_at'             => date('Y-m-d H:i:s'),
			]);
		}
		
		//User payment history
		UserPaymentHistory::create([
			'user_id'        => $userId,
			'type'           => 0,
			'order_id'       => $order->id,
			'payment_id'     => ($payment !== null) ? $payment->id : null,
			'amount'         => $totalAmount,
			'payment_status' => ($payment !== null) ? 1 : 0,
			'created_at'     => date('Y-m-d H:i:s'),
			'updated_at'     => date('Y-m-d H:i:s'),
		]);

		//Clear Cart
		Cart::clear();

		// Prepare email data from order details
		$orderDetails = OrderDetail::where('order_id', $order->id)->get();
		$productCodes = [];
		$productPrices = [];
		$optionPrices = [];
		$wearDates = [];
		$rentalPeriods = [];

		foreach ($orderDetails as $detail) {
			$productCodes[] = $detail->product_name;
			$productPrices[] = $detail->price;
			$optionPrices[] = ($detail->safe_pack ?? 0) + ($detail->tabi ?? 0) + ($detail->towel ?? 0);

			// Format wear date
			if ($detail->wear_date) {
				$wearDateFormatted = date('Y/m/d', strtotime($detail->wear_date));
				$wearDates[] = $wearDateFormatted;

				// Calculate rental period (5 nights 6 days)
				$arrivalDate = date('Y/m/d', strtotime($detail->wear_date . ' -2 days'));
				$returnDate = date('Y/m/d', strtotime($detail->wear_date . ' +3 days'));
				$rentalPeriods[] = $arrivalDate . ' ～ ' . $returnDate;
			}
		}

		//Send Email
		$data = $params;
		$data['site'] = url("/");
		$data['code'] = $orderCode;
		$data['total_amount'] = "￥" . number_format($cartTotalAmount);
		$data['payment_method'] = ($paymentMethod == 0) ? "クレジットカード" : "銀行振込";
		$data['payment_status'] = ($payment !== null && $payment->status == 1) ? "有料" : "未払い";
		$data['note'] = '';
		$data['name'] = $user->full_name;
		$data['furigana'] = $user->furigana_name;
		$data['address'] = "〒" . $user->post_code . " " . $user->city . " " . $user->district . " " . $user->address . " " . $user->address2;
		$data['phone_number'] = $user->phone_number;
		$data['email'] = $user->email;
		$data['is_provisional'] = $isProvisionalOrder;
		$data['provisional_expires_at'] = $isProvisionalOrder ? now()->addDays(3)->format('Y年m月d日 H:i') : null;

		// Additional data for provisional order email template
		$data['product_code'] = implode(', ', $productCodes);
		$data['product_price'] = number_format(array_sum($productPrices)) . "円";
		$data['option_price'] = number_format(array_sum($optionPrices)) . "円";
		$data['wearing_date'] = !empty($wearDates) ? implode(', ', $wearDates) : '未定';
		$data['rental_days'] = 5;

		// Calculate dates for rental flow
		if (!empty($wearDates)) {
			$firstWearDate = $orderDetails->first()->wear_date;
			$data['rental_start_date'] = date('Y/m/d', strtotime($firstWearDate . ' -2 days'));
			$data['rental_end_date'] = date('Y/m/d', strtotime($firstWearDate . ' +3 days'));
			$data['arrival_date'] = date('Y/m/d', strtotime($firstWearDate . ' -2 days'));
			$data['shipping_date'] = date('Y/m/d', strtotime($firstWearDate . ' -3 days'));
			$data['return_date'] = date('Y/m/d', strtotime($firstWearDate . ' +3 days'));
			$data['store_arrival_date'] = date('Y/m/d', strtotime($firstWearDate . ' +5 days'));
		} else {
			$data['rental_start_date'] = '';
			$data['rental_end_date'] = '';
			$data['arrival_date'] = '未定';
			$data['shipping_date'] = '未定';
			$data['return_date'] = '未定';
			$data['store_arrival_date'] = '未定';
		}

		$userEmail = $user->email;
		$notifyContent = ['code' => $orderCode];

		try {
			// Nội dung thông báo khác nhau cho đơn thường và đơn tạm thời
			$notifyMessage = $isProvisionalOrder
				? "[Order] 仮予約 #" . $orderCode . " (本人確認待ち)"
				: "[Order] a new order #" . $orderCode;

			Notify::create([
				'content'      => $notifyMessage,
				'module'       => 'order',
				'item_id'      => $orderCode,
				'item_content' => json_encode($notifyContent),
				'created_at'   => date('Y-m-d H:i:s'),
				'updated_at'   => date('Y-m-d H:i:s'),
			]);
			event(new NotifyEvent());

			//admin
			$adminSubject = $isProvisionalOrder
				? "【" . config('mail.from.name') . "】仮予約があります #" . $orderCode . " (本人確認待ち)"
				: "【" . config('mail.from.name') . "】新しい注文があります #" . $orderCode;

			Mail::send('emails.new_order_admin', $data, function ($message) use ($adminSubject) {
				$message->from(config('mail.from.address'), config('mail.from.name'));
				$message->to(config('settings.admin_email'));
				$message->subject($adminSubject);
			});
			logger("[Email] Sent admin order email to: " . config('settings.admin_email'));

			//user - Gửi email khác nhau tùy theo loại đơn hàng
			if ($isProvisionalOrder) {
				// Email cho đơn hàng tạm thời (仮予約)
				// Subject theo yêu cầu khách hàng: ご注文ありがとうございます。「KIREI」(着物レンタル）
				$userSubject = "ご注文ありがとうございます。「" . config('mail.from.name') . "」(着物レンタル）";
				Mail::send('emails.provisional_order_user', $data, function ($message) use ($userEmail, $userSubject) {
					$message->from(config('mail.from.address'), config('mail.from.name'));
					$message->to($userEmail);
					$message->subject($userSubject);
				});
				logger("[Email] Sent provisional order email to: " . $userEmail);
			} else {
				// Email cho đơn hàng thường
				$userSubject = "【" . config('mail.from.name') . "】お申し込みありがとうございます #" . $orderCode;
				Mail::send('emails.new_order_user', $data, function ($message) use ($userEmail, $userSubject) {
					$message->from(config('mail.from.address'), config('mail.from.name'));
					$message->to($userEmail);
					$message->subject($userSubject);
				});
				logger("[Email] Sent user order email to: " . $userEmail);
			}

		} catch (\Exception $exception) {
			logger($exception->getMessage());
		} finally {
			return response()->json([
				'status' => 'success',
				'code' => $orderCode,
				'is_provisional' => $isProvisionalOrder,
				'message' => $isProvisionalOrder
					? '仮予約が完了しました。本人確認書類を提出してください。'
					: 'ご注文ありがとうございます。'
			], 200);
		}
	}

	/**
	 * Get shipping cost by area_id
	 */
	public function getShippingCost(Request $request)
	{
		$areaId = $request->get('area_id');

		if (!$areaId) {
			return response()->json(['shipping_cost' => 10000]);
		}

		$shippingCost = ShippingCost::where('area_id', $areaId)
			->where('is_activated', 1)
			->where('is_deleted', 0)
			->first();

		if ($shippingCost) {
			// Kiểm tra free shipping nếu total vượt ngưỡng
			$cartTotal = Cart::getTotal();
			if ($shippingCost->free_from && $cartTotal >= $shippingCost->free_from) {
				return response()->json(['shipping_cost' => 0, 'free_shipping' => true]);
			}
			return response()->json(['shipping_cost' => (int) $shippingCost->price]);
		}

		// Default shipping cost
		return response()->json(['shipping_cost' => 10000]);
	}
}