<?php

namespace App\Livewire\Report;

use App\Exports\ExportARInvoiceDetail;
use App\Exports\ExportARItemDetail;
use App\Exports\ExportInvoice;
use App\Exports\ExportInvoiceDetail;
use App\Models\DetailInvoice;
use Livewire\Component;
use App\Models\Invoice as ModelsInvoice;
use App\Models\ItemTransTemp;
use App\Models\Sales;
use App\Models\Settings;
use Carbon\Carbon;
use Exception;
use GuzzleHttp\Client;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Http;
use Jantinnerezo\LivewireAlert\LivewireAlert;
use Livewire\Attributes\On;
use Maatwebsite\Excel\Facades\Excel;
use Mike42\Escpos\PrintConnectors\WindowsPrintConnector;
use Mike42\Escpos\CapabilityProfile;
use Mike42\Escpos\Printer;

class Invoice extends Component
{

    use LivewireAlert;

    public $startDate;
    public $endDate;
    public $invoices;
    public $arinvoices;
    public $data;

    #[On('syncCompleted')]
    public function mount()
    {
        ini_set('max_execution_time', '1000');
        $invoices = ModelsInvoice::whereNull('no_inv')->where(function ($query) {
            if ($this->startDate && $this->endDate) {
                if ($this->startDate === $this->endDate) {
                    // If start date and end date are the same, fetch data for the start date
                    $query->whereDate('created_at', '=', $this->startDate);
                } else {
                    $endDate = date('Y-m-d 23:59:59', strtotime($this->endDate));

                    // If start date and end date are different, fetch data within the date range
                    $query->whereBetween('created_at', [$this->startDate, $endDate]);
                }
            } elseif ($this->startDate) {
                $query->whereDate('created_at', '=', $this->startDate);
            } elseif ($this->endDate) {
                $query->whereDate('created_at', '<=', $this->endDate);
            }
        })
            ->orderBy('created_at', 'DESC')->get();

        $arinvoices = ModelsInvoice::with('detailInvoices.item')->whereNull('no_inv')->where(function ($query) {
            if ($this->startDate && $this->endDate) {
                if ($this->startDate === $this->endDate) {
                    // If start date and end date are the same, fetch data for the start date
                    $query->whereDate('created_at', '=', $this->startDate);
                } else {
                    $endDate = date('Y-m-d 23:59:59', strtotime($this->endDate));

                    // If start date and end date are different, fetch data within the date range
                    $query->whereBetween('created_at', [$this->startDate, $endDate]);
                }
            } elseif ($this->startDate) {
                $query->whereDate('created_at', '=', $this->startDate);
            } elseif ($this->endDate) {
                $query->whereDate('created_at', '<=', $this->endDate);
            }
        })
            ->orderBy('created_at', 'DESC')->get();
        $this->arinvoices = $arinvoices;
        $this->invoices = $invoices;

        $this->invoices = $this->invoices->map(function ($invoice) {
            $id_sales = $invoice->detailInvoices->first()->id_sales;
            $totalqty = $invoice->detailInvoices
            ->filter(function ($detail) {
                return $detail->qty > 0;
            })
            ->sum('qty');            
            $positiveSum = $invoice->detailInvoices->filter(function ($detail) {
                return $detail->total_price > 0;
            })->sum('total_price');
            
            $negativeSum = $invoice->detailInvoices->filter(function ($detail) {
                return $detail->total_price < 0;
            })->sum('total_price');
            $subtotal = $invoice->subtotal = $invoice->detailInvoices->sum(function ($detail) {
                return $detail->nprice * $detail->qty;
            });
            $invoice->discount = $invoice->detailInvoices->sum(function ($detail) {
                return ($detail->nprice - $detail->price) * $detail->qty;
            });

            $totalprice = $positiveSum + $negativeSum;
            $sales = Sales::find($id_sales);
            $invoice->sales_name = $sales->name;
            $invoice->qty = $totalqty;
            $invoice->subtotal = $subtotal;
            
            $invoice->grandtotal = $totalprice;

            if ($invoice->note) {
                // Decode the invoice note into an associative array
                $invoiceNote = json_decode($invoice->note, true);

                // Access the cash and transfer values
                $cash = $invoiceNote['cash'];
                $transfer = $invoiceNote['transfer'];

                // Set the cash and transfer values on the invoice object
                $invoice->cash = $cash;
                $invoice->transfer = $transfer;
            }


            return $invoice;
        });
        $this->dispatch('refreshjs');

    }

    public function filterInvoices()
    {

        $invoices = ModelsInvoice::whereNull('no_inv')->where(function ($query) {
            if ($this->startDate && $this->endDate) {
                if ($this->startDate === $this->endDate) {
                    // If start date and end date are the same, fetch data for the start date
                    $query->whereDate('created_at', '=', $this->startDate);
                } else {
                    $endDate = date('Y-m-d 23:59:59', strtotime($this->endDate));

                    // If start date and end date are different, fetch data within the date range
                    $query->whereBetween('created_at', [$this->startDate, $endDate]);
                }
            } elseif ($this->startDate) {
                $query->whereDate('created_at', '=', $this->startDate);
            } elseif ($this->endDate) {
                $query->whereDate('created_at', '<=', $this->endDate);
            }
        })
            ->orderBy('created_at', 'DESC')->get();
        $arinvoices = ModelsInvoice::with('detailInvoices.item')->whereNull('no_inv')->where(function ($query) {
            if ($this->startDate && $this->endDate) {
                if ($this->startDate === $this->endDate) {
                    // If start date and end date are the same, fetch data for the start date
                    $query->whereDate('created_at', '=', $this->startDate);
                } else {
                    $endDate = date('Y-m-d 23:59:59', strtotime($this->endDate));

                    // If start date and end date are different, fetch data within the date range
                    $query->whereBetween('created_at', [$this->startDate, $endDate]);
                }
            } elseif ($this->startDate) {
                $query->whereDate('created_at', '=', $this->startDate);
            } elseif ($this->endDate) {
                $query->whereDate('created_at', '<=', $this->endDate);
            }
        })
            ->orderBy('created_at', 'DESC')->get();

        $this->arinvoices = $arinvoices;
        if ($invoices->isEmpty()) {
            $invoices = ModelsInvoice::whereNull('no_inv')->get();
            $this->invoices = $invoices;
        }
        if ($arinvoices->isEmpty()) {
            $arinvoices = ModelsInvoice::with('detailInvoices.item')->whereNull('no_inv')->get();
            $this->arinvoices = $arinvoices;
        }

        $this->invoices = $invoices;
        $this->invoices = $this->invoices->map(function ($invoice) {
            $id_sales = $invoice->detailInvoices->first()->id_sales;
            $totalqty = $invoice->detailInvoices
            ->filter(function ($detail) {
                return $detail->qty > 0;
            })
            ->sum('qty');            $positiveSum = $invoice->detailInvoices->filter(function ($detail) {
                return $detail->total_price > 0;
            })->sum('total_price');
            
            $negativeSum = $invoice->detailInvoices->filter(function ($detail) {
                return $detail->total_price < 0;
            })->sum('total_price');
             $subtotal = $invoice->subtotal = $invoice->detailInvoices->sum(function ($detail) {
                return $detail->nprice * $detail->qty;
            });
            $invoice->discount = $invoice->detailInvoices->sum(function ($detail) {
                return ($detail->nprice - $detail->price) * $detail->qty;
            });

            $totalprice = $positiveSum + $negativeSum;         
            $sales = Sales::find($id_sales);
            $invoice->sales_name = $sales->name;
            $invoice->qty = $totalqty;
            $invoice->subtotal = $subtotal;
            
            $invoice->grandtotal = $totalprice;

            if ($invoice->note) {
                // Decode the invoice note into an associative array
                $invoiceNote = json_decode($invoice->note, true);

                // Access the cash and transfer values
                $cash = $invoiceNote['cash'];
                $transfer = $invoiceNote['transfer'];

                // Set the cash and transfer values on the invoice object
                $invoice->cash = $cash;
                $invoice->transfer = $transfer;
            }

            return $invoice;
        });
        $this->dispatch('refreshjs');
    }

    public function clearFilter()
    {
        $invoices = ModelsInvoice::whereNull('no_inv')->get();

        $arinvoices = ModelsInvoice::with('detailInvoices.item')->whereNull('no_inv')->where(function ($query) {
            if ($this->startDate && $this->endDate) {
                if ($this->startDate === $this->endDate) {
                    // If start date and end date are the same, fetch data for the start date
                    $query->whereDate('created_at', '=', $this->startDate);
                } else {
                    $endDate = date('Y-m-d 23:59:59', strtotime($this->endDate));

                    // If start date and end date are different, fetch data within the date range
                    $query->whereBetween('created_at', [$this->startDate, $endDate]);
                }
            } elseif ($this->startDate) {
                $query->whereDate('created_at', '=', $this->startDate);
            } elseif ($this->endDate) {
                $query->whereDate('created_at', '<=', $this->endDate);
            }
        })
            ->orderBy('created_at', 'DESC')->get();
        $this->arinvoices = $arinvoices;
        $this->invoices = $invoices;
        $this->invoices = $this->invoices->map(function ($invoice) {
            $id_sales = $invoice->detailInvoices->first()->id_sales;
            $totalqty = $invoice->detailInvoices
            ->filter(function ($detail) {
                return $detail->qty > 0;
            })
            ->sum('qty');            
            $positiveSum = $invoice->detailInvoices->filter(function ($detail) {
                return $detail->total_price > 0;
            })->sum('total_price');
            
            $negativeSum = $invoice->detailInvoices->filter(function ($detail) {
                return $detail->total_price < 0;
            })->sum('total_price');
            $subtotal = $invoice->subtotal = $invoice->detailInvoices->sum(function ($detail) {
                return $detail->nprice * $detail->qty;
            });
            $invoice->discount = $invoice->detailInvoices->sum(function ($detail) {
                return ($detail->nprice - $detail->price) * $detail->qty;
            });
            $totalprice = $positiveSum + $negativeSum;      
            $sales = Sales::find($id_sales);
            $invoice->sales_name = $sales->name;
            $invoice->qty = $totalqty;
            $invoice->subtotal = $subtotal;
            
            $invoice->grandtotal = $totalprice;

            if ($invoice->note) {
                // Decode the invoice note into an associative array
                $invoiceNote = json_decode($invoice->note, true);

                // Access the cash and transfer values
                $cash = $invoiceNote['cash'];
                $transfer = $invoiceNote['transfer'];

                // Set the cash and transfer values on the invoice object
                $invoice->cash = $cash;
                $invoice->transfer = $transfer;
            }


            return $invoice;
        });
        $this->startDate = '';
        $this->endDate = '';
    }


    #[On('refresh')]
    public function render()
    {
        $this->invoices = $this->invoices->map(function ($invoice) {
            $id_sales = $invoice->detailInvoices->first()->id_sales;
            $totalqty = $invoice->detailInvoices
            ->filter(function ($detail) {
                return $detail->qty > 0;
            })
            ->sum('qty');
            $positiveSum = $invoice->detailInvoices->filter(function ($detail) {
                return $detail->total_price > 0;
            })->sum('total_price');
            
            $negativeSum = $invoice->detailInvoices->filter(function ($detail) {
                return $detail->total_price < 0;
            })->sum('total_price');
             $subtotal = $invoice->subtotal = $invoice->detailInvoices->sum(function ($detail) {
                return $detail->nprice * $detail->qty;
            });
            $invoice->discount = $invoice->detailInvoices->sum(function ($detail) {
                return ($detail->nprice - $detail->price) * $detail->qty;
            });

            $totalprice = $positiveSum + $negativeSum;
            $sales = Sales::find($id_sales);
            $invoice->sales_name = $sales->name;
            $invoice->qty = $totalqty;
            $invoice->subtotal = $subtotal;
            
            $invoice->grandtotal = $totalprice;
            if ($invoice->note) {
                // Decode the invoice note into an associative array
                $invoiceNote = json_decode($invoice->note, true);

                // Access the cash and transfer values
                $cash = $invoiceNote['cash'];
                $transfer = $invoiceNote['transfer'];

                // Set the cash and transfer values on the invoice object
                $invoice->cash = $cash;
                $invoice->transfer = $transfer;
            }
            return $invoice;
        });

        return view('livewire.report.invoice', [
            'invoices' => $this->invoices,
        ]);
    }

    public function detailInvoices($code)
    {
        $data = DetailInvoice::where('invoice', $code)->get();
        dd($data);
    }
    
    public function exportExcelDetail($code)
    {
        $data = DetailInvoice::where('invoice', $code)->get();
        $invoicesdetail = $data;
        $currentDate = Carbon::now();
        $now = $currentDate->format('d-m-Y');
        if ($this->startDate === null) {
            $filename = "Invoice Detail Report - {$now}.xlsx";
        } else {
            $filename = "Invoice Detail Report - {$this->startDate} - {$this->endDate}.xlsx";
        }
        $this->dispatch('refresh');
        $this->dispatch('refreshBrowser');

        return Excel::download(new ExportInvoiceDetail($invoicesdetail), $filename);

    }
    public function exportExcel()
    {
        $invoices = $this->invoices;
        $currentDate = Carbon::now();
        $now = $currentDate->format('d-m-Y');
        if ($this->startDate === null) {
            $filename = "Invoice Report - {$now}.xlsx";
        } else {
            $filename = "Invoice Report - {$this->startDate} - {$this->endDate}.xlsx";
        }        
        $this->dispatch('refreshBrowser');
        $this->dispatch('refreshBrowser');

        $this->dispatch('refresh');
        return Excel::download(new ExportInvoice($invoices), $filename);
        
    }

    public function exportARItemDetail()
    {
        $currentDate = Carbon::now();
        $now = $currentDate->format('d-m-Y');
        $arinvoices = $this->arinvoices;
        if ($this->startDate === null) {
            $filename = "AR Invoice Report - {$now}.xlsx";
        } else {
            $filename = "AR Invoice Report - {$this->startDate} - {$this->endDate}.xlsx";
        }
        $this->dispatch('refresh');
        $this->dispatch('refreshBrowser');

        return Excel::download(new ExportARItemDetail($arinvoices), $filename);
    }

    public function exportARInvoiceDetail()
    {
        $currentDate = Carbon::now();
        $now = $currentDate->format('d-m-Y');
        $arinvoices = $this->arinvoices;
        if ($this->startDate === null) {
            $filename = "AR Invoice Report - {$now}.xlsx";
        } else {
            $filename = "AR Invoice Report - {$this->startDate} - {$this->endDate}.xlsx";
        }
        $this->dispatch('refresh');
        $this->dispatch('refreshBrowser');

        return Excel::download(new ExportARInvoiceDetail($arinvoices), $filename);
    }

    public function print($code)
    {
        $user = Auth::user();
        $setting = Settings::where('wh_code', $user->whs_code)->first();
        $printer = $setting->printer_name;
        try {
            $profile = CapabilityProfile::load("default");
            $connector = new WindowsPrintConnector($printer);
            $printer = new Printer($connector, $profile);

            $printer->setTextSize(1, 1);

            $datainvoice = DetailInvoice::where('invoice', $code)->get();
            $invoice = ModelsInvoice::where('no', $code)->first();
            $changeFormatted = number_format($invoice->change ?? 0, 2);
            $datafirst = DetailInvoice::where('invoice', $code)->first();

            if ($invoice->payment === "Multi") {
                $note = json_decode($invoice['note'], true);
                $cash = $note['cash'];
                $card = $note['transfer'];
                $change = 0;
            } elseif ($invoice->payment === "Card") {
                $note = json_decode($invoice['note'], true);
                $cash = 0;
                $card = $note['transfer'];
                $change = $invoice->change;
            } elseif ($invoice->payment === "Cash") {
                $cash = $invoice->paid;
                $card = 0;
                $change = $invoice->change;
            } elseif ($invoice->payment === "Qris") {
                $cash = 0;
                $card = $invoice->paid;
                $change = $invoice->change;
            }

            $toko = $setting->wh_name;
            $address = $setting->address;
            $phone = "Telp : " . $setting->phone;
            $manager = "Cashier : " . $user->name;
            $billNo = "Bill No : " . $invoice->no;
            $date = "Date    : " . $invoice->created_at;
            $handledBy = "Handled by : " . $datafirst->sales->name;
            $cash = $cash ?? 0; // Using the null coalescing operator to handle undefined variables
            $card = $card ?? 0;
            $change = $change ?? 0;

            foreach ($datainvoice as $cartItem) {
                $name = str_pad(substr($cartItem['name'], 0, 15), 15); // Truncate or pad to 15 characters
                $items[] = [
                    'name' => $name,
                    'qty' => $cartItem['qty'],
                    'price' => $cartItem['price'],
                    'nprice' => $cartItem['nprice'],
                    'discount' => $cartItem['disc'],
                ];
            }


            $subTotal = array_reduce($items, function ($carry, $item) {
                if ($item['nprice'] >= 0) {
                    return $carry + $item['nprice'] * $item['qty'];
                }
                return $carry;
            }, 0);

            $grandTotal = array_reduce($items, function ($carry, $item) {
                return $carry + $item['price'] * $item['qty'];
            }, 0);

            $discount = array_reduce($items, function ($carry, $item) {
                return ($carry + $item['nprice'] - $item['price']);
            }, 0);

            // Start the receipt
            $printer->setJustification(Printer::JUSTIFY_CENTER);
            $printer->text("$toko\n$phone\n$address\n");
            $printer->text("---------------------------------------\n");
            $printer->setJustification(0);
            $printer->text("$manager\n$billNo\n$date\n");
            $printer->text("---------------------------------------\n");

            // Print the table
            $printer->setJustification(Printer::JUSTIFY_LEFT);
            $printer->text("Item               Qty        Price\n");
            $printer->text("---------------------------------------\n");

            $totalSelisih = 0; // Initialize the total variable

            foreach ($items as $item) {
                if ($item['discount'] === null || $item['discount'] == 0) {
                    if ($item['price'] < 0) {
                        $formattedPrice = '(' . number_format($item['price'] * $item['qty'], 2) . ')'; // Ensure the negative number is properly formatted
                    } else {
                        $formattedPrice = number_format($item['price'] * $item['qty'], 2);
                    }
                    $printer->text(sprintf(
                        "%-15s %5d   %12s\n",
                        $item['name'],
                        $item['qty'],
                        $formattedPrice
                    ));
                } else {
                    $selisih = $item['nprice'] - $item['price'];
                    $printer->text(sprintf(
                        "%-15s %5d   %12s\n",
                        $item['name'],
                        $item['qty'],
                        number_format($item['nprice'] * $item['qty'], 2)
                    ));
                    $printer->setFont(Printer::FONT_B);
                    $printer->setTextSize(1, 1);
                    $printer->text(sprintf(
                        "%36s\n",
                        "(" . number_format($selisih * $item['qty'], 2) . ")"
                    ));
                    $totalSelisih += $selisih * $item['qty'];

                }
            }

            // Print totals

            $printer->setJustification(0);

            $printer->text("---------------------------------------\n");
            $padding = 14; // Number of spaces before the text
            $subTotal = "SubTotal   : " . number_format($subTotal, 2);
            $discount = "Discount   : " . number_format($totalSelisih, 2);
            $grandTotal = "GrandTotal : " . number_format($grandTotal, 2);

            // Add padding before the text to ensure it starts at character 12
            $rightAlignedSubtotal = str_repeat(' ', $padding) . $subTotal;
            $rightAlignedDiscount = str_repeat(' ', $padding) . $discount;
            $rightAlignedGrandTotal = str_repeat(' ', $padding) . $grandTotal;

            $printer->text("$rightAlignedSubtotal\n");
            $printer->text("$rightAlignedDiscount\n");
            $printer->text("$rightAlignedGrandTotal\n");

            // $printer->text("---------------------------------------\n");
            $cash = "Cash       : " . number_format($cash, 2);
            $card = "Card       : " . number_format($card, 2);
            $change = "Change     : " . $changeFormatted;
            // Add padding before the text to ensure it starts at character 12
            $rightAlignedCash = str_repeat(' ', $padding) . $cash;
            $rightAlignedCard = str_repeat(' ', $padding) . $card;
            $rightAlignedChange = str_repeat(' ', $padding) . $change;


            $printer->text("$rightAlignedCard\n");
            $printer->text("$rightAlignedCash\n");
            $printer->text("$rightAlignedChange\n");

            // Reset text justification to default (centered)
            $printer->setJustification();

            // Handled by
            $printer->text("---------------------------------------\n");
            $printer->text("$handledBy\n");

            // Thank you message
            $printer->setJustification(Printer::JUSTIFY_CENTER);
            $printer->text("---------------------------------------\n");
            $footer = $setting->receipt_footer;
            $lines = explode('\n', $footer);

            foreach ($lines as $line) {
                $printer->text($line . "\n"); // Print each line with a newline character
            }

            $printer->text("THANK YOU\n\n\n\n"); // Send a form feed character

            $printer->text("( _ _ _ _ _ _ _ _ _ _ _ )");

            $printer->feed(2); // Adjust the number of lines as needed

            // Cut the receipt
            $printer->cut();

            // Close the printer
            $printer->close();

            // dd($items, $data, 'Subtotal : '. $subTotal, 'GrandTotal : '. $grandTotal, 'Discount : '. $discount);
            $this->dispatch('refresh');
        } catch (Exception $e) {$this->refreshBrowser();
            dd($e);
        }
    }

    public function sync($code)
    {
        $user = Auth::user();
        $setting = Settings::where('wh_code', $user->whs_code)->first();
        $url = $setting->url;
        $detailinvoice = DetailInvoice::where('invoice', $code)->get();
        $invoice = ModelsInvoice::where('no', $code)->first();
        $date = date_create($invoice->date);
        $formattedDate = date_format($date, 'Y-m-d');
        $currentDate = Carbon::now()->format('Y-m-d');
        $getsales = DetailInvoice::where('invoice', $code)->first();
        $idsales = $getsales->id_sales;

        if ($invoice->payment === "Multi") {
            $note = json_decode($invoice['note'], true);
            $cash = $note['cash'];
            $card = $note['transfer'];
            $cashAccount = $setting->cashacc;
            $transferAccount = $setting->cardacc;
        } elseif ($invoice->payment === "Card") {
            $note = json_decode($invoice['note'], true);
            $cash = 0;
            $card = $note['transfer'];
            $cashAccount = '';
            $transferAccount = $setting->cardacc;
        } elseif ($invoice->payment === "Cash") {
            $cash = $invoice->must_paid;
            $card = 0;
            $cashAccount = $setting->cashacc;
            $transferAccount = '';
        } elseif ($invoice->payment === "Qris") {
            $cash = 0;
            $card = $invoice->must_paid;
            $cashAccount = '';
            $transferAccount = $setting->cardacc;
        }
       

        foreach ($detailinvoice as $data) {
            $syncItems[] =
                [
                    'ItemCode' => $data->code,
                    'Quantity' => $data->qty,
                    'UnitPrice' => $data->nprice,
                    'LineTotal' => $data->total_price,
                    'WhsCode' => $setting->wh_code,
                    'Cost1' => $setting->cost1,
                    'Cost2' => $setting->cost2,
                    'Cost3' => $setting->cost3,
                    'Cost4' => $setting->cost4,
                    'Cost5' => $setting->cost5
                    // 'WhsCode' => "RCSM",
                    // 'SBU' => "Galaxy",
                ];
        }
        $commentcode = $user->whs_code . '/' . $code . '/' . $user->name;
        $data = [
            "CardCode" => $setting->cardcode,
            "CntctCode" => "0",
            "NumAtCard" => "0",
            "DocDate" => $formattedDate,
            "DocDueDate" => $formattedDate,
            "TaxDate" => $formattedDate,
            "SlpCode" => $idsales,
            "Comments" => $commentcode,
            "BPLId" => $setting->bpl_id,
            "CashAccount" => $cashAccount,
            "CashSum" => $cash,
            "TransferAccount" => $transferAccount,
            "TransferSum" => $card,
            "TransferDate" => $currentDate,
            "DocType" => "C",
            "Lines" => $syncItems,
        ];
       
        $response = Http::post($url . '/api/search', [
            "Select" => "\"Comments\"",
            "From" => "OINV",
            "Where" => "\"Comments\"='" . $commentcode . "' limit 1",
        ]);


        $responseBody = $response->getBody()->getContents();
        $responseData = json_decode($responseBody, true);
        if($responseData[0]['Comments'] == $commentcode){ 
            $invoice = ModelsInvoice::where('no', $code)->first();
            $invoice->sync = 'Y';
            $invoice->save();
            $this->alert('info', 'Invoice already exists on SAP', [
                'position' => 'top-end',
                'timer' => 5000,
                'toast' => true,
                'timerProgressBar' => true,
            ]);
            $this->dispatch('refreshBrowser');
            $this->dispatch('syncCompletedBrowser');
            $this->dispatch('syncCompleted');
        }else{
            try {
                $user = Auth::user();
                $setting = Settings::where('wh_code', $user->whs_code)->first();
                $url = $setting->url;
                $whscode = $setting->wh_code;
                $client = new Client();
                $response = $client->post($url . '/api/addarinvoice', [
                    'headers' => [
                        'Content-Type' => 'application/json',
                    ],
                    'json' => $data,
                ]);
    
                $responseBody = $response->getBody()->getContents();
                $responseData = json_decode($responseBody, true);
                $errorCode = $responseData['ErrorCode'];
                // dd($errorCode);
                if ($errorCode !== 0) {
                    $this->alert('warning', $responseData['Message'], [
                        'position' => 'top-end',
                        'timer' => 5000,
                        'toast' => true,
                        'timerProgressBar' => true,
                    ]);
                } else {
                    $invoice = ModelsInvoice::where('no', $code)->first();
                    $invoice->sync = 'Y';
                    $invoice->save();
                    $this->alert('success', $responseData['Message'], [
                        'position' => 'top-end',
                        'timer' => 5000,
                        'toast' => true,
                        'timerProgressBar' => true,
                    ]);
                }
                $this->dispatch('syncCompletedBrowser');
                $this->dispatch('syncCompleted');
                $this->dispatch('refreshBrowser');

                } catch (\Exception $e) {
                    $this->alert('error', 'No Internet Connection to Sync', [
                        'position' => 'top-end',
                        'timer' => 5000,
                        'toast' => true,
                        'timerProgressBar' => true,
                    ]);
                    $this->dispatch('refreshBrowser');
                    $this->dispatch('syncCompletedBrowser');
                    $this->dispatch('syncCompleted');

                }   
        }
        
    }

    public function syncAll()
    {
        $invoices = ModelsInvoice::where('sync', 'N')
            ->whereNull('no_inv')
            ->with('detailInvoices')->get();
        $user = Auth::user();
        $setting = Settings::where('wh_code', $user->whs_code)->first();

        foreach ($invoices as $invoice) {
            $date = date_create($invoice->date);
            $formattedDate = date_format($date, 'Y-m-d');
            $currentDate = Carbon::now()->format('Y-m-d');
            $getsales = DetailInvoice::where('invoice', $invoice->no)->first();
            $idsales = $getsales->id_sales;

            if ($invoice->payment === "Multi") {
                $note = json_decode($invoice['note'], true);
                $cash = $note['cash'];
                $card = $note['transfer'];
                $cashAccount = $setting->cashacc;
                $transferAccount = $setting->cardacc;
            } elseif ($invoice->payment === "Card") {
                $note = json_decode($invoice['note'], true);
                $cash = 0;
                $card = $note['transfer'];
                $cashAccount = '';
                $transferAccount =  $setting->cardacc;
            } elseif ($invoice->payment === "Cash") {
                $cash = $invoice->must_paid;
                $card = 0;
                $cashAccount = $setting->cashacc;
                $transferAccount = '';
            } elseif ($invoice->payment === "Qris") {
                $cash = 0;
                $card = $invoice->must_paid;
                $cashAccount = '';
                $transferAccount = $setting->cardacc;
            }
            $detailInvoices = $invoice->detailInvoices;
            foreach ($detailInvoices as $data) {
                $syncItems[] =
                    [
                        'ItemCode' => $data->code,
                        'Quantity' => $data->qty,
                        'UnitPrice' => $data->nprice,
                        'LineTotal' => $data->disc, //LineTotal -> grandtotal barang
                        'WhsCode' => $setting->wh_code,
                        'Cost1' => $setting->cost1,
                        'Cost2' => $setting->cost2,
                        'Cost3' => $setting->cost3,
                        'Cost4' => $setting->cost4,
                        'Cost5' => $setting->cost5
                        // 'WhsCode' => "RCSM",
                        // 'SBU' => "Galaxy",
                    ];
            }
            $data = [
                "CardCode" => $setting->cardcode,
                "CntctCode" => "0",
                "NumAtCard" => "0",
                "DocDate" => $formattedDate,
                "DocDueDate" => $formattedDate,
                "TaxDate" => $formattedDate,
                "SlpCode" => $idsales,
                "Comments" => $invoice->no,
                "BPLId" => $setting->bpl_id,
                "CashAccount" => $cashAccount,
                "CashSum" => $cash,
                "TransferAccount" => $transferAccount,
                "TransferSum" => $card,
                "TransferDate" => $currentDate,
                "DocType" => "C",
                "Lines" => $syncItems,
            ];
            try {
                $client = new Client();
                $setting = Settings::where('wh_code', $user->whs_code)->first();
                $url = $setting->url;
                $response = $client->post($url . '/api/addarinvoice', [
                    'headers' => [
                        'Content-Type' => 'application/json',
                    ],
                    'json' => $data,
                ]);

                $responseBody = $response->getBody()->getContents();
                $responseData = json_decode($responseBody, true);
                $errorCode = $responseData['ErrorCode'];
                // dd($data, $responseData);
                if ($errorCode !== 0) {
                    $this->alert('warning', $responseData['Message'], [
                        'position' => 'top-end',
                        'timer' => 5000,
                        'toast' => true,
                        'timerProgressBar' => true,
                    ]);
                } else {
                    $invoice->sync = 'Y';
                    $invoice->save();
                    $this->alert('success', $responseData['Message'], [
                        'position' => 'top-end',
                        'timer' => 5000,
                        'toast' => true,
                        'timerProgressBar' => true,
                    ]);
                }
                $this->dispatch('syncCompletedBrowserAll');
                $this->dispatch('syncCompleted');
            } catch (\Exception $e) {
                $this->alert('error', 'No Internet Connection to Sync', [
                    'position' => 'top-end',
                    'timer' => 5000,
                    'toast' => true,
                    'timerProgressBar' => true,
                ]);
            }
        }
    }

    public function sapGetTrans()
    {
        $user = Auth::user();
        $setting = Settings::where('wh_code', $user->whs_code)->first();
        $userId = auth()->user()->id;
        $url = $setting->url;
        $whscode = $setting->wh_code;
        try {
            $response = Http::post($url . '/api/search', [
                "Select" => "\"Warehouse\" as \"whs_code\",\"BASE_REF\" as \"no_trans\",\"TransType\" as \"tipe\",\"InQty\"-\"OutQty\" as \"qty\",\"DocDate\" as \"date\",\"ItemCode\" as \"item_code\",\"DocLineNum\" as \"linenum\",'" . $userId . "' as \"id_user\" ",
                "From" => "OINM",
                "Where" => "\"Warehouse\"='" . $whscode . "' and \"TransType\" not in ('13','67');",
            ]);
            $responseBody = $response->getBody()->getContents();
            $responseData = json_decode($responseBody, true);
            $errorCode = $responseData['ErrorCode'];

            if ($response->successful()) {
                $jsonData = $response->json();
                if ($errorCode == 0) {
                    ItemTransTemp::where('id_user', $userId)->delete();

                    $chunks = array_chunk($jsonData, 1000);

                    foreach ($chunks as $chunk) {
                        $insertData = [];

                        foreach ($chunk as $item) {
                            $insertData[] = [
                                'whs_code' => $item['whs_code'],
                                'no_trans' => $item['no_trans'],
                                'tipe' => $item['tipe'],
                                'qty' => $item['qty'],
                                'date' => $item['date'],
                                'canceled' => 'N',
                                'item_code' => $item['item_code'],
                                'linenum' => $item['linenum'],
                                'id_user' => $item['id_user'],
                            ];
                        }

                        DB::table('Luv2_item_trans_temp')->insert($insertData);
                    }

                    #insert item trans
                    DB::statement("
                        INSERT INTO \"Luv2_item_trans\" (\"whs_code\", \"no_trans\", \"tipe\", \"qty\", \"date\", \"canceled\", \"item_code\", \"linenum\") 
                        SELECT \"whs_code\", \"no_trans\", \"tipe\", \"qty\", \"date\", \"canceled\", \"item_code\", \"linenum\"
                        FROM \"Luv2_item_trans_temp\"
                        WHERE NOT EXISTS (
                            SELECT 1 FROM \"Luv2_item_trans\" WHERE \"Luv2_item_trans\".\"no_trans\" = \"Luv2_item_trans_temp\".\"no_trans\" and \"Luv2_item_trans\".\"tipe\" = \"Luv2_item_trans_temp\".\"tipe\" and \"Luv2_item_trans\".\"linenum\" = \"Luv2_item_trans_temp\".\"linenum\"
                        ) and \"Luv2_item_trans_temp\".\"id_user\"='" . $userId . "'
                    ");

                    ItemTransTemp::where('id_user', $userId)->delete();
                    $this->alert('success', 'Data synchrone succesfully', [
                        'position' => 'top-right',
                        'timer' => 3000,
                        'toast' => true,
                        'timerProgressBar' => true,
                    ]);
                } else {
                    $this->alert('warning', $responseData['Message'], [
                        'position' => 'top-end',
                        'timer' => 5000,
                        'toast' => true,
                        'timerProgressBar' => true,
                    ]);
                }
            }
        } catch (\Throwable $th) {
            $this->alert('error', 'No Internet Connection to Sync', [
                'position' => 'top-end',
                'timer' => 5000,
                'toast' => true,
                'timerProgressBar' => true,
            ]);
        }
    }
}
