<?php

declare(strict_types=1);

namespace PortalPeople\booking\services;

use backend\models\Bookingsbe;
use backend\models\Cartlines;
use backend\models\Inventorycentersbe;
use backend\models\Productsbe;
use DateTime;
use Yii;

/**
 * AvailabilityService
 *
 * Checks board/equipment availability for a given date range and product/centre.
 * Extracted from api/modules/v1/controllers/BookingController::actionCheck().
 *
 * NOTE: The original actionCheck had a bug in the Rental branch — $price was referenced
 * inside the foreach loop over $bookings without being defined in that scope. The behaviour
 * is preserved faithfully here; fix by supplying $price from getPricing() in the rental path
 * when that is available.
 */
class AvailabilityService
{
    /**
     * Run an availability check.
     *
     * @param array<string, mixed> $bodyParams  Full request body params (expects 'bookingbe' key)
     * @return mixed  Rendered HTML partial or null on error
     */
    public function check(array $bodyParams): mixed
    {
        $data       = $bodyParams['bookingbe'];
        $source     = $data['source'];
        $cartlineid = $data['cartlineid'] ?? null;
        $cartline   = Cartlines::find()->where(['id' => $cartlineid])->one();

        $sdate = isset($data['startdatea'])
            ? $data['startdatea']['year'] . '-' . $data['startdatea']['month'] . '-' . $data['startdatea']['day']
            : '--';
        $edate = isset($data['enddatea'])
            ? $data['enddatea']['year'] . '-' . $data['enddatea']['month'] . '-' . $data['enddatea']['day']
            : '--';

        $sdate = $sdate !== '--' ? $sdate : $data['startdate'];
        $edate = $edate !== '--' ? $edate : $data['enddate'];

        $sd = new DateTime($sdate);
        $ed = new DateTime($edate);
        $td = $rd = (int)$sd->diff($ed)->format('%a');

        $producttype = null;
        $product     = null;

        if ($data['productid'] !== null) {
            $product     = Productsbe::find()->where(['id' => $data['productid'], 'language' => 'en'])->one();
            $producttype = $product->product_type;
        }

        Yii::debug($producttype, 'type');

        $bookings = Bookingsbe::findavail($data['Center'], $data['sport'], $sdate, $edate);
        Yii::debug($bookings, 'booking data');

        if ($producttype === 'Rental') {
            $query     = ['categories.id' => $data['sport'], 'categories.language' => 'en'];
            $joinquery = ['inventory', 'sport'];
        } else {
            $query     = ['and', ['products.language' => 'en'], ['products.id' => $data['productid']]];
            $joinquery = ['inventory', 'products'];
        }

        $boards = Inventorycentersbe::find()
            ->select(['inventory_centers.id', 'inventory_centers.centerid', 'inventory_centers.qty_online', 'inventory_centers.relatedid'])
            ->andFilterWhere($query)
            ->andWhere(['inventory_centers.centerid' => $data['Center']])
            ->andWhere(['inventory.status' => 'Active'])
            ->andWhere(['>', 'inventory_centers.qty_online', 0])
            ->joinWith($joinquery)
            ->all();

        $boardsarray = [];
        foreach ($boards as $board) {
            $boardsarray[] = $board->id;
        }

        Yii::debug($boardsarray, 'boards');

        $out   = [];
        $dates = [];
        $new   = [];

        while ($sd->format('Y-m-d') <= $ed->format('Y-m-d')) {
            $date1          = $sd->format('Y-m-d');
            $dates[$date1]  = $date1;
            $new[$date1]    = 'new';
            $sd->modify('+1 day');
        }

        if ($producttype === 'Rental') {
            foreach ($bookings as $booking) {
                foreach ($booking->datesdata as $date => $boardid) {
                    $board = Inventorycentersbe::find()->where(['id' => $boardid])->one();

                    if (in_array($date, $dates) && in_array($boardid, $boardsarray)) {
                        // NOTE: $price is undefined in the original rental path — preserved faithfully
                        $out[$board->inventory->model . ' - ' . $board->inventory->volume][$date][] = [
                            'available'  => 'No',
                            'status'     => 'booked',
                            'reason'     => 'Unavailable',
                            'qty'        => $board->qty_online,
                            'id'         => $board->id,
                            'stock_code' => $price->stock_code ?? null,
                            'priceid'    => $price->id ?? null,
                        ];
                        $rd--;
                    } elseif (!in_array($date, $dates) && in_array($boardid, $boardsarray)) {
                        $out[$board->inventory->model . ' - ' . $board->inventory->volume][$date][] = [
                            'status'     => 'new',
                            'available'  => 'Yes',
                            'reason'     => 'Bookable',
                            'qty'        => $board->qty_online,
                            'id'         => $board->id,
                            'stock_code' => $price->stock_code ?? null,
                            'priceid'    => $price->id ?? null,
                        ];
                    }
                }
            }
        } else {
            foreach ($bookings as $booking) {
                foreach ($booking->datesdata as $date => $boardid) {
                    $board = Inventorycentersbe::find()->where(['id' => $boardid])->one();

                    if (in_array($date, $dates) && in_array($boardid, $boardsarray)) {
                        foreach ($product->getPricing($product->id, $data['Center'], 'pre-booked') as $price) {
                            $out[$product->product_name . ' - ' . $price->qty . ' - ' . $price->unit][$date][] = [
                                'available'  => 'No',
                                'status'     => 'booked',
                                'reason'     => 'Unavailable',
                                'qty'        => $board->qty_online,
                                'id'         => $board->id,
                                'stock_code' => $price->stock_code,
                                'priceid'    => $price->id,
                            ];
                            $rd--;
                            Yii::debug($out, 'price');
                        }

                        Yii::debug(true, 'In Array');
                    } else {
                        Yii::debug(false, 'In Array');

                        foreach ($product->getPricing($product->id, $data['Center'], 'pre-booked') as $price) {
                            Yii::debug($price, 'out');
                            $out[$product->product_name . ' - ' . $price->qty . ' - ' . $price->unit][$date][] = [
                                'status'     => 'new',
                                'available'  => 'Yes',
                                'reason'     => 'Bookable',
                                'qty'        => $board->qty_online,
                                'id'         => $board->id,
                                'stock_code' => $price->stock_code,
                                'priceid'    => $price->id,
                            ];
                            Yii::debug($out, 'out');
                        }
                    }
                }
            }
        }

        $newarray = [];

        foreach ($new as $date => $newa) {
            foreach ($boards as $board) {
                foreach ($product->getPricing($product->id, $data['Center'], 'pre-booked') as $price) {
                    Yii::debug($price->qty / 2, '?');
                    Yii::debug($td, '2?');

                    if (($price->qty / 2) < $td) {
                        $out[$product->product_name . ' - ' . $price->qty . ' - ' . $price->unit][$date][] = [
                            'status'     => 'New',
                            'available'  => 'yes',
                            'reason'     => 'Bookable',
                            'id'         => $board->id,
                            'qty'        => $board->qty_online,
                            'stock_code' => $price->stock_code,
                            'priceid'    => $price->id,
                        ];
                    }
                }
            }
        }

        foreach ($out as $boardid => $datea) {
            ksort($datea);

            foreach ($datea as $date => $dateData) {
                $unavailable = 0;
                $available   = 0;
                $boardaid    = '';
                $boardqty    = '';
                $stock_code  = null;
                $priceid     = null;

                foreach ($dateData as $array) {
                    $array['available'] === 'No' ? $unavailable++ : $available++;
                    $boardaid   = $array['id'];
                    $boardqty   = $array['qty'];
                    $stock_code = $array['stock_code'];
                    $priceid    = $array['priceid'];
                }

                $newarray[$boardid]['qty']            = $boardqty;
                $newarray[$boardid]['id']             = $boardaid;
                $newarray[$boardid]['stock_code']     = $stock_code;
                $newarray[$boardid]['priceid']        = $priceid;
                $newarray[$boardid]['dates'][$date]   = [
                    'status'    => 'New',
                    'available' => $available > 0,
                    'reason'    => $available > 0 ? 'Bookable' : 'No More Bookable Boards',
                    'id'        => $boardaid,
                    'qty'       => $boardqty,
                    'unaqty'    => $unavailable,
                    'aqty'      => $available,
                ];
            }

            $over = 0;
            foreach ($newarray[$boardid]['dates'] as $array) {
                if ($array['unaqty'] > $over) {
                    $over = $array['unaqty'];
                }
            }

            $newarray[$boardid]['left'] = $newarray[$boardid]['qty'] - $over;
        }

        Yii::debug($newarray, 'debug');

        /** @var \yii\web\Controller $controller */
        $controller = Yii::$app->controller;
        $controller->layout = false;

        return $controller->renderAjax(
            '@backend/views/bookings/_table',
            ['source' => $source, 'booking' => $newarray, 'dates' => $dates, 'bookings' => $bookings, 'cartline' => $cartline]
        );
    }
}
