<?php

namespace App\Http\Controllers\FrontControllers;

use App\Http\Controllers\Controller;
use App\Models\Order;
use App\Models\OrderItem;
use App\Models\Setting;
use App\Models\State;
use App\Repositories\CartRepository;
use App\Repositories\StripeRepositoryEloquent;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use Stripe\Stripe;
use App\Traits\PHPCustomMail;
class CheckoutController extends Controller
{
    use PHPCustomMail;
    protected $cartRepository;
    private $stripeRepo;

    public function __construct(CartRepository $cartRepository, StripeRepositoryEloquent $stripeRepositoryEloquent)
    {
        $this->cartRepository = $cartRepository;
        $this->stripeRepo = $stripeRepositoryEloquent;
    }

    public function index()
    {
        $get_states = State::all();
        $cartCount = count(session()->get('cart', []));
        $totalAmount = $this->totalAmountCart();

        return view('front.checkout', compact(
            'cartCount',
            'get_states',
            'totalAmount'
        ));

    }


    private function insertOrderItem($last_order_id, $cart_data)
    {
        foreach ($cart_data as $index => $itemdata) {

            $invoice_number = rand(1111, 9999);


            OrderItem::create([
                'order_id' => $last_order_id,
                'product_id' => $itemdata['product_id'],
                'price' => $itemdata['price'],
                'quantity' => $itemdata['quantity'],
                'invoice_number' => 'INV-' . $invoice_number,
            ]);
        }
    }


    public function checkoutOrder(Request $request)
    {
        $request->validate([
            'first_name' => 'required',
            'last_name' => 'required',
            'email' => 'required|email|unique:users',
            'phone_number' => 'required|numeric',
            'address' => 'required',
            'city' => 'required',
            'country' => 'required',
            'postal_code' => 'required|numeric',
        ]);


        try {
            $response = $this->stripeRepo->calculateTaxForSale($request->all());
            if ($response->getStatusCode() !== 200) {
                $error = json_decode($response->getContent(), true);
                return redirect()->back()->with('error', $error['error'] ?? 'Failed to calculate tax.');
            }
            $responseArray = json_decode($response->getContent(), true);
            session()->put('texData', $responseArray);
            session()->put('formData', $request->all());
            $sessonData = session()->get('formData', []);
            $get_tex_info = session()->get('texData', []);

            return view('front.payment', compact('sessonData', 'get_tex_info'));

        } catch (\Exception $e) {

            return redirect()->back()->with('error', 'Order failed: ' . $e->getMessage());
        }
    }

    public function cancel()
    {
        return redirect()->back()->with('error', 'Order Canceled');
    }

    public function thankYou()
    {
        return view('front.thank-you');
    }

    private function totalAmountCart()
    {
        $cart = session()->get('cart', []);
        $totalAmount = 0;

        foreach ($cart as $item) {
            $totalAmount += $item['price'] * $item['quantity'];
        }

        return $totalAmount;
    }

    public function payment(Request $request)
    {
        try {
            $setting = Setting::first();

            $request->validate([
                'payment_method_id' => 'required'
            ]);
            $get_info = session()->get('formData', []);
            $get_tex_info = session()->get('texData', []);
            $user_id = Auth::check() ? Auth::id() : 2;

            $stripeToken = $this->stripeRepo
                ->checkFrontStripeToken($request->input('payment_method_id'));

            DB::beginTransaction();
            $cart_data = $this->cartRepository->getCartContent();
            $charge = $this->stripeRepo->frontCharge($stripeToken, $get_tex_info);
            if ($charge) {
                $trackno = rand(1111, 9999);
                $order = new Order;
                $order->user_id = $user_id ?? '1';
                $order->first_name = $get_info['first_name'];
                $order->last_name = $get_info['last_name'];
                $order->email = $get_info['email'];
                $order->address = $get_info['address'];
                $order->optional = 1;
                $order->city = $get_info['city'];
                $order->postal_code = $get_info['postal_code'];
                $order->phone_number = $get_info['phone_number'];
                $order->tracking_no = 'ecommerce' . $trackno;
                $order->payment_mode = 'Stripe';
                $order->payment_status = 0;
                $order->order_status = 'Pending';
                $order->total_price = number_format($get_tex_info['amount_total'] / 100, 2);
                $order->total_items = count(session()->get('cart', [])) ?? '';
                $order->save();

                $last_order_id = $order->id;
                $this->insertOrderItem($last_order_id, $cart_data);
                $this->cartRepository->removeWholeCart();
                $email = $get_info['email'];
                $amount = $get_tex_info['amount_total'];
                $full_name = $get_info['first_name'] . ' ' . $get_info['last_name'];

                // Email data
                $data = [
                    'full_name' => $full_name,
                    'amount' => $amount,
                    'tracking_no' => $order->tracking_no,
                    'email' => $email,
                    'address' => $order->address,
                    'postal_code' => $order->postal_code,
                    'city' => $order->city,

                ];


                $this->sendEmail($data, $setting);

                DB::commit();
                return redirect()->route('front.success', ['order_id' => $last_order_id])->with('success', 'Payment successfully processed.');
            } else {
                redirect()->back()->with('error', 'some thing went wrong');
            }
        } catch (\Exception $e) {
            DB::rollBack();
            return redirect()->route('front.success')->with('error', $e->getMessage());
        }
    }

    private function sendEmail($data, $setting)
    {
        try {
            Mail::send('user.email.donation', ['data' => $data], function ($message) use ($setting, $data) {
                $message->to($setting->email, "Admin")
                    ->subject('Order Confirmation')
                    ->from('info@luxury-candles.net', 'Luxury Candles');
            });
            Mail::send('user.email.customer-email', ['data' => $data], function ($message) use ($setting, $data) {
                $message->to($data['email'], $data['full_name'])
                    ->subject('Order Confirmation')
                    ->from('info@luxury-candles.net', 'Luxury Candles');
            });
        } catch (\Exception $e) {
            redirect()->back()->with('error', 'some thing went wrong');
        }
    }
}
