<?php

declare(strict_types=1);

/**
 * 本文件属于 DBErp 进销存系统。
 *
 * 版权所有 © 2026 北京珑大钜商科技有限公司。保留所有权利。
 *
 * 未经官方授权，不得删除、篡改或隐藏本文件中的版权声明、产品标识与来源信息。
 * 商业授权、官方更新与技术支持服务，请以珑大官方支持中心记录为准。
 *
 * @link https://support.loongdom.cn
 * @see  https://www.dberp.com.cn
 */

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

/**
 * 基础能力：编号规则、字典、地区、系统档案、集成映射与同步日志（合并原 170000–171127、170003、230000、site_filing 等）。
 */
return new class extends Migration
{
    public function up(): void
    {
        Schema::create('dberp_number_sequences', function (Blueprint $table): void {
            $table->id();
            $table->string('code', 64)->comment('业务内唯一编码');
            $table->string('applies_to', 64)->default('other')->comment('适用范围（内部键，界面展示中文）');
            $table->string('name')->comment('规则名称');
            $table->string('prefix', 32)->default('')->comment('前缀');
            $table->string('date_segment', 32)->default('none')->comment('日期片段：无/年月日等');
            $table->unsignedTinyInteger('serial_digits')->default(6)->comment('流水号位数');
            $table->boolean('is_enabled')->default(true)->comment('是否启用');
            $table->text('remark')->nullable()->comment('备注');
            $table->string('pattern', 512)->nullable()->comment('编号模板/规则串，占位');
            $table->unsignedBigInteger('next_value')->default(1);
            $table->unsignedInteger('sort_order')->default(0)->comment('越小越靠前');
            $table->timestamps();

            $table->unique('code', 'uq_dberp_numseq_code');
            $table->index(['applies_to', 'is_enabled'], 'idx_dberp_numseq_scope_enabled');
        });

        Schema::create('dberp_dictionary_types', function (Blueprint $table): void {
            $table->id();
            $table->string('code', 64)->comment('类型编码');
            $table->string('name')->comment('类型名称');
            $table->text('description')->nullable()->comment('类型说明');
            $table->unsignedInteger('sort_order')->default(0)->comment('越小越靠前');
            $table->boolean('is_delete_locked')->default(false)->comment('禁止删除（系统预置类型）');
            $table->timestamps();

            $table->unique('code', 'uq_dberp_dict_type_code');
        });

        Schema::create('dberp_dictionary_items', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('type_id')->constrained('dberp_dictionary_types')->cascadeOnDelete();
            $table->string('code', 64)->comment('项编码（同类型下唯一）');
            $table->string('label')->comment('展示名称');
            $table->string('value', 512)->nullable()->comment('业务值/扩展值');
            $table->boolean('is_enabled')->default(true)->comment('是否启用');
            $table->text('description')->nullable()->comment('说明');
            $table->boolean('is_system_preset')->default(false)->comment('系统预置');
            $table->boolean('is_delete_locked')->default(false)->comment('禁止删除');
            $table->unsignedInteger('sort_order')->default(0)->comment('越小越靠前');
            $table->timestamps();

            $table->unique(['type_id', 'code'], 'uq_dberp_dict_item_type_code');
            $table->index('type_id', 'idx_dberp_dict_item_type');
            $table->index(['type_id', 'is_enabled', 'sort_order'], 'idx_dberp_dict_item_type_enabled_sort');
        });

        Schema::create('dberp_integration_sync_logs', function (Blueprint $table): void {
            $table->id();
            $table->string('channel', 32)->comment('渠道标识，如 dbshop');
            $table->string('direction', 16)->comment('inbound|outbound 等');
            $table->string('status', 32)->comment('pending|success|failed 等占位');
            $table->string('reference', 128)->nullable()->comment('外部或内部关联单号');
            $table->string('source_document_no', 128)->nullable()->comment('来源单号/业务单号');
            $table->string('external_reference', 128)->nullable()->comment('外部单号/外部标识');
            $table->text('message')->nullable()->comment('摘要信息');
            $table->string('error_type', 64)->nullable()->comment('错误类型');
            $table->string('result_summary', 255)->nullable()->comment('本次结果摘要');
            $table->json('context')->nullable()->comment('扩展上下文，注意脱敏');
            $table->string('sync_object_type', 32)->nullable();
            $table->string('source_system', 32)->nullable();
            $table->string('target_system', 32)->nullable()->default('dberp');
            $table->string('related_model_type')->nullable();
            $table->unsignedBigInteger('related_model_id')->nullable();
            $table->unsignedInteger('retry_count')->default(0);
            $table->dateTime('latest_retry_at')->nullable();
            $table->string('latest_retry_status', 32)->nullable();
            $table->string('latest_retry_message', 255)->nullable();
            $table->timestamp('created_at')->useCurrent();
            $table->timestamp('updated_at')->nullable();

            $table->index(['channel', 'created_at'], 'idx_dberp_intlog_ch_time');
            $table->index(['source_system', 'sync_object_type', 'status'], 'idx_dberp_intlog_obj_status');
            $table->index(['related_model_type', 'related_model_id'], 'idx_dberp_intlog_related');
            $table->index(['source_system', 'sync_object_type', 'error_type'], 'idx_dberp_intlog_err');
            $table->index('source_document_no', 'idx_dberp_intlog_srcdoc');
            $table->index('external_reference', 'idx_dberp_intlog_extref');
        });

        Schema::create('dberp_integration_mappings', function (Blueprint $table): void {
            $table->id();
            $table->string('source_system', 32)->comment('来源系统，如 dbshop');
            $table->string('target_system', 32)->default('dberp')->comment('目标系统，默认 dberp');
            $table->string('object_type', 32)->comment('product|product_category|customer|order 等');
            $table->string('local_model_type')->nullable()->comment('本地模型类型');
            $table->unsignedBigInteger('local_model_id')->nullable()->comment('本地模型主键');
            $table->string('external_id', 128)->comment('外部主键');
            $table->string('external_code', 128)->nullable()->comment('外部编码/单号');
            $table->string('external_name')->nullable()->comment('外部名称');
            $table->string('external_parent_id', 128)->nullable()->comment('外部父级 ID');
            $table->string('external_sku', 128)->nullable()->comment('外部 SKU');
            $table->string('external_spec')->nullable()->comment('外部规格快照');
            $table->string('status', 32)->default('matched')->comment('matched|synced|failed');
            $table->string('match_strategy', 32)->nullable()->comment('mapping|barcode|mobile|manual 等');
            $table->string('governance_note', 255)->nullable()->comment('治理备注');
            $table->string('last_error_type', 64)->nullable()->comment('最近错误类型');
            $table->string('last_error_message', 255)->nullable()->comment('最近错误摘要');
            $table->string('source_document_no', 128)->nullable()->comment('来源单号');
            $table->json('mapping_payload')->nullable()->comment('扩展承载，注意脱敏');
            $table->dateTime('last_synced_at')->nullable();
            $table->dateTime('invalidated_at')->nullable()->comment('失效时间');
            $table->timestamps();

            $table->unique(['source_system', 'object_type', 'external_id'], 'uq_dberp_int_map_ext');
            $table->index(['local_model_type', 'local_model_id'], 'idx_dberp_int_map_local');
            $table->index(['source_system', 'object_type', 'status'], 'idx_dberp_int_map_status');
            $table->index(['source_system', 'object_type', 'last_error_type'], 'idx_dberp_intmap_err');
        });

        Schema::create('dberp_regions', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('parent_id')->nullable()->constrained('dberp_regions')->restrictOnDelete();
            $table->string('country_code', 8)->comment('国家代码');
            $table->string('region_code', 64)->comment('系统地区编码');
            $table->string('external_code', 32)->nullable()->comment('外部标准码');
            $table->string('name', 160)->comment('地区名称');
            $table->string('short_name', 120)->nullable()->comment('简称');
            $table->string('level', 32)->comment('层级');
            $table->unsignedTinyInteger('depth')->default(1)->comment('层级深度，国家=1');
            $table->string('path', 255)->comment('层级路径');
            $table->string('merger_name', 255)->comment('完整层级名称');
            $table->string('remark', 500)->nullable()->comment('备注');
            $table->unsignedInteger('sort_order')->default(0)->comment('越小越靠前');
            $table->boolean('is_enabled')->default(true)->comment('启停状态');
            $table->boolean('is_leaf')->default(true)->comment('是否叶子节点');
            $table->string('source', 64)->default('manual')->comment('数据来源');
            $table->timestamps();

            $table->unique('region_code', 'uq_dberp_region_code');
            $table->unique(['country_code', 'external_code'], 'uq_dberp_region_country_ext');
            $table->index(['parent_id', 'sort_order', 'id'], 'idx_dberp_region_parent_sort');
            $table->index(['country_code', 'level', 'is_enabled'], 'idx_dberp_region_country_lvl');
            $table->index(['is_enabled', 'sort_order', 'id'], 'idx_dberp_region_enabled_sort');
            $table->index('name', 'idx_dberp_region_name');
            $table->index('external_code', 'idx_dberp_region_ext');
            $table->index('path', 'idx_dberp_region_path');
        });

        Schema::create('dberp_system_profile', function (Blueprint $table): void {
            $table->id();

            $table->string('company_name')->default('')->comment('企业名称');
            $table->string('system_display_name')->default('')->comment('系统对外展示名称');
            $table->string('contact_phone', 64)->nullable()->comment('联系电话');
            $table->string('contact_email', 128)->nullable()->comment('联系邮箱');
            $table->string('address', 255)->nullable()->comment('详细地址');
            $table->string('country_code', 8)->nullable()->comment('国家代码');
            $table->foreignId('region_id')->nullable()->comment('地区节点')->constrained('dberp_regions')->nullOnDelete();
            $table->string('region_name_snapshot', 255)->nullable()->comment('地区展示快照');
            $table->string('site_icp_record_no', 64)->nullable()->comment('网站备案号（登录页展示，链至工信部备案平台）');
            $table->string('site_public_security_record_no', 128)->nullable()->comment('公安备案号（登录页展示，链至公安备案平台）');

            $table->string('default_currency_code', 8)->default('CNY')->comment('默认货币');
            $table->unsignedTinyInteger('amount_decimal_places')->default(2)->comment('金额小数位数');
            $table->unsignedTinyInteger('quantity_decimal_places')->default(2)->comment('数量小数位数');

            $table->boolean('allow_negative_stock')->default(false)->comment('允许负库存');
            $table->unsignedBigInteger('default_warehouse_id')->nullable()->comment('默认仓库（预留关联）');
            $table->foreignId('default_source_type_item_id')
                ->nullable()
                ->constrained('dberp_dictionary_items')
                ->nullOnDelete()
                ->comment('默认来源类型（字典项）');

            $table->string('document_void_policy', 64)->default('restore_stock_and_finance')->comment('单据作废冲回规则');
            $table->string('payment_over_limit_policy', 64)->default('forbid')->comment('收付款超额限制');
            $table->string('receipt_over_limit_policy', 64)->default('forbid')->comment('收款超额限制');
            $table->boolean('allow_settlement_on_closed_document')->default(false)->comment('单据关闭后允许继续登记收付款');
            $table->string('settlement_void_policy', 64)->default('rollback')->comment('结算单作废冲回规则');
            $table->boolean('safety_stock_alert_enabled')->default(false)->comment('安全库存预警（预留）');

            $table->timestamps();
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('dberp_system_profile');
        Schema::dropIfExists('dberp_regions');
        Schema::dropIfExists('dberp_integration_mappings');
        Schema::dropIfExists('dberp_integration_sync_logs');
        Schema::dropIfExists('dberp_dictionary_items');
        Schema::dropIfExists('dberp_dictionary_types');
        Schema::dropIfExists('dberp_number_sequences');
    }
};
