<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use App\Http\Requests\Api\Checkout\CheckoutRequest;
use App\Http\Resources\OrderPaginationResource;
use App\Http\Resources\OrderShowResource;
use App\Http\Resources\ProductResource;
use App\Http\Resources\StatusResource;
use App\Models\City;
use App\Models\Currency;
use App\Models\DeliveryPrice;
use App\Models\Order;
use App\Models\Power;
use App\Models\Product;
use App\Models\Setting;
use App\Services\API\OrderService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Services\API\ProductService;
use App\Services\BotService;
use Illuminate\Support\Facades\Auth;

class OrderController extends Controller
{
    public function checkout(CheckoutRequest $request)
    {
        $currency = Currency::getCurrency()->dollar;
        DB::beginTransaction();
        try {
            $data = $request->validated();
            $orderService = new OrderService($data);
	    $row = $orderService->createOrder($data);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'message' => $e->getMessage()
            ], 403);
        }
        DB::commit();

        $url = null;

        if (!in_array($row->order->payment_type, ['cash', 'bank'])) {
            if ($row->order->payment_type == 'click') {
                $merchant_id = env("CLICK_MERCHANT_ID");
                $service_id = env("CLICK_SERVICE_ID");
                $url = "https://my.click.uz/services/pay?service_id={$service_id}&merchant_id={$merchant_id}&amount={$row->billing->amount}&transaction_param={$row->billing->id}";
            } else {
                $amount = $row->billing->amount * 100;
                $payme_url = "https://checkout.paycom.uz/" . base64_encode("m=66faa5c44f9ee150b7ff81cf;ac.key={$row->billing->id};a={$amount}");
                $url = $payme_url; //route('payment.merchant', [$row->order->payment_type, $row->billing->id, $row->billing->amount]);
            }
        }

        $order = Order::find($row->order->id);
        $contract = $order->contracts()->latest()->first();
        $products = $order->products()
            ->with(['product' => function ($query) {
                $query->select('id', 'name', 'price'); // Faqat kerakli ustunlarni tanlash
            }])
            ->get()
            ->map(function ($orderProduct) use ($currency) {
                return [
                    'name' => "📦 " . $orderProduct->product->name['uz'],
                    'price' => ceiling($orderProduct->price * $currency, 100),
                    'count' => $orderProduct->count,
                ];
            });

        // set lang
        app()->setLocale('uz');

        $group_id = Setting::query()->first()->group_id;
        $user = Auth::user();
        $service = new BotService();
        $service->sendMessage([
            "group_id" => $group_id,
            "order_id" => $row->order->id,
            "order_url" => route("dashboard.orders.view", ["order" => $row->order->id]),
            'client_type' => trans('admin.contract-templates.' . $row->order->client_type),
            'delivery_type' => trans('admin.orders.type_delivery.' . $row->order->delivery_type),
            "products" => $products,
            "client" => $user->first_name . " " . $user->last_name,
            "phone" => $user->phone,
            'time' => now(),
            'summa' => ceiling($order->price_total * $currency, 100),
        ]);

        if ($row->order->client_type == 'physical') {
            $client = $row->order->full_name;
        } else {
            $client = $row->order->legalInfo->company_name;
        }

        // download contract from s3
        // $path = $contract->path; // S3 file path
        // $localDirectory = storage_path('downloads');
        // $localPath = storage_path('downloads/' . basename($contract->path));

        // // Ensure 'downloads' directory exists
        // if (!is_dir($localDirectory)) {
        //     mkdir($localDirectory, 0755, true);
        // }

        // // Retrieve the file from S3 and save locally
        // $content = Storage::disk('s3')->get($path);
        // file_put_contents($localPath, $content);

        // $this->sendFileWithData($group_id, $row, $client, $localPath);

        return response()->json([
            'data' => [
                "id" => $row->order->id,
                "payment_status" => new StatusResource($order->getPaymentStatus),
                // "billing_id" => !in_array($row->order->payment_type, ['cash', 'bank']) ? $row->billing->id : null,
                "payment_type" => $row->order->payment_type,
                "pay_url" => $url,
                // "pay_url" => !in_array($row->order->payment_type, ['cash', 'bank']) ? "https://checkout.payme.uz" : null,
                "contract_url" => $contract?->getPath() ?? null
            ]
        ], 201);
    }

    public function preview(Request $request)
    {
        $currency = Currency::latest()->first();
        // add currency to cache
        cache()->put('currency', $currency, now()->addMinutes(60));

        $products = $this->getProducts($request);

        $countCollection = collect($request->products);
        $is_install = false;

        foreach ($products as $product) {
            // Find the corresponding count for the current product
            if ((new ProductService($product))->isInstall()) {
                $is_install = true; // Set the flag to true if any product is installed
            }
            $countItem = $countCollection->firstWhere('id', $product->id);

            if ($countItem) {
                // Update the product's count attribute (assuming you have a 'count' attribute in your Product model)
                $product->count = $countItem['count'];
            }
        }

        $power = Power::where('power', '>=', $products->sum('power'))->first();
        if (empty($power)) {
            $power_id = 0;
        } else {
            $power_id = $power->id;
        }

        // delivery price
        if (!empty($request->city_id)) {
            $city = City::where('id', $request->city_id)->first();
            $delivery_price = DeliveryPrice::where('power_id', $power_id)->where('region_id', $city->region_id)->first();
        } else {
            $delivery_price = 0;
        }

        // installation price
        $settings = Setting::query()->first();
        $power = $products->sum('power') / 1000;

        if ($request->type == 'ready_solutions') {
            $installation_price = $power * ($settings->master_price / $currency->dollar);
        } else {
            $installation_price = 0;
        }

        // product price
        $product_price = collect($products)->sum(function ($product) {
            $count = collect(request()->products)->firstWhere('id', $product->id)['count'] ?? 0;

            return $product->finalPrice * $count;
        });

        if (!empty($delivery_price)) {
            $delivery_price = $delivery_price->price;
        } else {
            $delivery_price = 0;
        }

        $total = $product_price + ($delivery_price / $currency->dollar) + $installation_price;
        return response()->json([
            'data' => [
                "is_install" => $is_install,
                'products' => ProductResource::collection($products),
                'delivery_price' => ceiling($delivery_price, 100),
                'installation_price' => ceiling($installation_price * $currency->dollar, 100),
                'total_price' => ceiling($total * $currency->dollar, 100),
                'product_price' => ceiling($product_price * $currency->dollar, 100),
            ]
        ]);
    }

    private function getProducts(Request $request)
    {
        $products_cart = collect($request->only('products'))->flatten(1);
        $product_ids = $products_cart->pluck('id');
        $products = Product::whereIn('id', $product_ids)->get();

        $products = $products->map(function ($product) use ($products_cart) {
            $product->power = $product->power * $products_cart->filter(function ($cart) use ($product) {
                return $cart['id'] == $product->id;
            })->value('count');
            return $product;
        });

        return $products;
    }


    public function list(Request $request)
    {
        $user = getAuthUser();
        $orders = $user->orders()->orderBy('id', 'desc')->with('getCurrency')->paginate($request->limit ?? 10);

        $currency = Currency::latest()->first();
        // add currency to cache
        cache()->put('currency', $currency, now()->addMinutes(60));

        return (new OrderPaginationResource($orders))->response();
    }

    public function show($order_id)
    {
        $user = getAuthUser();
        $order = $user->orders()->findOrFail($order_id);

        $currency = $order->getCurrency;
        // add currency to cache
        cache()->put('currency', $currency, now()->addMinutes(60));

        // chech if user has this order
        if (!$order) {
            return response()->json([
                'message' => 'Order not found'
            ], 404);
        }

        return new OrderShowResource($order);
    }

    public function checkPaymentStatus($order_id)
    {
        // check if this order belongs to the user
        $user = request()->user();

        $order = $user->orders()->find($order_id);

        // chech if user has this order
        if (!$order) {
            return response()->json([
                'message' => 'Order not found'
            ], 404);
        }

        return response()->json([
            'data' => [
                'payment_status' => $order->payment_status //new StatusResource($order->getPaymentStatus),
            ]
        ]);
    }
}
