<?php
/**
 * TaxClass — Tax class data access.
 *
 * Tax classes are the bridge between products and tax rates.
 * A product has a tax_class_id; tax rates are defined per class + zone.
 *
 * DB tables:
 *   tc_tax_classes              — id, handle, status
 *   tc_tax_class_translations   — id, class_id, language_code, name
 *
 * @package TitanCart\Modules\Tax
 */

namespace TitanCart\Modules\Tax;

use TitanCart\DB\Database;

defined( 'ABSPATH' ) || exit;

class TaxClass {

    private Database $db;

    public function __construct() {
        $this->db = titancart_db();
    }

    // ══════════════════════════════════════════════════════════════════════════
    // READ
    // ══════════════════════════════════════════════════════════════════════════

    /**
     * Return all active tax classes with translated names.
     *
     * @param  string $lang
     * @return array[]
     */
    public function get_all( string $lang = 'en' ): array {
        $classes = $this->db->getArray(
            "SELECT c.*,
                    COALESCE(
                        (SELECT name FROM {$this->db->table('tax_class_translations')}
                         WHERE class_id = c.id AND language_code = ?s LIMIT 1),
                        (SELECT name FROM {$this->db->table('tax_class_translations')}
                         WHERE class_id = c.id AND language_code = 'en' LIMIT 1),
                        c.handle
                    ) AS name
             FROM {$this->db->table('tax_classes')} c
             WHERE c.status = 'active'
             ORDER BY c.id ASC",
            $lang
        );

        return $classes;
    }

    /**
     * Return a single class or null.
     *
     * @param  int    $id
     * @param  string $lang
     * @return array|null
     */
    public function get_by_id( int $id, string $lang = 'en' ): ?array {
        return $this->db->getRow(
            "SELECT c.*,
                    COALESCE(
                        (SELECT name FROM {$this->db->table('tax_class_translations')}
                         WHERE class_id = c.id AND language_code = ?s LIMIT 1),
                        (SELECT name FROM {$this->db->table('tax_class_translations')}
                         WHERE class_id = c.id AND language_code = 'en' LIMIT 1),
                        c.handle
                    ) AS name
             FROM {$this->db->table('tax_classes')} c
             WHERE c.id = ?i LIMIT 1",
            $lang,
            $id
        );
    }

    /**
     * Return a class by its handle string.
     *
     * @param  string $handle
     * @return array|null
     */
    public function get_by_handle( string $handle ): ?array {
        return $this->db->getRow(
            "SELECT * FROM {$this->db->table('tax_classes')} WHERE handle = ?s LIMIT 1",
            $handle
        );
    }

    // ══════════════════════════════════════════════════════════════════════════
    // WRITE
    // ══════════════════════════════════════════════════════════════════════════

    /**
     * Create a tax class.
     *
     * @param  array   $data          {handle, status?}
     * @param  array[] $translations  { 'en' => ['name' => ...], ... }
     * @return int  New class ID.
     */
    public function create( array $data, array $translations = [] ): int {
        $handle = sanitize_key( $data['handle'] ?? '' );

        if ( $handle === '' ) {
            return 0;
        }

        // KI-84: the default must appear on BOTH sides. `in_array( $data['x'] ?? 'd', … )`
        // tests the DEFAULT, so an absent (or explicitly NULL) key PASSES the test and
        // falls into the true-branch — which must repeat the `??`. Returning $data['x']
        // raw there yields an undefined index ⇒ NULL ⇒ a NOT NULL column. See KI-82.
        $status          = in_array( $data['status'] ?? 'active', [ 'active', 'disabled' ], true ) ? ( $data['status'] ?? 'active' ) : 'active';
        $reg_number      = sanitize_text_field( $data['registration_number'] ?? '' );
        $priority        = (int) ( $data['priority'] ?? 0 );
        $rates_depend_on = in_array( $data['rates_depend_on'] ?? 'shipping', [ 'shipping', 'billing' ], true ) ? ( $data['rates_depend_on'] ?? 'shipping' ) : 'shipping';
        $includes_tax    = ! empty( $data['price_includes_tax'] ) ? 1 : 0;

        $this->db->query(
            "INSERT INTO {$this->db->table('tax_classes')}
             (handle, registration_number, priority, rates_depend_on, price_includes_tax, status)
             VALUES (?s, ?s, ?i, ?s, ?i, ?s)",
            $handle, $reg_number, $priority, $rates_depend_on, $includes_tax, $status
        );

        $id = $this->db->lastInsertId();

        foreach ( $translations as $lang_code => $t ) {
            $this->save_translation( $id, $lang_code, $t );
        }

        return $id;
    }

    /**
     * Update a tax class.
     *
     * @param  int     $id
     * @param  array   $data
     * @param  array[] $translations
     * @return bool
     */
    public function update( int $id, array $data, array $translations = [] ): bool {
        $allowed = [ 'handle', 'status', 'registration_number', 'priority', 'rates_depend_on', 'price_includes_tax' ];
        $fields  = array_intersect_key( $data, array_flip( $allowed ) );

        if ( isset( $fields['handle'] ) ) {
            $fields['handle'] = sanitize_key( $fields['handle'] );
        }

        if ( ! empty( $fields ) ) {
            $this->db->query(
                "UPDATE {$this->db->table('tax_classes')} SET ?u WHERE id = ?i",
                $fields,
                $id
            );
        }

        foreach ( $translations as $lang_code => $t ) {
            $this->save_translation( $id, $lang_code, $t );
        }

        return true;
    }

    /**
     * Soft-disable a tax class.
     *
     * @param  int $id
     * @return bool
     */
    public function disable( int $id ): bool {
        $this->db->query(
            "UPDATE {$this->db->table('tax_classes')} SET status = 'disabled' WHERE id = ?i",
            $id
        );
        return true;
    }

    // ══════════════════════════════════════════════════════════════════════════
    // TRANSLATIONS
    // ══════════════════════════════════════════════════════════════════════════

    /**
     * Upsert a translation row.
     *
     * @param  int    $class_id
     * @param  string $lang_code
     * @param  array  $t  {name}
     */
    public function save_translation( int $class_id, string $lang_code, array $t ): void {
        $this->db->query(
            "INSERT INTO {$this->db->table('tax_class_translations')}
             (class_id, language_code, name)
             VALUES (?i, ?s, ?s)
             ON DUPLICATE KEY UPDATE name = VALUES(name)",
            $class_id,
            $lang_code,
            sanitize_text_field( $t['name'] ?? '' )
        );
    }
}
