<?php
/**
 * acc-schema.php — نصب/ارتقای جداول هسته ai_acc_*
 */
if ( ! defined( 'ABSPATH' ) ) exit;

class Acc_Schema {

    public static function ensure_core_tables(): void {
        global $wpdb;
        $pre     = $wpdb->prefix;
        $charset = $wpdb->get_charset_collate();

        $upgrade = ABSPATH . 'wp-admin/includes/upgrade.php';
        if ( is_readable( $upgrade ) ) {
            require_once $upgrade;
            self::_dbdelta_tables( $pre, $charset );
        } else {
            self::_raw_create_tables( $pre, $charset );
        }

        self::_seed_dimension_groups();
    }

    private static function _table_sql( string $pre, string $charset ): array {
        return [
            "CREATE TABLE {$pre}ai_acc_dimension_groups (
                id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
                group_code VARCHAR(50) NOT NULL,
                group_name VARCHAR(100) NOT NULL,
                description TEXT NULL,
                sort_order INT NOT NULL DEFAULT 0,
                is_active TINYINT(1) NOT NULL DEFAULT 1,
                created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
                PRIMARY KEY (id),
                UNIQUE KEY group_code (group_code)
            ) {$charset}",
            "CREATE TABLE {$pre}ai_acc_dimensions (
                id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
                group_id BIGINT UNSIGNED NOT NULL,
                dim_code VARCHAR(50) NOT NULL,
                dim_name VARCHAR(200) NOT NULL,
                data_type VARCHAR(20) NOT NULL DEFAULT 'string',
                is_active TINYINT(1) NOT NULL DEFAULT 1,
                created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
                PRIMARY KEY (id),
                KEY group_id (group_id)
            ) {$charset}",
            "CREATE TABLE {$pre}ai_acc_dimension_values (
                id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
                dim_id BIGINT UNSIGNED NOT NULL,
                value_code VARCHAR(80) NOT NULL,
                value_name VARCHAR(200) NOT NULL,
                parent_value_id BIGINT UNSIGNED NULL,
                is_active TINYINT(1) NOT NULL DEFAULT 1,
                created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
                PRIMARY KEY (id),
                KEY dim_id (dim_id),
                KEY value_code (value_code)
            ) {$charset}",
            "CREATE TABLE {$pre}ai_acc_gl_dim_rules (
                id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
                gl_id INT NOT NULL,
                group_id BIGINT UNSIGNED NOT NULL,
                is_required TINYINT(1) NOT NULL DEFAULT 1,
                PRIMARY KEY (id),
                UNIQUE KEY gl_group (gl_id, group_id)
            ) {$charset}",
            "CREATE TABLE {$pre}ai_acc_event_templates (
                id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
                event_type VARCHAR(100) NOT NULL,
                version INT NOT NULL DEFAULT 1,
                template_name VARCHAR(200) NULL,
                mapping_logic LONGTEXT NOT NULL,
                description TEXT NULL,
                is_active TINYINT(1) NOT NULL DEFAULT 1,
                created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
                updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
                PRIMARY KEY (id),
                UNIQUE KEY type_ver (event_type, version),
                KEY type_active (event_type, is_active)
            ) {$charset}",
            "CREATE TABLE {$pre}ai_acc_events (
                id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
                event_type VARCHAR(100) NOT NULL,
                event_payload LONGTEXT NULL,
                metadata LONGTEXT NULL,
                workflow_state VARCHAR(20) NOT NULL DEFAULT 'pending',
                template_version INT NULL,
                amount DECIMAL(18,2) NOT NULL DEFAULT 0,
                dimension_id BIGINT UNSIGNED NULL,
                reference_type VARCHAR(100) NULL,
                reference_id BIGINT UNSIGNED NULL,
                idempotency_key VARCHAR(128) NULL,
                error_message TEXT NULL,
                posted_at DATETIME NULL,
                posted_mapping_json LONGTEXT NULL,
                reverses_event_id BIGINT UNSIGNED NULL,
                reversed_by_event_id BIGINT UNSIGNED NULL,
                source_module VARCHAR(40) NULL,
                description VARCHAR(500) NULL,
                status VARCHAR(20) NULL,
                created_by BIGINT UNSIGNED NULL,
                created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
                PRIMARY KEY (id),
                UNIQUE KEY idempotency_key (idempotency_key),
                KEY workflow_state (workflow_state),
                KEY event_type (event_type),
                KEY ref (reference_type, reference_id)
            ) {$charset}",
            "CREATE TABLE {$pre}ai_acc_flows (
                id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
                event_id BIGINT UNSIGNED NOT NULL,
                from_account_id INT NOT NULL,
                to_account_id INT NOT NULL,
                amount DECIMAL(18,2) NOT NULL DEFAULT 0,
                description VARCHAR(500) NULL,
                dimension_id BIGINT UNSIGNED NULL,
                entry_pair_id VARCHAR(64) NULL,
                line_no INT NULL,
                tag_json LONGTEXT NULL,
                is_confirmed TINYINT(1) NOT NULL DEFAULT 0,
                created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
                PRIMARY KEY (id),
                KEY event_id (event_id),
                KEY confirmed (is_confirmed)
            ) {$charset}",
            "CREATE TABLE {$pre}ai_acc_articles (
                id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
                article_code VARCHAR(60) NOT NULL,
                label VARCHAR(200) NOT NULL,
                dr_account_id INT NOT NULL,
                cr_account_id INT NOT NULL,
                amount_source VARCHAR(80) NULL,
                category VARCHAR(60) NULL,
                is_active TINYINT(1) NOT NULL DEFAULT 1,
                created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
                PRIMARY KEY (id),
                UNIQUE KEY article_code (article_code)
            ) {$charset}",
        ];
    }

    private static function _dbdelta_tables( string $pre, string $charset ): void {
        foreach ( self::_table_sql( $pre, $charset ) as $sql ) {
            dbDelta( $sql . ';' );
        }
    }

    private static function _raw_create_tables( string $pre, string $charset ): void {
        global $wpdb;
        foreach ( self::_table_sql( $pre, $charset ) as $sql ) {
            $wpdb->query( preg_replace( '/^CREATE TABLE /', 'CREATE TABLE IF NOT EXISTS ', $sql, 1 ) );
        }
    }

    private static function _seed_dimension_groups(): void {
        global $wpdb;
        $pre = $wpdb->prefix;
        $groups = [
            [ 'PARTY', 'طرف حساب', 'مشتری، تأمین‌کننده، بانک' ],
            [ 'PROJECT', 'پروژه', 'پروژه و قرارداد' ],
            [ 'COST_CENTER', 'مرکز هزینه', 'سربار و بخش‌ها' ],
            [ 'PERSONNEL', 'پرسنل', 'کارشناس و پرسنل' ],
            [ 'BRANCH', 'شعبه', 'دفتر و شعبه خدماتی' ],
            [ 'DEPT', 'واحد سازمانی', 'دپارتمان' ],
            [ 'PRODUCT', 'محصول/خدمت', 'کالا و خدمت' ],
        ];
        foreach ( $groups as [ $code, $name, $desc ] ) {
            if ( ! $wpdb->get_var( $wpdb->prepare(
                "SELECT id FROM {$pre}ai_acc_dimension_groups WHERE group_code=%s", $code
            ) ) ) {
                $wpdb->insert( "{$pre}ai_acc_dimension_groups", [
                    'group_code' => $code, 'group_name' => $name, 'description' => $desc, 'sort_order' => 10,
                ] );
            }
        }
    }
}
