<?php

namespace objects;

use classes\db;
use classes\object_property;
use classes\slack;
use Exception;
use traits\db_object_t;

class xlvask_potential_order_matches_o extends db
{
    use db_object_t;

    public object_property $wash_id; // The wash id (In XL Vask - UUID)
    public object_property $order_id; // The order id that this potential order match is for (In XL Vask - UUID)
    public object_property $customer_id; // The customer id (In XL Vask - UUID)
    public object_property $customer_number; // The customer number
    public object_property $ignore_duplicate; // Whether to ignore duplicate matches (0 = No, 1 = Yes)
    public object_property $department; // The department id
    public object_property $created_at; // The created at timestamp
    public object_property $updated_at; // The updated at timestamp
    public object_property $deleted_at; // The deleted at timestamp

    public function structure(): void
    {
        $this->setTable('xlvask_potential_order_matches');
    }

    /**
     * Convert the object to an array
     * @throws Exception If the object is not selected
     * @throws Exception If the object is not found
     */
    public function asArray(): array
    {
        self::requireSelected();
        return [
            'id' => (int)$this->id,
            'wash_id' => (string)$this->wash_id->value(),
            'order_id' => (int)$this->order_id->value(),
            'customer_id' => (int)$this->customer_id->value(),
            'customer_number' => $this->customer_number->value(),
            'ignore_duplicate' => (int)$this->ignore_duplicate->value(),
            'department' => (int)$this->department->value(),
            'created_at' => (int)$this->created_at->value(),
            'updated_at' => (int)$this->updated_at->value(),
        ];
    }

    /**
     * Add a new object to the database
     * @param string $washId The wash id (In XL Vask - UUID)
     * @param int $order The order id that this potential order match is for (In XL Vask - UUID)
     * @param string $customer_id The customer id (In XL Vask - UUID)
     * @param int $customerNumber The customer number
     * @param int $department The department id
     * @return void
     * @throws Exception If the object was not created successfully
     */
    public function add(
        string $washId,
        int    $order,
        string $customer_id,
        int    $customerNumber,
        int    $department,
    ): void
    {
        //echo 'Wash ID: ' . $washId . ', Order: ' . $order . ', Customer ID: ' . $customer_id . ', Customer Number: ' . $customerNumber . ', Department: ' . $department . "\n";
        $tmp_id = self::add_object(
            [
                'wash_id' => $washId,
                'order_id' => $order,
                'customer_id' => $customer_id,
                'customer_number' => $customerNumber,
                'ignore_duplicate' => 0, // Default to not ignoring duplicates
                'department' => $department,
            ]
        );
        //echo 'Temporary ID: ' . $tmp_id . "\n";
        $this->id = $tmp_id;
        self::getObjectProperties();
        self::objectChanged();
        self::notifyDepartment();
    }

    public function getObjectProperties(): void
    {
        $this->wash_id = new object_property($this->table, $this->id, 'wash_id', 'string', true);
        $this->order_id = new object_property($this->table, $this->id, 'order_id', 'int', true);
        $this->customer_id = new object_property($this->table, $this->id, 'customer_id', 'string', true);
        $this->customer_number = new object_property($this->table, $this->id, 'customer_number', 'int', true);
        $this->ignore_duplicate = new object_property($this->table, $this->id, 'ignore_duplicate', 'int', true);
        $this->department = new object_property($this->table, $this->id, 'department', 'int', true);
        $this->created_at = new object_property($this->table, $this->id, 'created_at', 'int', true);
        $this->updated_at = new object_property($this->table, $this->id, 'updated_at', 'int', true);
        $this->deleted_at = new object_property($this->table, $this->id, 'deleted_at', 'int', false);
    }

    public function objectChanged(): void
    {
        //TODO: Add cache invalidation
    }

    /**
     * Notify the department about the new potential order match
     * @throws Exception If the object is not selected
     * @throws Exception If the department is not found
     * @throws Exception If the department notification fails
     */
    public function notifyDepartment(): void
    {
        $this->requireSelected();
        $slack = new slack();
        $slack->send_message('
            A new potential order match has been created:
            - Wash ID: ' . $this->wash_id->value() . '
            - Order ID: ' . $this->order_id->value() . '
            - Customer ID: ' . $this->customer_id->value() . '
            - Customer Number: ' . $this->customer_number->value() . '
            - Department: ' . $this->department->value(),
            'xlvask_potential_order_matches');
    }

    public function shouldIgnoreDuplicate(string $WashId): bool
    {
        if (!$this->doesWashPotentialOrderMatchExist($WashId)) {
            return false;
        }
        // Check if the potential order match for the given wash ID has ignore_duplicate set to 1
        $result = $this->getFieldsWhere(
            [
                'wash_id' => $WashId,
                'ignore_duplicate' => 1,
            ],
            [
                'id'
            ]
        );
        return count($result) > 0;
    }

    public function doesWashPotentialOrderMatchExist(string $WashId): bool
    {
        // Check if a potential order match exists for the given wash ID
        return count($this->getFieldsWhere(
                [
                    'wash_id' => $WashId,
                ],
                [
                    'id'
                ])) > 0;
    }
}