<?php

namespace objects;

use classes\db;
use classes\department_customer_price_overrides_schema_bootstrap;
use traits\db_object_t;

class department_customer_price_overrides_o extends db
{
    use db_object_t;

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

    public function objectChanged(): void
    {
    }

    public function setPrice(int $departmentId, int $userId, bool $isCategory, int|string $objectId, int $percentage, ?int $fixedPrice = null): void
    {
        global $db;

        if ($isCategory) {
            $fixedPrice = null;
        }

        $this->removePrice($departmentId, $userId, $isCategory, $objectId);

        if ($percentage <= 0 && $fixedPrice === null) {
            return;
        }

        $objectId = $db->escape_string((string)$objectId);
        $fixedPriceSql = $fixedPrice === null ? 'NULL' : (string)max(0, (int)$fixedPrice);
        $sql = "INSERT INTO {$this->table} (`department_id`, `user_id`, `is_category`, `product_or_category_id`, `percentage`, `fixed_price`)
            VALUES (" . (int)$departmentId . ", " . (int)$userId . ", " . (int)$isCategory . ", '{$objectId}', " . (int)$percentage . ", {$fixedPriceSql})";
        $db->query($sql);
    }

    public function removePrice(int $departmentId, int $userId, bool $isCategory, int|string $objectId): void
    {
        global $db;

        $objectId = $db->escape_string((string)$objectId);
        $sql = "DELETE FROM {$this->table}
            WHERE `department_id` = " . (int)$departmentId . "
              AND `user_id` = " . (int)$userId . "
              AND `is_category` = " . (int)$isCategory . "
              AND `product_or_category_id` = '{$objectId}'";
        $db->query($sql);
    }

    /**
     * @return array<int, array<string, mixed>>
     */
    public function getAllPrices(int $departmentId, int $userId): array
    {
        global $db;

        $sql = "SELECT * FROM {$this->table}
            WHERE `department_id` = " . (int)$departmentId . "
              AND `user_id` = " . (int)$userId . "
            ORDER BY `is_category` DESC, `product_or_category_id` ASC";
        $result = $db->query($sql);
        $prices = [];
        if ($result && $result->num_rows > 0) {
            while ($row = $result->fetch_assoc()) {
                $prices[] = $this->parseRow($row);
            }
        }

        return $prices;
    }

    public function getDirectPriceRow(int $departmentId, int $userId, bool $isCategory, int|string $objectId): ?array
    {
        global $db;

        $objectId = $db->escape_string((string)$objectId);
        $sql = "SELECT * FROM {$this->table}
            WHERE `department_id` = " . (int)$departmentId . "
              AND `user_id` = " . (int)$userId . "
              AND `is_category` = " . (int)$isCategory . "
              AND `product_or_category_id` = '{$objectId}'
            LIMIT 1";
        $result = $db->query($sql);
        if (!$result || $result->num_rows < 1) {
            return null;
        }

        return $this->parseRow($result->fetch_assoc());
    }

    private function parseRow(array $row): array
    {
        $isCategory = (bool)$row['is_category'];

        return [
            'id' => (int)$row['id'],
            'department_id' => (int)$row['department_id'],
            'user_id' => (int)$row['user_id'],
            'is_category' => $isCategory,
            'product_or_category_id' => $isCategory ? (string)$row['product_or_category_id'] : (int)$row['product_or_category_id'],
            'percentage' => (int)$row['percentage'],
            'fixed_price' => array_key_exists('fixed_price', $row) && $row['fixed_price'] !== null ? (int)$row['fixed_price'] : null,
            'created_at' => (string)$row['created_at'],
            'updated_at' => (string)$row['updated_at'],
        ];
    }
}
