-- zyt projection and integration state for the Luoyang pharmacy ERP.
-- Existing-order DDL is guarded because this migration may be resumed after a partial deployment.

SET @schema_name := DATABASE();

SET @ddl := IF(
  EXISTS (
    SELECT 1 FROM information_schema.COLUMNS
    WHERE TABLE_SCHEMA = @schema_name AND TABLE_NAME = 'zyt_tcm_prescription_order'
      AND COLUMN_NAME = 'ej_pharmacy_order_no'
  ),
  'SELECT 1',
  'ALTER TABLE `zyt_tcm_prescription_order` ADD COLUMN `ej_pharmacy_order_no` varchar(40) NULL DEFAULT NULL COMMENT ''Remote ej ERP order number'' AFTER `ship_mode`'
);
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;

SET @ddl := IF(
  EXISTS (
    SELECT 1 FROM information_schema.COLUMNS
    WHERE TABLE_SCHEMA = @schema_name AND TABLE_NAME = 'zyt_tcm_prescription_order'
      AND COLUMN_NAME = 'ej_pharmacy_submit_time'
  ),
  'SELECT 1',
  'ALTER TABLE `zyt_tcm_prescription_order` ADD COLUMN `ej_pharmacy_submit_time` int unsigned NOT NULL DEFAULT 0 AFTER `ej_pharmacy_order_no`'
);
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;

SET @ddl := IF(
  EXISTS (
    SELECT 1 FROM information_schema.COLUMNS
    WHERE TABLE_SCHEMA = @schema_name AND TABLE_NAME = 'zyt_tcm_prescription_order'
      AND COLUMN_NAME = 'ej_pharmacy_status'
  ),
  'SELECT 1',
  'ALTER TABLE `zyt_tcm_prescription_order` ADD COLUMN `ej_pharmacy_status` varchar(32) NOT NULL DEFAULT '''' AFTER `ej_pharmacy_submit_time`'
);
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;

SET @ddl := IF(
  EXISTS (
    SELECT 1 FROM information_schema.COLUMNS
    WHERE TABLE_SCHEMA = @schema_name AND TABLE_NAME = 'zyt_tcm_prescription_order'
      AND COLUMN_NAME = 'ej_pharmacy_review_status'
  ),
  'SELECT 1',
  'ALTER TABLE `zyt_tcm_prescription_order` ADD COLUMN `ej_pharmacy_review_status` varchar(24) NOT NULL DEFAULT '''' AFTER `ej_pharmacy_status`'
);
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;

SET @ddl := IF(
  EXISTS (
    SELECT 1 FROM information_schema.COLUMNS
    WHERE TABLE_SCHEMA = @schema_name AND TABLE_NAME = 'zyt_tcm_prescription_order'
      AND COLUMN_NAME = 'ej_pharmacy_status_version'
  ),
  'SELECT 1',
  'ALTER TABLE `zyt_tcm_prescription_order` ADD COLUMN `ej_pharmacy_status_version` bigint unsigned NOT NULL DEFAULT 0 AFTER `ej_pharmacy_review_status`'
);
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;

SET @ddl := IF(
  EXISTS (
    SELECT 1 FROM information_schema.COLUMNS
    WHERE TABLE_SCHEMA = @schema_name AND TABLE_NAME = 'zyt_tcm_prescription_order'
      AND COLUMN_NAME = 'ej_pharmacy_current_step'
  ),
  'SELECT 1',
  'ALTER TABLE `zyt_tcm_prescription_order` ADD COLUMN `ej_pharmacy_current_step` varchar(100) NOT NULL DEFAULT '''' AFTER `ej_pharmacy_status_version`'
);
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;

SET @ddl := IF(
  EXISTS (
    SELECT 1 FROM information_schema.COLUMNS
    WHERE TABLE_SCHEMA = @schema_name AND TABLE_NAME = 'zyt_tcm_prescription_order'
      AND COLUMN_NAME = 'ej_pharmacy_remark'
  ),
  'SELECT 1',
  'ALTER TABLE `zyt_tcm_prescription_order` ADD COLUMN `ej_pharmacy_remark` varchar(500) NOT NULL DEFAULT '''' AFTER `ej_pharmacy_current_step`'
);
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;

-- Repair a partial deployment that created the order number as NOT NULL DEFAULT ''.
ALTER TABLE `zyt_tcm_prescription_order`
  MODIFY COLUMN `ej_pharmacy_order_no` varchar(40) NULL DEFAULT NULL COMMENT 'Remote ej ERP order number';
UPDATE `zyt_tcm_prescription_order` SET `ej_pharmacy_order_no` = NULL
WHERE `ej_pharmacy_order_no` = '';

SET @ddl := IF(
  EXISTS (
    SELECT 1 FROM information_schema.STATISTICS
    WHERE TABLE_SCHEMA = @schema_name AND TABLE_NAME = 'zyt_tcm_prescription_order'
      AND INDEX_NAME = 'uk_ej_pharmacy_order_no'
  ),
  'SELECT 1',
  'ALTER TABLE `zyt_tcm_prescription_order` ADD UNIQUE KEY `uk_ej_pharmacy_order_no` (`ej_pharmacy_order_no`)'
);
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;

SET @ddl := IF(
  EXISTS (
    SELECT 1 FROM information_schema.STATISTICS
    WHERE TABLE_SCHEMA = @schema_name AND TABLE_NAME = 'zyt_tcm_prescription_order'
      AND INDEX_NAME = 'idx_ej_pharmacy_status'
  ),
  'SELECT 1',
  'ALTER TABLE `zyt_tcm_prescription_order` ADD KEY `idx_ej_pharmacy_status` (`ej_pharmacy_status`,`ej_pharmacy_status_version`)'
);
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;

-- EJ callbacks may carry longer Unicode carrier codes and tracking numbers than the legacy order projection.
ALTER TABLE `zyt_tcm_prescription_order`
  MODIFY COLUMN `express_company` varchar(32) NOT NULL DEFAULT '' COMMENT 'Carrier code',
  MODIFY COLUMN `tracking_number` varchar(100) NOT NULL DEFAULT '' COMMENT 'Tracking number';
ALTER TABLE `zyt_express_tracking`
  MODIFY COLUMN `tracking_number` varchar(100) NOT NULL DEFAULT '' COMMENT 'Tracking number';
ALTER TABLE `zyt_express_trace`
  MODIFY COLUMN `tracking_number` varchar(100) NOT NULL DEFAULT '' COMMENT 'Tracking number';

CREATE TABLE IF NOT EXISTS `zyt_ej_medicine_catalog` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  `medicine_code` varchar(32) NOT NULL,
  `name` varchar(120) NOT NULL,
  `brand` varchar(120) NOT NULL DEFAULT '',
  `unit` varchar(24) NOT NULL,
  `settlement_price` decimal(12,4) NOT NULL DEFAULT 0.0000,
  `retail_price` decimal(12,4) NOT NULL DEFAULT 0.0000,
  `status` tinyint unsigned NOT NULL DEFAULT 1,
  `catalog_version` bigint unsigned NOT NULL DEFAULT 0,
  `remote_deleted` tinyint unsigned NOT NULL DEFAULT 0,
  `create_time` int unsigned NOT NULL DEFAULT 0,
  `update_time` int unsigned NOT NULL DEFAULT 0,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_medicine_code` (`medicine_code`),
  KEY `idx_catalog_version` (`catalog_version`),
  KEY `idx_name_status` (`name`,`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS `zyt_ej_medicine_mapping` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  `local_medicine_id` bigint unsigned NOT NULL,
  `medicine_code` varchar(32) NOT NULL,
  `status` tinyint unsigned NOT NULL DEFAULT 1,
  `operator_id` bigint unsigned NOT NULL DEFAULT 0,
  `operator_name` varchar(80) NOT NULL DEFAULT '',
  `create_time` int unsigned NOT NULL DEFAULT 0,
  `update_time` int unsigned NOT NULL DEFAULT 0,
  `delete_time` int unsigned DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_local_medicine` (`local_medicine_id`),
  UNIQUE KEY `uk_medicine_code` (`medicine_code`),
  KEY `idx_medicine_status` (`medicine_code`,`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

SET @ddl := IF(
  EXISTS (
    SELECT 1 FROM information_schema.STATISTICS
    WHERE TABLE_SCHEMA = @schema_name AND TABLE_NAME = 'zyt_ej_medicine_mapping'
      AND INDEX_NAME = 'uk_medicine_code'
  ),
  'SELECT 1',
  'ALTER TABLE `zyt_ej_medicine_mapping` ADD UNIQUE KEY `uk_medicine_code` (`medicine_code`)'
);
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;

CREATE TABLE IF NOT EXISTS `zyt_ej_pharmacy_submission` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  `prescription_order_id` bigint unsigned NOT NULL,
  `source_revision` int unsigned NOT NULL DEFAULT 1,
  `request_hash` char(64) NOT NULL,
  `request_id` varchar(64) NOT NULL DEFAULT '',
  `remote_order_no` varchar(40) NOT NULL DEFAULT '',
  `status` varchar(24) NOT NULL DEFAULT 'PENDING',
  `http_status` int unsigned NOT NULL DEFAULT 0,
  `response_summary` json DEFAULT NULL,
  `error_message` varchar(1000) NOT NULL DEFAULT '',
  `operator_id` bigint unsigned NOT NULL DEFAULT 0,
  `operator_name` varchar(80) NOT NULL DEFAULT '',
  `create_time` int unsigned NOT NULL DEFAULT 0,
  `update_time` int unsigned NOT NULL DEFAULT 0,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_order_revision` (`prescription_order_id`,`source_revision`),
  KEY `idx_status_time` (`status`,`update_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS `zyt_pharmacy_submission_claim` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  `prescription_order_id` bigint unsigned NOT NULL,
  `source_revision` int unsigned NOT NULL DEFAULT 1,
  `target` varchar(16) NOT NULL,
  `status` varchar(24) NOT NULL DEFAULT 'PENDING',
  `claim_token` char(32) NOT NULL,
  `idempotency_key` char(64) NOT NULL,
  `remote_order_no` varchar(64) NOT NULL DEFAULT '',
  `request_id` varchar(64) NOT NULL DEFAULT '',
  `error_message` varchar(1000) NOT NULL DEFAULT '',
  `operator_id` bigint unsigned NOT NULL DEFAULT 0,
  `operator_name` varchar(80) NOT NULL DEFAULT '',
  `claimed_at` int unsigned NOT NULL DEFAULT 0,
  `lease_expires_at` int unsigned NOT NULL DEFAULT 0,
  `completed_at` int unsigned NOT NULL DEFAULT 0,
  `failed_at` int unsigned NOT NULL DEFAULT 0,
  `create_time` int unsigned NOT NULL DEFAULT 0,
  `update_time` int unsigned NOT NULL DEFAULT 0,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_order_revision` (`prescription_order_id`,`source_revision`),
  UNIQUE KEY `uk_claim_token` (`claim_token`),
  KEY `idx_status_time` (`status`,`update_time`),
  KEY `idx_target_remote` (`target`,`remote_order_no`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

ALTER TABLE `zyt_pharmacy_submission_claim`
  MODIFY COLUMN `status` varchar(24) NOT NULL DEFAULT 'PENDING';

SET @ddl := IF(
  EXISTS (
    SELECT 1 FROM information_schema.COLUMNS
    WHERE TABLE_SCHEMA = @schema_name AND TABLE_NAME = 'zyt_pharmacy_submission_claim'
      AND COLUMN_NAME = 'lease_expires_at'
  ),
  'SELECT 1',
  'ALTER TABLE `zyt_pharmacy_submission_claim` ADD COLUMN `lease_expires_at` int unsigned NOT NULL DEFAULT 0 AFTER `claimed_at`'
);
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;

UPDATE `zyt_pharmacy_submission_claim`
SET `lease_expires_at` = `claimed_at` + 300
WHERE `status` = 'PENDING' AND `lease_expires_at` = 0 AND `claimed_at` > 0;

CREATE TABLE IF NOT EXISTS `zyt_pharmacy_submission_claim_audit` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  `claim_id` bigint unsigned NOT NULL,
  `prescription_order_id` bigint unsigned NOT NULL,
  `source_revision` int unsigned NOT NULL DEFAULT 1,
  `target` varchar(16) NOT NULL,
  `action` varchar(32) NOT NULL,
  `from_status` varchar(24) NOT NULL,
  `to_status` varchar(24) NOT NULL,
  `remote_order_no` varchar(64) NOT NULL DEFAULT '',
  `note` varchar(1000) NOT NULL DEFAULT '',
  `operator_id` bigint unsigned NOT NULL DEFAULT 0,
  `operator_name` varchar(80) NOT NULL DEFAULT '',
  `create_time` int unsigned NOT NULL DEFAULT 0,
  PRIMARY KEY (`id`),
  KEY `idx_claim_time` (`claim_id`,`create_time`),
  KEY `idx_order_time` (`prescription_order_id`,`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS `zyt_ej_pharmacy_callback_inbox` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  `event_id` char(36) NOT NULL,
  `pharmacy_order_no` varchar(40) NOT NULL,
  `source_order_no` varchar(64) NOT NULL,
  `event_type` varchar(48) NOT NULL,
  `status_version` bigint unsigned NOT NULL DEFAULT 0,
  `payload` json NOT NULL,
  `process_status` varchar(24) NOT NULL DEFAULT 'PENDING',
  `processed_time` int unsigned NOT NULL DEFAULT 0,
  `error_message` varchar(1000) NOT NULL DEFAULT '',
  `create_time` int unsigned NOT NULL DEFAULT 0,
  `update_time` int unsigned NOT NULL DEFAULT 0,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_event_id` (`event_id`),
  KEY `idx_process_status` (`process_status`,`id`),
  KEY `idx_order_version` (`pharmacy_order_no`,`status_version`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS `zyt_ej_pharmacy_sync_state` (
  `id` tinyint unsigned NOT NULL,
  `cursor` bigint unsigned NOT NULL DEFAULT 0,
  `last_success_time` int unsigned NOT NULL DEFAULT 0,
  `last_failure_time` int unsigned NOT NULL DEFAULT 0,
  `last_error_summary` varchar(500) NOT NULL DEFAULT '',
  `lock_token` char(32) NOT NULL DEFAULT '',
  `lock_expires_at` int unsigned NOT NULL DEFAULT 0,
  `create_time` int unsigned NOT NULL DEFAULT 0,
  `update_time` int unsigned NOT NULL DEFAULT 0,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

INSERT INTO `zyt_ej_pharmacy_sync_state` (`id`, `cursor`, `create_time`, `update_time`)
VALUES (1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP())
ON DUPLICATE KEY UPDATE `id` = VALUES(`id`);

-- Page sits beside the existing doctor medicine library; API nodes make every endpoint visible to AuthMiddleware.
SET @doctor_medicine_menu_id := (
  SELECT `id`
  FROM `zyt_system_menu`
  WHERE `perms` = 'doctor.medicine/lists'
     OR (`component` = 'doctor/medicine' AND `type` = 'C')
  ORDER BY (`perms` = 'doctor.medicine/lists') DESC, `id` ASC
  LIMIT 1
);
SET @doctor_medicine_parent_id := (
  SELECT `pid` FROM `zyt_system_menu` WHERE `id` = @doctor_medicine_menu_id LIMIT 1
);

INSERT INTO `zyt_system_menu` (
  `pid`, `type`, `name`, `icon`, `sort`, `perms`, `paths`, `component`,
  `selected`, `params`, `is_cache`, `is_show`, `is_disable`, `create_time`, `update_time`
)
SELECT
  @doctor_medicine_parent_id, 'C', '洛阳药房药材映射', '', 0,
  'pharmacy.medicineMapping/lists', 'pharmacy/medicine-mapping', 'pharmacy/medicine_mapping/index',
  '', '', 0, 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
FROM DUAL
WHERE @doctor_medicine_parent_id IS NOT NULL
  AND NOT EXISTS (
    SELECT 1 FROM `zyt_system_menu` WHERE `perms` = 'pharmacy.medicineMapping/lists'
  );

SET @medicine_mapping_menu_id := (
  SELECT `id` FROM `zyt_system_menu` WHERE `perms` = 'pharmacy.medicineMapping/lists' LIMIT 1
);

INSERT INTO `zyt_system_menu` (
  `pid`, `type`, `name`, `icon`, `sort`, `perms`, `paths`, `component`,
  `selected`, `params`, `is_cache`, `is_show`, `is_disable`, `create_time`, `update_time`
)
SELECT
  @medicine_mapping_menu_id, 'A', `permission_node`.`name`, '', `permission_node`.`sort`,
  `permission_node`.`perms`, '', '', '', '', 0, 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
FROM (
  SELECT '查看同步状态' AS `name`, 10 AS `sort`, 'pharmacy.medicineMapping/status' AS `perms`
  UNION ALL SELECT '检索远端药材', 20, 'pharmacy.medicineMapping/catalogOptions'
  UNION ALL SELECT '同步远端目录', 30, 'pharmacy.medicineMapping/sync'
  UNION ALL SELECT '保存药材映射', 40, 'pharmacy.medicineMapping/save'
  UNION ALL SELECT '解除药材映射', 50, 'pharmacy.medicineMapping/unlink'
) AS `permission_node`
WHERE @medicine_mapping_menu_id IS NOT NULL
  AND NOT EXISTS (
    SELECT 1 FROM `zyt_system_menu` AS `existing_menu`
    WHERE `existing_menu`.`perms` = `permission_node`.`perms`
  );

-- New clients use this explicit unified-upload permission. The historical
-- submitGancaoRecipel node remains valid and its controller still routes by ship_mode.
SET @prescription_order_menu_id := (
  SELECT `id` FROM `zyt_system_menu` WHERE `perms` = 'tcm.prescriptionOrder/lists' LIMIT 1
);
INSERT INTO `zyt_system_menu` (
  `pid`, `type`, `name`, `icon`, `sort`, `perms`, `paths`, `component`,
  `selected`, `params`, `is_cache`, `is_show`, `is_disable`, `create_time`, `update_time`
)
SELECT
  @prescription_order_menu_id, 'A', '上传药房', '', 10,
  'tcm.prescriptionOrder/uploadToPharmacy', '', '', '', '', 0, 1, 0,
  UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
FROM DUAL
WHERE @prescription_order_menu_id IS NOT NULL
  AND NOT EXISTS (
    SELECT 1 FROM `zyt_system_menu` WHERE `perms` = 'tcm.prescriptionOrder/uploadToPharmacy'
  );

-- Historical route retained as a controlled compatibility alias for the same pharmacy-upload capability.
INSERT INTO `zyt_system_menu` (
  `pid`, `type`, `name`, `icon`, `sort`, `perms`, `paths`, `component`,
  `selected`, `params`, `is_cache`, `is_show`, `is_disable`, `create_time`, `update_time`
)
SELECT
  @prescription_order_menu_id, 'A', '上传药房（兼容入口）', '', 11,
  'tcm.prescriptionOrder/submitGancaoRecipel', '', '', '', '', 0, 1, 0,
  UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
FROM DUAL
WHERE @prescription_order_menu_id IS NOT NULL
  AND NOT EXISTS (
    SELECT 1 FROM `zyt_system_menu` WHERE `perms` = 'tcm.prescriptionOrder/submitGancaoRecipel'
  );

-- Manual reconciliation can finalize an uncertain remote result or release it for retry,
-- so it requires a separate high-risk permission from ordinary pharmacy upload.
INSERT INTO `zyt_system_menu` (
  `pid`, `type`, `name`, `icon`, `sort`, `perms`, `paths`, `component`,
  `selected`, `params`, `is_cache`, `is_show`, `is_disable`, `create_time`, `update_time`
)
SELECT
  @prescription_order_menu_id, 'A', '人工核对甘草提交', '', 12,
  'tcm.prescriptionOrder/confirmGancaoSubmission', '', '', '', '', 0, 1, 0,
  UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
FROM DUAL
WHERE @prescription_order_menu_id IS NOT NULL
  AND NOT EXISTS (
    SELECT 1 FROM `zyt_system_menu` WHERE `perms` = 'tcm.prescriptionOrder/confirmGancaoSubmission'
  );
