<?php

namespace Database\Factories;

use App\Models\OrderManagement\Order;
use App\Models\OrderManagement\BillingDesk;
use App\Models\PaymentManagement\Payment;
use App\Models\ProductManagement\Product;
use App\Models\OrderManagement\ShippingCompany;
use App\Models\SettingManagement\Status;
use App\Models\UserManagement\Admin;
use App\Models\UserManagement\Customer;
use App\Models\UserManagement\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Order>
 */
class OrderFactory extends Factory{
    protected $model = Order::class;

    public $items = [];

    public function definition(){

        $shippingCompanies = ShippingCompany::all()->pluck("id")->toArray();
//        $statusesId = Status::whereIn("code",$statuses)->pluck("code")->toArray();
        $point_of_sales = BillingDesk::get();

        $year = date('Y');
        $endDate = "$year-12-31"; //  'now'

//        $created_at = fake()->dateTimeThisYear($endDate);
//        $updated_at = fake()->dateTimeThisYear($endDate);

//        $period = format_date($created_at,'Y-m');

//        $optionsId = [
//            "prefix" => "ORD".format_date($created_at,'ym'),
//            "count_by" => [
//                "column" => "created_at",
//                "keyName" => "ref_id",
//                "value" => [
//                    date("Y-m-d", strtotime("first day of $period")),
//                    date("Y-m-d", strtotime("last day of $period")),
//                ]
//            ]
//        ];
//        $orderId = newId(Order::class,4,$optionsId); // "ORD22010001"

        $point_of_sale = (blank($point_of_sales))
                        ? BillingDesk::factory()->create()
                        : fake()->randomElement($point_of_sales);


        return [
//            'ref_id' => $orderId,
           // "customer_id" => $user->id,
            'shipping_company_id' => fake()->randomElement($shippingCompanies),
            'payment_method_id' => null,
            'discount_code' =>  fake()->slug(1,false),
            'currency' => getSettingsOf("currency"),
//            'status_code' => fake()->randomElement($statusesId),
            'point_of_sale_id' => $point_of_sale->id,
            'warehouse_id' => null,

//            'created_at' => $created_at,
//            'updated_at' => $updated_at,
        ];
    }

    public function configure(){

        return $this->afterMaking(function (Order $order){

                        $customers = Customer::active()->get();

                        $products = Product::active()
                                            ->activeCategory()
                                            //  ->inRandomOrder()
                                            ->take(rand(1,5))
                                            ->get();

                        $items = $products->map(function ($product) {
                                            $qty = rand(1,5);
                                            return  [
                                                "product_id" => $product->id,
                                                "quantity" => $qty,
                                                "price" => $product->price,
                                                "amount" => $product->price * $qty,
                                            ];
                                        });


                        $subTotalValue = $items->sum('amount');
                        $discountValue = $subTotalValue / 2;
                        $shippingValue = rand(500,2500);
                        $taxValue = ($subTotalValue - $discountValue) * 0.15;
                        $totalValue = $subTotalValue - $discountValue + $shippingValue + $taxValue;

                        $customer = (blank($customers))
                                    ? Customer::factory()->has(Payment::factory(1,['paid_amount' =>  $totalValue]))->create()
                                    : fake()->randomElement($customers);

                        $admin =  Admin::all()->random();

                        $order->setAttribute("subtotal", $subTotalValue);
                        $order->setAttribute("discount", $discountValue);
                        $order->setAttribute("shipping", $shippingValue);
                        $order->setAttribute("tax", $taxValue);
                        $order->setAttribute("total", $totalValue);
                        $order->setAttribute("customer_id", $customer->id ?? null);
                        $order->setAttribute("created_by", $admin->id ?? null);

                        $this->items = $items->map(fn ($item) => Arr::only($item,['product_id',"price","quantity"]));

                    })

                    ->afterCreating(function (Order $order) {

                    if (blank($order->items) or filled($this->items)){

                        $items = $this->items->toArray();

                        $order->items()->createMany($items); // Create Order Products

                       // $o = Order::find($order->getKey());

                        if($order->customer->balance >= $order->total ){
                            $order->setStatusTo(Status::PAID);
                        }

                        $statuses = [
                            Status::UNDER_PROCESS,
                            Status::DELIVERED,
                            Status::REFUNDED_REQUEST,
                            Status::RETURNED_ORDER,
                            Status::REFUNDED_ORDER,
                            Status::REJECTED,
                        ];
                        $order->setStatusTo(fake()->randomElement($statuses));

        //                dd($items,$o->toArray());
                    }
                }) ;

    }
}
