<?php

namespace App\Http\Controllers\Daily;

use App\Models\daily\Distribution;
use App\Models\daily\Stall;
use App\Models\daily\InvoiceDoc;
use App\Http\Controllers\GetAPIController;
use App\Http\Controllers\Controller;
use App\Http\Requests\DailyValidateRequest;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Log;

class DailyController extends Controller
{
    private $itemMapper;
    private $tanksizeMethod;
    private $stallMethod;
    private $transporterMethod;
    public function __construct()
    {
        $this->middleware('permission:daily-view', ['only' => ['index','show']]);
        $this->middleware('permission:daily-add', ['only' => ['create','store']]);
        $this->middleware('permission:daily-edit', ['only' => ['edit','update']]);
        $this->middleware('permission:daily-delete', ['only' => ['destroy']]);
        $this->itemMapper = Config::get('itemMapper');
        $this->transporterMethod = (new GetAPIController())->getTransporterMethod();
        $this->stallMethod = (new GetAPIController())->getStallMethod();
        $this->tanksizeMethod = (new GetAPIController())->getTankSizeMethod();
    }

    public function index(Request $request)
    {
        Session::flash('backUrl', $request->fullUrl());
        return view('daily.index');
    }

    public function create()
    {
        if (Session::has('backUrl')) {
            Session::keep('backUrl');
        }
        $transporterMethod = $this->transporterMethod;
        $stallMethod = $this->stallMethod;
        $tanksizeMethod = $this->tanksizeMethod;
        return view('daily.create', compact('transporterMethod', 'stallMethod', 'tanksizeMethod'));
    }


    public function store(DailyValidateRequest $request, Distribution $distribution)
    {
        if (Session::has('backUrl')) {
            Session::keep('backUrl');
        }

        $nextNumber = InvoiceDoc::create();
        $uniqueRandomNumber = sprintf('%06d', $nextNumber->id);

        // $uniqueRandomNumber = null;
        // $nextId = 1;
        // do {
        //     $formattedId = sprintf('%06d', $nextId); // Format the ID to have leading zeros
        //     $nextId++;

        //     // Check if the generated $formattedId is unique in the database
        //     $isUnique = Distribution::where('invoiceNo', $formattedId)->doesntExist();

        //     if ($isUnique) {
        //         $uniqueRandomNumber = $formattedId;
        //     }
        // } while (!$isUnique);

        $data = $request->validated();
        $dbFormattedDate = Carbon::createFromFormat('d/m/Y', $data['date'])->format('Y-m-d');

        $StatusID = $request->statusID;

        $stallData = $request->input('stall');
        if ($StatusID == 2) {
            // Return with error if there is a stall with 0 quantity when submit
            foreach ($stallData as $stall) {
                if ($stall['unitPrice'] == 0.00) {
                    $notification = [
                        'message' => 'There is a stall with 0 quantity.',
                        'alert-type' => 'error'
                    ];
                    return redirect()->back()->withInput($data)->with($notification);
                }
            }
        }

        $totalBig = 0;
        $totalMedium = 0;
        $totalSmall = 0;

        foreach ($stallData as $stall) {
            $totalBig += $stall['quantityBig'];
            $totalMedium += $stall['quantityMedium'];
            $totalSmall += $stall['quantitySmall'];
        }

        $distribution = Distribution::create([
            'transporterCode' => $data['transporterCode'],
            'transporterName' => $data['transporterName'],
            'vehicleNo' => $data['transporterVehicle'],
            'invoiceNo' => $uniqueRandomNumber,
            // 'address' => $data['transporterAddress'],
            // 'city' => $data['transporterCity'],
            // 'state' => $data['transporterState'],
            // 'zipcode' => $data['transporterZip'],
            'refNo' => $data['referenceNo'],
            'date' => $dbFormattedDate,
            'totalAmount' => $data['total_amount'],
            'totalTransporterAmount' => $data['total_transporter_amount'],
            'totalBig' => $totalBig, // Save the total for quantityBig
            'totalMedium' => $totalMedium, // Save the total for quantityMedium
            'totalSmall' => $totalSmall,
            'statusID' => $StatusID,
        ]);

        if ($StatusID == 1) {
            $notificationMessage = 'Draft saved.';
        } else {
            $notificationMessage = 'Submitted!';

            // Create invoice first as we need the documentNo(Invoice No) for stall creation
            $invoicePost = [
                "debtorCode" => $distribution->transporterCode,
                "documentNo" => "KPBDD-".$distribution->invoiceNo,
                "documentDate" => $distribution->date,
                "vehicleNo" => $distribution->vehicleNo,
                "refNo" => $distribution->refNo,
                "items" => [
                    [
                        "itemCode" => $this->itemMapper['BIG'],
                        "quantity" => $distribution->totalBig,
                        "unitPrice" => $this->tanksizeMethod['tanks'][0]['priceTransporter']
                    ],
                    [
                        "itemCode" => $this->itemMapper['MEDIUM'],
                        "quantity" => $distribution->totalMedium,
                        "unitPrice" => $this->tanksizeMethod['tanks'][1]['priceTransporter']
                    ],
                    [
                        "itemCode" => $this->itemMapper['SMALL'],
                        "quantity" => $distribution->totalSmall,
                        "unitPrice" => $this->tanksizeMethod['tanks'][2]['priceTransporter']
                    ]
                ]
            ];

            $response = (new GetAPIController())->postSalesInvoice($invoicePost);
            if (!$response['success']) {
                $notification = [
                    'message' => 'Invoice created but AutoCount has error. <br/> Report to admin with the following message <br/> '
                                . $response['result'],
                    'alertType' => 'error',
                ];
                return redirect()->back()->withInput()->with($notification);
            }
        }

        $dailyDistributionId = $distribution->id;
        foreach ($stallData as $key => $stall) {
            $stallEntry = [
                'dailyDistributionId' => $dailyDistributionId,
                'bigPrice' => $data['bigPrice'],
                'mediumPrice' => $data['mediumPrice'],
                'smallPrice' => $data['smallPrice'],
                'dailyStallId' => $stall['stallId'],
                'bigQuantity' => $stall['quantityBig'],
                'mediumQuantity' => $stall['quantityMedium'],
                'smallQuantity' => $stall['quantitySmall'],
                'remark' => $stall['remark'],
                'rowTotal' => $stall['unitPrice'],
                'bigTransporterPrice' => $data['bigTransporterPrice'],
                'mediumTransporterPrice' => $data['mediumTransporterPrice'],
                'smallTransporterPrice' => $data['smallTransporterPrice'],
            ];
            $stallCreate = Stall::create($stallEntry);

            if ($StatusID == 2) {
                $tankBig = [
                    "itemCode" => $this->itemMapper['BIG'],
                    "quantity" => $stall['quantityBig'],
                    "unitPrice" => $data['bigPrice']
                ];

                $tankMedium = [
                    "itemCode" => $this->itemMapper['MEDIUM'],
                    "quantity" => $stall['quantityMedium'],
                    "unitPrice" => $data['mediumPrice']
                ];

                $tankSmall = [
                    "itemCode" => $this->itemMapper['SMALL'],
                    "quantity" => $stall['quantitySmall'],
                    "unitPrice" => $data['smallPrice']
                ];

                $soDocNo = "KPBDD-".$distribution->invoiceNo."-SO".sprintf('%03d', $key+1);
                Log::debug($soDocNo);
                $salesOrderPost = [
                    "customerCode" => $stall['stallId'],
                    "documentNo" => $soDocNo,
                    "documentDate" => $dbFormattedDate,
                    "items" => [
                        $tankBig,
                        $tankMedium,
                        $tankSmall
                    ]
                ];
                $response = (new GetAPIController())->postSalesOrder($salesOrderPost, $stallCreate->id);
                if (!$response['success']) {
                    $notification = [
                        'message' => 'Sales Order created but AutoCount has error. <br/> Report to admin with the following message <br/> '
                                    . $response['result'],
                        'alertType' => 'error',
                    ];
                    return redirect()->back()->withInput()->with($notification);
                }
            }
        }

        $notification = [
            'message' => $notificationMessage,
            'alert-type' => 'success'
        ];

        if (auth()->user()->can('daily-view')) {
            return redirect()->route('admin.daily.index')->with($notification);
        } else {
            return redirect()->route('admin.dashboard')->with($notification);
        }
    }

    public function show($id, Distribution $distribution)
    {
        if (Session::has('backUrl')) {
            Session::keep('backUrl');
        }

        $distribution = Distribution::findOrFail($id);
        $stall = Stall::where('dailyDistributionId', $distribution->id)->first();

        $stallData = Stall::where('dailyDistributionId', $id)
        ->select('dailyStallId', 'bigQuantity', 'mediumQuantity', 'smallQuantity', 'remark', 'rowTotal')
        ->get();

        $totalQuantity = $distribution->totalQuantity;
        $transporterMethod = $this->transporterMethod;
        $stallMethod = $this->stallMethod;
        $tanksizeMethod = $this->tanksizeMethod;

        $formattedDate = Carbon::parse($distribution['date'])->format('d/m/Y');
        return view('daily.show', compact('transporterMethod', 'stallMethod', 'tanksizeMethod', 'stall', 'distribution', 'stallData', 'totalQuantity', 'formattedDate'));
    }

    public function edit($id, Distribution $distribution)
    {
        if (Session::has('backUrl')) {
            Session::keep('backUrl');
        }

        $distribution = Distribution::findOrFail($id);
        if ($distribution->statusID == 2) {
            $notification = [
                'message' => 'This distribution is already submitted and cannot be edited',
                'alert-type' => 'error'
            ];

            return redirect()->route('admin.daily.index')->with($notification);
        }
        $stall = Stall::where('dailyDistributionId', $id)->first();
        $distributions = Distribution::where('id', '!=', $id)->get();

        $stallData = Stall::where('dailyDistributionId', $id)
        ->select('dailyStallId', 'bigQuantity', 'mediumQuantity', 'smallQuantity', 'remark')
        ->get();

        $transporterMethod = $this->transporterMethod;
        $stallMethod = $this->stallMethod;
        $tanksizeMethod = $this->tanksizeMethod;

        $formattedDate = Carbon::parse($distribution['date'])->format('d/m/Y');
        return view('daily.edit', compact('transporterMethod', 'stallMethod', 'tanksizeMethod', 'stall', 'distribution', 'stallData', 'formattedDate'));
    }

    public function update(DailyValidateRequest $request, Distribution $distribution, $id)
    {
        if (Session::has('backUrl')) {
            Session::keep('backUrl');
        }

        $data = $request->validated();
        $StatusID = $request->statusID;
        $stallData = $request->input('stall');

        if ($StatusID == 2) {
            // Return with error if there is a stall with 0 quantity when submit
            foreach ($stallData as $stall) {
                if ($stall['unitPrice'] == 0.00) {
                    $notification = [
                        'message' => 'There is a stall with 0 quantity.',
                        'alert-type' => 'error'
                    ];
                    return redirect()->back()->withInput($data)->with($notification);
                }
            }
        }

        $stallData = $data['stall'];
        unset($data['stall']);

        $totalBig = 0;
        $totalMedium = 0;
        $totalSmall = 0;

        foreach ($stallData as $stall) {
            $totalBig += $stall['quantityBig'];
            $totalMedium += $stall['quantityMedium'];
            $totalSmall += $stall['quantitySmall'];
        }

        $dbFormattedDate = Carbon::createFromFormat('d/m/Y', $data['date'])->format('Y-m-d');

        $distribution = Distribution::findOrFail($id);

        $distribution->update([
            'transporterCode' => $data['transporterCode'],
            'transporterName' => $data['transporterName'],
            'vehicleNo' => $data['transporterVehicle'],
            // 'invoiceNo' => $data['transporterInvoice'],
            // 'address' => $data['transporterAddress'],
            // 'city' => $data['transporterCity'],
            // 'state' => $data['transporterState'],
            // 'zipcode' => $data['transporterZip'],
            'refNo' => $data['referenceNo'],
            'date' => $dbFormattedDate,
            'totalTransporterAmount' => $data['total_transporter_amount'],
            'totalAmount' => $data['total_amount'],
            'totalBig' => $totalBig,
            'totalMedium' => $totalMedium,
            'totalSmall' => $totalSmall,
            'statusID' => $StatusID,
        ]);

        if ($StatusID == 1) {
            $notificationMessage = 'Draft saved.';
        } else {
            $notificationMessage = 'Submitted!';

            // Create invoice first as we need the documentNo(Invoice No) for stall creation
            $invoicePost = [
                "debtorCode" => $distribution->transporterCode,
                "documentNo" => "KPBDD-".$distribution->invoiceNo,
                "documentDate" => $distribution->date,
                "vehicleNo" => $distribution->vehicleNo,
                "refNo" => $distribution->refNo,
                "items" => [
                    [
                        "itemCode" => $this->itemMapper['BIG'],
                        "quantity" => $distribution->totalBig,
                        "unitPrice" => $this->tanksizeMethod['tanks'][0]['priceTransporter']
                    ],
                    [
                        "itemCode" => $this->itemMapper['MEDIUM'],
                        "quantity" => $distribution->totalMedium,
                        "unitPrice" => $this->tanksizeMethod['tanks'][1]['priceTransporter']
                    ],
                    [
                        "itemCode" => $this->itemMapper['SMALL'],
                        "quantity" => $distribution->totalSmall,
                        "unitPrice" => $this->tanksizeMethod['tanks'][2]['priceTransporter']
                    ]
                ]
            ];
            $response = (new GetAPIController())->postSalesInvoice($invoicePost);
            if (!$response['success']) {
                $notification = [
                    'message' => 'Invoice created but AutoCount has error. <br/> Report to admin with the following message <br/> '
                                . $response['result'],
                    'alertType' => 'error',
                ];
                return redirect()->back()->withInput()->with($notification);
            }
        }

        Stall::where('dailyDistributionId', $id)->delete(); // Delete existing stall entries
        foreach ($stallData as $key => $stall) {
            $stallCreate = Stall::create([
                'dailyDistributionId' => $id,
                'bigPrice' => $data['bigPrice'],
                'mediumPrice' => $data['mediumPrice'],
                'smallPrice' => $data['smallPrice'],
                'dailyStallId' => $stall['stallId'],
                'bigQuantity' => $stall['quantityBig'],
                'mediumQuantity' => $stall['quantityMedium'],
                'smallQuantity' => $stall['quantitySmall'],
                'remark' => $stall['remark'],
                'rowTotal' => $stall['unitPrice'],
                'bigTransporterPrice' => $data['bigTransporterPrice'],
                'mediumTransporterPrice' => $data['mediumTransporterPrice'],
                'smallTransporterPrice' => $data['smallTransporterPrice'],
            ]);

            if ($StatusID == 2) {
                $tankBig = [
                    "itemCode" => $this->itemMapper['BIG'],
                    "quantity" => $stall['quantityBig'],
                    "unitPrice" => $data['bigPrice']
                ];

                $tankMedium = [
                    "itemCode" => $this->itemMapper['MEDIUM'],
                    "quantity" => $stall['quantityMedium'],
                    "unitPrice" => $data['mediumPrice']
                ];

                $tankSmall = [
                    "itemCode" => $this->itemMapper['SMALL'],
                    "quantity" => $stall['quantitySmall'],
                    "unitPrice" => $data['smallPrice']
                ];

                $soDocNo = "KPBDD-".$distribution->invoiceNo."-SO".sprintf('%03d', $key+1);
                Log::debug($soDocNo);
                $salesOrderPost = [
                    "customerCode" => $stall['stallId'],
                    "documentNo" => $soDocNo,
                    "documentDate" => $dbFormattedDate,
                    "items" => [
                        $tankBig,
                        $tankMedium,
                        $tankSmall
                    ]
                ];
                $response = (new GetAPIController())->postSalesOrder($salesOrderPost, $stallCreate->id);
                if (!$response['success']) {
                    $notification = [
                        'message' => 'Sales Order created but AutoCount has error. <br/> Report to admin with the following message <br/> '
                                    . $response['result'],
                        'alertType' => 'error',
                    ];
                    return redirect()->back()->withInput()->with($notification);
                }
            }
        }

        $notification = [
            'message' => $notificationMessage,
            'alert-type' => 'success'
        ];

        return redirect()->route('admin.daily.index')->with($notification);
    }

    public function destroy($id, Distribution $distribution)
    {
        $distribution = Distribution::find($id);
        if (auth()->user()->can('daily-delete')) {
            if ($distribution->statusID == 2) {
                $salesDocNo = Stall::where('dailyDistributionId', $id)
                    ->select('autocount_doc_no')
                    ->get();

                foreach($salesDocNo as $docNo) {
                    $deleteSODocNo = [
                        "docNo" => $docNo->autocount_doc_no
                    ];
                    $response = (new GetAPIController())->deleteSalesOrder($deleteSODocNo);

                    if (!$response['success']) {
                        return response()->json([
                            'message' => 'AutoCount error: ' . $response['result'],
                            'alert-type' => 'error'
                        ], 500);
                    }
                }

                $deleteDocNo = [
                    "docNo" => "KPBDD-".$distribution->invoiceNo
                ];
                $response = (new GetAPIController())->deleteInvoice($deleteDocNo);

                if (!$response['success']) {
                    return response()->json([
                        'message' => 'AutoCount error: ' . $response['result'],
                        'alert-type' => 'error'
                    ], 500);
                }
            }
            $distribution->delete();

            return response()->json([
                'message' => 'Daily Distribution deleted successfully',
                'alert-type' => 'success'
            ], 202);
        } else {
            return response()->json([
                'message' => 'You do not have permission.',
                'alert-type' => 'warning'
            ], 400);
        }
    }
}
