<?php

namespace App\Livewire\Pos\It\ItReqOut;

use App\Models\ItemPrice;
use App\Models\ItReqOut;
use App\Models\Settings;
use App\Models\Warehouse;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Jantinnerezo\LivewireAlert\LivewireAlert;
use Livewire\Attributes\On;
use Livewire\Attributes\Rule;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Livewire\Component;

class ItReqOutCreate extends Component
{
    public $item;
    #[Rule('required', message: 'Please fill the remarks.')]
    public $remarks = '';
    public $no = '';
    public $searchitem = "";
    public $selectedItem = null;
    public $selectedCodeItem;
    public $selectedIndexItem;
    public $date;
    public $tableItems = [];
    public $selectedWarehouse = null;
    public $selectedCodeWarehouse;
    public $selectedIndexWarehouse;
    public $searchwarehouse;
    public $warehouse;
    public $selectedWarehouseto = null;
    public $selectedCodeWarehouseto;
    public $selectedIndexWarehouseto;
    public $searchwarehouseto;
    public $warehouseto;
    public $pricelist;

    use LivewireAlert;

    public function render()
    {
        $results = [];
        $resultitem = [];
        $resultwarehouse = [];
        $resultwarehouseto = [];

        if (strlen($this->searchitem) >= 1) {
            $resultitem = DB::table('Luv2_item')->where(function ($query) {
                $query->where('code', 'ILIKE', '%' . $this->searchitem . '%')
                    ->orWhere('barcode', 'LIKE', '%' . $this->searchitem . '%')
                    ->orWhere('name', 'ILIKE', '%' . $this->searchitem . '%');
            })->limit(10)->get();
            $this->item = $resultitem;
        }
        if (strlen($this->searchwarehouse) >= 1) {
            $resultwarehouse = DB::table('Luv2_warehouse')->where('name', 'ILIKE', '%' . $this->searchwarehouse . '%')->limit(10)->get();
            $this->warehouse = $resultwarehouse;
        }
        if (strlen($this->searchwarehouseto) >= 1) {
            $resultwarehouseto = DB::table('Luv2_warehouse')->where('name', 'ILIKE', '%' . $this->searchwarehouseto . '%')
                ->where('code', '!=', $this->selectedWarehouse->code)
                ->limit(10)->get();
            $this->warehouseto = $resultwarehouseto;
        }

        return view('livewire.pos.it.it-req-out.it-req-out-create', [
            'results' => $results,
            'resultitem' => $resultitem,
            'resultwarehouse' => $resultwarehouse,
            'resultwarehouseto' => $resultwarehouseto,

        ]);
    }

    public function mount()
    {
        $user = Auth::user();
        $setting = Settings::first();
        $whs = Warehouse::where('code', $setting->wh_code)->first();
        $pricelist = $whs->id_pricelist;
        $this->pricelist = $pricelist;
        $this->date = Carbon::now()->format('Y-m-d');

        if ($user->whs_code != '') {
            $warehouse = DB::table('Luv2_warehouse')->where('code', $user->whs_code)->first();
            $this->selectedWarehouse = $warehouse;
            $this->searchwarehouse = $warehouse->name;
        }
    }

    public function selectItem($index)
    {
        $this->selectedIndexItem = $index;
        $this->selectedCodeItem = $this->item[$index]->code;

        $item = DB::table('Luv2_item')
            ->select('Luv2_item.*', DB::raw('COALESCE((
            SELECT SUM("qty")
            FROM "Luv2_item_trans"
            WHERE "Luv2_item_trans"."item_code" = "Luv2_item"."code"
        ), 0) AS "qty"'))
            ->where('code', $this->selectedCodeItem)
            ->first();
        if ($item) {
            $prices = ItemPrice::where('item_code', $item->code)->where('id_pricelist', $this->pricelist)->first();
            $this->searchitem = $item->name;
            $this->selectedItem = $item;
            $item->price = $prices->price;

            $itemArray = (array) $item;
            // Initialize a flag to check if the item already exists in the tableItems
            $itemExists = false;

            // Check if the item already exists in the tableItems
            foreach ($this->tableItems as &$tableItem) {
                if ($tableItem['code'] === $itemArray['code']) {
                    // If item exists, increment the quantity
                    $tableItem['quantity'] += 1;
                    $itemExists = true;
                    break;
                }
            }

            // If the item does not exist in the tableItems, add it with a default quantity of 1
            if (!$itemExists) {
                $itemArray['quantity'] = 1;
                $this->tableItems[] = $itemArray;
            }

            $this->searchitem = '';

            $this->alert('info', 'Item: ' . $item->name, [
                'position' => 'top-end',
                'timer' => 3000,
                'toast' => true,
                'timerProgressBar' => true,
            ]);

            $this->dispatch('refreshDatatable');
        }
    }

    public function selectItemByClick($itemCode)
    {
        $item = DB::table('Luv2_item')
            ->select('Luv2_item.*', DB::raw('COALESCE((
            SELECT SUM("qty")
            FROM "Luv2_item_trans"
            WHERE "Luv2_item_trans"."item_code" = "Luv2_item"."code"
        ), 0) AS "qty"'))
            ->where('code', $itemCode)
            ->first();

        if ($item) {
            $prices = ItemPrice::where('item_code', $item->code)->where('id_pricelist', $this->pricelist)->first();

            $this->searchitem = $item->name;
            $this->selectedItem = $item;
            $item->price = $prices->price;
            $itemArray = (array) $item;

            // Initialize a flag to check if the item already exists in the tableItems
            $itemExists = false;

            // Check if the item already exists in the tableItems
            foreach ($this->tableItems as &$tableItem) {
                if ($tableItem['code'] === $itemArray['code']) {
                    // If item exists, increment the quantity
                    $tableItem['quantity'] += 1;
                    $itemExists = true;
                    break;
                }
            }

            // If the item does not exist in the tableItems, add it with a default quantity of 1
            if (!$itemExists) {
                $itemArray['quantity'] = 1;
                $this->tableItems[] = $itemArray;
            }

            $this->searchitem = '';

            $this->alert('info', 'Item: ' . $item->name, [
                'position' => 'top-end',
                'timer' => 3000,
                'toast' => true,
                'timerProgressBar' => true,
            ]);

            $this->dispatch('refreshDatatable');
        }
    }

    public function selectItemByBarcode()
    {
        $item = DB::table('Luv2_item')
            ->select('Luv2_item.*', DB::raw('COALESCE((
            SELECT SUM("qty")
            FROM "Luv2_item_trans"
            WHERE "Luv2_item_trans"."item_code" = "Luv2_item"."code"
        ), 0) AS "qty"'))
            ->where('barcode', $this->searchitem)
            ->first();

        if ($item) {
            $prices = ItemPrice::where('item_code', $item->code)->where('id_pricelist', $this->pricelist)->first();

            $this->selectedItem = $item;
            $item->price = $prices->price;
            $itemArray = (array) $item;

            // Initialize a flag to check if the item already exists in the tableItems
            $itemExists = false;

            // Check if the item already exists in the tableItems
            foreach ($this->tableItems as &$tableItem) {
                if ($tableItem['code'] === $itemArray['code']) {
                    // If item exists, increment the quantity
                    $tableItem['quantity'] += 1;
                    $itemExists = true;
                    break;
                }
            }

            // If the item does not exist in the tableItems, add it with a default quantity of 1
            if (!$itemExists) {
                $itemArray['quantity'] = 1;
                $this->tableItems[] = $itemArray;
            }

            $this->searchitem = '';

            $this->alert('info', 'Item: ' . $item->name, [
                'position' => 'top-end',
                'timer' => 3000,
                'toast' => true,
                'timerProgressBar' => true,
            ]);

            $this->dispatch('refreshDatatable');
        }else{
            $this->searchitem = '';

            $this->alert('info', 'Item not found', [
                'position' => 'top-end',
                'timer' => 3000,
                'toast' => true,
                'timerProgressBar' => true,
            ]);
        }
    }

    #[On('removeItem')]
    public function removeItem($index)
    {
        if (isset($this->tableItems[$index])) {
            unset($this->tableItems[$index]);
            $this->tableItems = array_values($this->tableItems);
            $this->alert('info', 'Item removed successfully.', [
                'position' => 'top-end',
                'timer' => 3000,
                'toast' => true,
                'timerProgressBar' => true,
            ]);
            $this->dispatch('refreshDatatable');
        }
    }

    public function updatedSearchitem()
    {
        $this->selectedItem = null;
    }

    public function selectWarehouse($index)
    {
        $this->selectedIndexWarehouse = $index;
        $this->selectedCodeWarehouse = $this->warehouse[$index]->code;

        $warehouse = DB::table('Luv2_warehouse')->where('code', $this->selectedCodeWarehouse)
            ->first();

        if ($warehouse) {

            $this->searchwarehouse = $warehouse->name;
            $this->selectedWarehouse = $warehouse;

            $this->selectedCodeWarehouse = null;
            $this->selectedIndexWarehouse = null;

            $this->alert('info', 'Warehouse: ' . $warehouse->name, [
                'position' => 'top-end',
                'timer' => 3000,
                'toast' => true,
                'timerProgressBar' => true,
            ]);
            $this->dispatch('refreshDatatable');
        }
    }

    public function selectWarehouseByClick($warehouseCode)
    {

        $warehouse = DB::table('Luv2_warehouse')->where('code', $warehouseCode)
            ->first();

        if ($warehouse) {

            $this->searchwarehouse = $warehouse->name;
            $this->selectedWarehouse = $warehouse;

            $this->alert('info', 'Warehouse: ' . $warehouse->name, [
                'position' => 'top-end',
                'timer' => 3000,
                'toast' => true,
                'timerProgressBar' => true,
            ]);
            $this->dispatch('refreshDatatable');
        }
    }


    public function updatedSearchwarehouse()
    {
        $this->selectedWarehouse = null;
    }

    public function selectWarehouseto($index)
    {
        $this->selectedIndexWarehouseto = $index;
        $this->selectedCodeWarehouseto = $this->warehouseto[$index]->code;

        $warehouse = DB::table('Luv2_warehouse')->where('code', $this->selectedCodeWarehouseto)
            ->first();

        if ($warehouse) {

            $this->searchwarehouseto = $warehouse->name;
            $this->selectedWarehouseto = $warehouse;

            $this->selectedCodeWarehouseto = null;
            $this->selectedIndexWarehouseto = null;

            $this->alert('info', 'Warehouse: ' . $warehouse->name, [
                'position' => 'top-end',
                'timer' => 3000,
                'toast' => true,
                'timerProgressBar' => true,
            ]);
            $this->dispatch('refreshDatatable');
        }
    }

    public function selectWarehousetoByClick($warehouseCode)
    {

        $warehouse = DB::table('Luv2_warehouse')->where('code', $warehouseCode)
            ->first();

        if ($warehouse) {

            $this->searchwarehouseto = $warehouse->name;
            $this->selectedWarehouseto = $warehouse;

            $this->alert('info', 'Warehouse: ' . $warehouse->name, [
                'position' => 'top-end',
                'timer' => 3000,
                'toast' => true,
                'timerProgressBar' => true,
            ]);
            $this->dispatch('refreshDatatable');
        }
    }


    public function updatedSearchwarehouseto()
    {
        $this->selectedWarehouseto = null;
    }

    public function savetoTable()
    {
        $this->validate();
        if ($this->selectedWarehouseto) {
            $user = Auth::user();
            //Code Generate No

            $huruf = 'ITROUT';

            $tanggal = Carbon::now()->isoFormat('YYMMDDHHmm');

            $countgr = DB::table('Luv2_it_req_out')
                ->where('id_user', $user->id)
                ->whereDate('created_at', Carbon::today())
                ->count();
            $countgr += 1;

            $countgr = min($countgr, 999);
            $countgr = str_pad($countgr, 3, '0', STR_PAD_LEFT);
            $no = $huruf . $tanggal . $countgr;
            $this->no = $no;

            $insertdetail = collect($this->tableItems)->map(function ($item) {
                $user = Auth::user();
                $quantitysend = $item['quantity'];


                return [
                    'no' => $this->no,
                    'item_code' => $item['code'],
                    'qty' => $item['qty'],
                    'qty_send' => $quantitysend,
                    'created_at' => Carbon::now(),
                    'updated_at' => Carbon::now(),
                ];
            })->toArray();

            $insertheader =
                [
                    'whs_code' => $this->selectedWarehouse->code,
                    'whs_code_to' => $this->selectedWarehouseto->code,
                    'no' => $this->no,
                    'date' => $this->date,
                    'comments' => $this->remarks,
                    'canceled' => 'N',
                    'created_at' => Carbon::now(),
                    'updated_at' => Carbon::now(),
                    'id_user' => $user->id,
                    'sync' => 'N'
                ];

            DB::beginTransaction();

            try {
                $no = $this->no;
                // Insert into Luv2_it_req_out
                DB::table('Luv2_it_req_out')->insert($insertheader);

                // Insert into Luv2_it_req_out_detail
                DB::table('Luv2_it_req_out_detail')->insert($insertdetail);

                // Commit the transaction
                DB::commit();

                $this->alert('info', 'IT Request Out and details stored successfully, Please wait for the synchrone.', [
                    'position' => 'top-end',
                    'timer' => 3000,
                    'toast' => true,
                    'timerProgressBar' => true,
                ]);

                $this->clearAfterSave();
                $this->dispatch('toSyncITReqOutAfterSave', $no);
            } catch (\Exception $e) {
                DB::rollBack();

                $this->alert('info', 'Failed to store IT Request Out and details: ' . $e->getMessage(), [
                    'position' => 'top-end',
                    'timer' => 3000,
                    'toast' => true,
                    'timerProgressBar' => true,
                ]);
            }
        } else {
            $this->alert('warning', 'Please select warehouse ! ', [
                'position' => 'top-end',
                'timer' => 3000,
                'toast' => true,
                'timerProgressBar' => true,
            ]);
        }
    }

    public function clearAftersave()
    {

        $this->item = '';
        $this->tableItems = [];
        $this->remarks = '';
        $this->no = '';
        $this->searchwarehouse = '';
        $this->selectedWarehouse = null;
        $this->searchwarehouseto = '';
        $this->selectedWarehouseto = null;
    }

    #[On('toSyncITReqOutAfterSave')]
    public function syncITReqOut($no)
    {
        $setting = Settings::first();

        $itreqout = ItReqOut::with(['whsTo', 'details'])
            ->where('canceled', 'N')
            ->where('no', $no)
            ->withSum('details', 'qty_send')
            ->orderBy('Luv2_it_req_out.date', 'desc')
            ->orderBy('Luv2_it_req_out.no', 'desc')
            ->first()->toArray();

        $itreqoutdetail =  DB::table('Luv2_it_req_out_detail')
            ->Join('Luv2_it_req_out', 'Luv2_it_req_out_detail.no', '=', 'Luv2_it_req_out.no')
            ->Join('Luv2_item', 'Luv2_it_req_out_detail.item_code', '=', 'Luv2_item.code')
            ->select('Luv2_item.code', 'Luv2_item.barcode', 'Luv2_item.name', DB::raw('SUM("Luv2_it_req_out_detail"."qty") as "qty"'), DB::raw('SUM("Luv2_it_req_out_detail"."qty_send") as "qty_send"'))
            ->where('Luv2_it_req_out.no', $no)
            ->groupBy('Luv2_item.code')
            ->get();

        $linenum = 0; // Initialize the line number

        foreach ($itreqoutdetail as $it) {
            $syncItems[] = [
                'no' => $no,
                'id_company' => $setting->id_company,
                'linenum' => $linenum++,
                'qty' => $it->qty_send,
                'qty_receive' => $it->qty_send,
                'item_name' => $it->name,
                'item_barcode' => $it->barcode,
                'item_code' => $it->code,
            ];
        }

        $formattedData = [
            'id_company' => $setting->id_company,
            'no' => $itreqout['no'],
            'id_whs' => $itreqout['whs_code'],
            'id_whs_to' => $itreqout['whs_code_to'],
            'date' => $itreqout['date'],
            'id_user' => $itreqout['id_user'],
            'comments' => $itreqout['comments'],
            'details' => $syncItems
        ];
        $urladmin = $setting->url_admin;
        $response = Http::post($urladmin . 'itreqout', $formattedData);
        Log::info('API Response: ', [
            'status' => $response->status(),
            'body' => $response->body()
        ]);

        if ($response->successful() && $response->json('success') === true) {
            $itreqoutModel = ItReqOut::where('no', $no)->first();
            $itreqoutModel->sync = 'Y';
            $itreqoutModel->save();

            $this->alert('success', 'IT Request Out Sync succesfully', [
                'position' => 'top-end',
                'timer' => 5000,
                'toast' => true,
                'timerProgressBar' => true,
            ]);
            $this->dispatch('afterSuccessSync');
        } else {
            $this->alert('error', $response->json('message') . ' ' .  $response->json('error'), [
                'position' => 'top-end',
                'timer' => 5000,
                'toast' => true,
                'timerProgressBar' => true,
            ]);
            $this->dispatch('refreshjs');
        }

    }

    #[On('afterSuccessSync')]
    public function afterSync()
    {
        sleep(1);
        return redirect()->route('it.itreqout');
    }
}
