-- ============================================================================
--  2026_sprint30c_loop.sql — اسپرینت ۳۰ (فاز ۳): بستنِ حلقهٔ عملیاتیِ بیمار
-- ----------------------------------------------------------------------------
--  ✦ ۱۰۰٪ ADDITIVE و idempotent. config.php دست‌نخورده. اجرای مجدد امن.
--  ✦ شمارهٔ پروندهٔ concurrency-safe، قیمت‌گذاریِ تجاریِ کانتر پرویزی + ممیزی،
--     پیوندِ آیتمِ فاکتور ↔ آیتمِ پلن (ضدتکرار)، مسیریابیِ per-آیتمِ پس‌از‌پرداخت،
--     جدولِ اصلاحاتِ مجاز (ممیزی)، و گِیتِ عکس.
-- ============================================================================
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ── شمارندهٔ اتمیک (برای شمارهٔ پروندهٔ concurrency-safe) ──
CREATE TABLE IF NOT EXISTS `cw_counters` (
  `name` VARCHAR(40) NOT NULL,
  `val`  BIGINT UNSIGNED NOT NULL DEFAULT 0,
  `updated_at` DATETIME DEFAULT NULL,
  PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- مقداردهیِ اولیه‌ی شمارندهٔ شمارهٔ پرونده = max(بیشترین عددِ موجود, file_number_seed)
INSERT INTO `cw_counters` (`name`,`val`,`updated_at`)
SELECT 'file_number',
  GREATEST(
    COALESCE((SELECT MAX(CAST(file_number AS UNSIGNED)) FROM cw_patients WHERE file_number REGEXP '^[0-9]+$'),0),
    COALESCE((SELECT CAST(v AS UNSIGNED) FROM cw_settings WHERE k='file_number_seed'),0)
  ), NOW()
FROM DUAL
WHERE NOT EXISTS (SELECT 1 FROM `cw_counters` WHERE `name`='file_number');

-- ── پیوندِ آیتمِ فاکتور به آیتمِ پلن (ردیابی + ضدتکرارِ صورت‌حساب) ──
SET @c:=(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='cw_payment_items' AND COLUMN_NAME='plan_item_id');
SET @s:=IF(@c=0,"ALTER TABLE `cw_payment_items` ADD COLUMN `plan_item_id` BIGINT UNSIGNED DEFAULT NULL AFTER `service_id`, ADD INDEX `idx_planitem` (`plan_item_id`)",'SELECT 1'); PREPARE st FROM @s; EXECUTE st; DEALLOCATE PREPARE st;

-- ── قیمت‌گذاریِ تجاریِ کانتر پرویزی (بدونِ دست‌زدن به قیمتِ پیشنهادیِ پزشک) ──
-- proposed_price = قیمتِ پیشنهادیِ پزشک (تغییرناپذیر) · commercial_price = قیمتِ نهاییِ تجاری
SET @c:=(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='cw_consult_plan_items' AND COLUMN_NAME='proposed_price');
SET @s:=IF(@c=0,"ALTER TABLE `cw_consult_plan_items`
   ADD COLUMN `proposed_price` BIGINT DEFAULT NULL AFTER `price`,
   ADD COLUMN `commercial_price` BIGINT DEFAULT NULL AFTER `final_price`,
   ADD COLUMN `discount_amount` BIGINT NOT NULL DEFAULT 0 AFTER `commercial_price`,
   ADD COLUMN `discount_reason` VARCHAR(255) DEFAULT NULL AFTER `discount_amount`,
   ADD COLUMN `priced_by` INT UNSIGNED DEFAULT NULL AFTER `discount_reason`,
   ADD COLUMN `priced_at` DATETIME DEFAULT NULL AFTER `priced_by`",'SELECT 1'); PREPARE st FROM @s; EXECUTE st; DEALLOCATE PREPARE st;
-- بک‌فیل: قیمتِ پیشنهادیِ پزشک را از price فعلی نگه‌دار (فقط اگر خالی است)
UPDATE `cw_consult_plan_items` SET `proposed_price`=`price` WHERE `proposed_price` IS NULL;
UPDATE `cw_consult_plan_items` SET `commercial_price`=`final_price` WHERE `commercial_price` IS NULL;

CREATE TABLE IF NOT EXISTS `cw_plan_item_price_log` (
  `id`         BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `item_id`    BIGINT UNSIGNED NOT NULL,
  `visit_id`   INT UNSIGNED DEFAULT NULL,
  `patient_id` INT UNSIGNED DEFAULT NULL,
  `old_price`  BIGINT DEFAULT NULL,
  `new_price`  BIGINT DEFAULT NULL,
  `discount`   BIGINT NOT NULL DEFAULT 0,
  `reason`     VARCHAR(255) DEFAULT NULL,
  `changed_by` INT UNSIGNED DEFAULT NULL,
  `created_at` DATETIME NOT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_item` (`item_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- ── مسیریابیِ per-آیتمِ خدمتِ انجام‌شده (پس‌از‌پرداخت) ──
SET @c:=(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='cw_performed_services' AND COLUMN_NAME='plan_item_id');
SET @s:=IF(@c=0,"ALTER TABLE `cw_performed_services`
   ADD COLUMN `plan_item_id` BIGINT UNSIGNED DEFAULT NULL AFTER `service_id`,
   ADD COLUMN `payment_id` INT UNSIGNED DEFAULT NULL AFTER `plan_item_id`,
   ADD COLUMN `source_dept` VARCHAR(24) DEFAULT NULL AFTER `room`,
   ADD COLUMN `session_no` INT DEFAULT NULL AFTER `source_dept`,
   ADD COLUMN `total_sessions` INT DEFAULT NULL AFTER `session_no`,
   ADD COLUMN `aftercare_sent` TINYINT(1) NOT NULL DEFAULT 0 AFTER `total_sessions`,
   ADD INDEX `idx_planitem` (`plan_item_id`)",'SELECT 1'); PREPARE st FROM @s; EXECUTE st; DEALLOCATE PREPARE st;

-- ── اصلاحاتِ مجاز (ممیزیِ عمومی: لینکِ اشتباهِ بیمار/نوبت/ارجاع/تصمیم/قیمت/فاکتور/وضعیت) ──
CREATE TABLE IF NOT EXISTS `cw_corrections` (
  `id`          BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `entity`      VARCHAR(30)  NOT NULL,   -- patient_link|appointment|referral|decision|price|invoice_item|status|other
  `ref_id`      BIGINT UNSIGNED DEFAULT NULL,
  `visit_id`    INT UNSIGNED DEFAULT NULL,
  `patient_id`  INT UNSIGNED DEFAULT NULL,
  `old_value`   TEXT DEFAULT NULL,
  `new_value`   TEXT DEFAULT NULL,
  `reason`      VARCHAR(255) NOT NULL,
  `corrected_by`INT UNSIGNED DEFAULT NULL,
  `created_at`  DATETIME NOT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_entity` (`entity`),
  KEY `idx_visit` (`visit_id`),
  KEY `idx_patient` (`patient_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- ── تنظیمات: اجبارِ گِیتِ عکس ──
INSERT IGNORE INTO `cw_settings` (`k`,`v`,`updated_at`) VALUES
 ('photo_gate_enforce','1',NOW());

SET FOREIGN_KEY_CHECKS = 1;
-- ============================================================================
--  ROLLBACK (دستی):
--   DROP TABLE IF EXISTS `cw_corrections`,`cw_plan_item_price_log`,`cw_counters`;
--   ALTER TABLE `cw_payment_items` DROP COLUMN `plan_item_id`;
--   ALTER TABLE `cw_consult_plan_items` DROP COLUMN `proposed_price`, DROP COLUMN `commercial_price`,
--     DROP COLUMN `discount_amount`, DROP COLUMN `discount_reason`, DROP COLUMN `priced_by`, DROP COLUMN `priced_at`;
--   ALTER TABLE `cw_performed_services` DROP COLUMN `plan_item_id`, DROP COLUMN `payment_id`,
--     DROP COLUMN `source_dept`, DROP COLUMN `session_no`, DROP COLUMN `total_sessions`, DROP COLUMN `aftercare_sent`;
-- ============================================================================
