<?php

namespace classes;

use interfaces\wordpress_bookings_remote_i;
use traits\wordpress_api_object_t;

class wordpress_bookings_remote implements wordpress_bookings_remote_i
{
    use wordpress_api_object_t;

    protected array $booking_cache = [];
    protected wash_certificate_store $wash_certificate_store;

    public function __construct()
    {
        // Run wordpress_api_object_t constructor
        $this->wordpress_api_object_t_construct();
        $this->wash_certificate_store = new wash_certificate_store();
    }

    /**
     * @inheritDoc
     */
    public function get_all_wash_ids(): array
    {
        // Get all the wash IDs
        return $this->request('get_all_wash_ids');
    }

    /**
     * @inheritDoc
     */
    public function get_all_bookings(): array
    {
        // Get all the bookings
        return $this->request('get_all_wash_bookings');
    }

    /**
     * @inheritDoc
     */
    public function get_last_wash_id(): int
    {
        // Get the last wash ID
        $result = $this->request('get_last_wash_id');
        return $result["success"] ? (int)$result["data"]["last_wash_id"] : 0;
    }

    /**
     * @inheritDoc
     */
    public function parse_bookings(array $bookings): array
    {
        // Parse all the bookings
        $parsed_bookings = [];
        foreach ( $bookings as $booking ) {
            $parsed_booking = $this->parse_booking($booking);
            if ($parsed_booking !== null) {
                // Check if the booking has a wash certificate
                $parsed_bookings[] = $parsed_booking;
            }
        }
        return $parsed_bookings;
    }

    /**
     * @inheritDoc
     */
    public function parse_booking(array|int $booking): array|null
    {
        // Check if the booking is an integer, and get the booking by the ID
        if (is_int($booking)) {
            $booking = $this->get_booking($booking);
        }

        // Check if the success is false
        if (isset($booking["success"])) {
            if (!$booking["success"]) {
                return null;
            } else {
                $booking = $booking["data"]["booking"];
            }
        } else if (isset($booking["id"])) {
            // Check if the booking property is set

        } else {
            return null;
        }

        // Parse the booking pickup bool
        // 1 = true, 0 = false
        // "true" = true, "false" = false
        if ($booking["pickup_bool"] === 1 || $booking["pickup_bool"] === "true") {
            $booking["pickup_bool"] = true;
        } else {
            $booking["pickup_bool"] = false;
        }

        $this->booking_cache[$booking["id"]] = [
            "id" => (int)$booking["id"],
            "customer_number" => (int)$booking["customer_number"],
            "wash_type" => (string)$booking["wash_type"],
            "contact_email" => (string)$booking["contact_email"],
            "reference_number" => (string)$booking["reference_number"],
            "regNrTraekker" => (string)$booking["regNrTraekker"],
            "regNrTrailer" => (string)$booking["regNrTrailer"],
            "washCertificateEmail" => (string)$booking["washCertificateEmail"],
            "date" => (string)$booking["date"],
            "department" => (string)$booking["department"],
            "pickup_bool" => $booking["pickup_bool"],
            "notes" => (string)$booking["notes"],
            "washCertificateStatus" => (string)$booking["washCertificateStatus"],
            "washCertificateUrl" => (string)$booking["washCertificateUrl"],
            "status" => (string)$booking["status"]
        ];

        // If the status is pending, check if the booking has a wash certificate
        if ($this->booking_cache[$booking["id"]]["status"] === 'pending') {
            $this->booking_cache[$booking["id"]]["status"] = $this->check_booking_has_wash_certificate($booking) ? 'completed' : 'pending';
        }
        return $this->booking_cache[$booking["id"]];
    }

    /**
     * @inheritDoc
     */
    public function get_booking(int $id): array
    {
        // Get the booking by the ID
        return $this->request('get_wash_booking', ['wash_id' => $id]);
    }

    /**
     * @inheritDoc
     */
    public function check_booking_has_wash_certificate(array $booking): bool
    {
        // Check if the booking has a wash certificate
        return $this->wash_certificate_store->washCertificateExists($booking['id']);
    }

    /**
     * @inheritDoc
     */
    public function check_booking_has_expected_keys(array $booking, array $expected_keys): bool
    {
        // Check if the booking has the expected keys
        return count(array_intersect($expected_keys, array_keys($booking))) === count($expected_keys);
    }

    /**
     * @inheritDoc
     */
    public function get_booking_cache(): array
    {
        // Get the booking cache
        return $this->booking_cache;
    }
}