-- ============================================================================
--  2026_sprint30_unified_paperless_workflow.sql — اسپرینت ۳۰
--  «کلینیک پیپرلسِ متصل»: کیف‌پول/شادی‌کلاب، کدهدیه، امتیاز ارزشمندی (دوگانه)،
--  نرخ ارز، پلنِ ساختاریافته‌ی مشاوره + تصمیمِ کانتر پرویزی، الزامِ عکس،
--  الگوریتمِ تخصیصِ پرستار، ارتقاء CRM کال‌سنتر (نتیجه‌ی تماس/کلیم/پیگیری)،
--  تسک‌های تماس (تولد/VIP/پیگیری)، اسکریپت/دانشِ پروسیجر، لاگِ sync سایت،
--  و اسکلتِ ایمپورتِ آینده از «سلاک طب».
-- ----------------------------------------------------------------------------
--  ✦ ۱۰۰٪ ADDITIVE و idempotent. هیچ جدول/ستون/داده‌ای حذف یا بازنویسی نمی‌شود.
--  ✦ روی همان دیتابیسِ shadicli_nurse اجرا شود (phpMyAdmin → SQL → Go).
--  ✦ اجرای مجدد امن است (IF NOT EXISTS + گاردِ information_schema برای ALTER).
--  ✦ ستون فقرات همان cw_visits/cw_visit_log و cw_set_status() باقی می‌ماند؛
--     این اسپرینت فقط «زیرسیستم‌های جدید» را کنارِ آن اضافه می‌کند.
--  ✦ Rollback در انتهای فایل (جداگانه اجرا شود).
-- ============================================================================
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ╔══════════════════════════════════════════════════════════════════════════╗
-- ║ ۰) گاردِ افزودنِ ستون (تکرارِ الگوی خودِ پروژه به‌صورتِ رویه‌ی کمکی نیست،   ║
-- ║    بلکه هر ALTER با information_schema محافظت می‌شود تا اجرای مجدد امن باشد)║
-- ╚══════════════════════════════════════════════════════════════════════════╝

-- ───────────────────────── ۱) کیف‌پول / موجودیِ حساب ────────────────────────
-- منبعِ حقیقت = دفترِ تراکنش‌ها (cw_wallet_tx). موجودیِ نقدیِ کش‌شده روی cw_patients
-- برای نمایشِ سریع نگه‌داری می‌شود و در هر تراکنش به‌روزرسانی می‌گردد.
SET @c:=(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='cw_patients' AND COLUMN_NAME='wallet_balance');
SET @s:=IF(@c=0,'ALTER TABLE `cw_patients` ADD COLUMN `wallet_balance` BIGINT NOT NULL DEFAULT 0 AFTER `vip_level`','SELECT 1'); PREPARE st FROM @s; EXECUTE st; DEALLOCATE PREPARE st;

CREATE TABLE IF NOT EXISTS `cw_wallet_tx` (
  `id`            BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `patient_id`    INT UNSIGNED NOT NULL,
  `tx_type`       VARCHAR(24)  NOT NULL,        -- gift|birthday|manual|refund|promo|shadiclub|redeem_code|spend|expire|adjust
  `amount`        BIGINT       NOT NULL,        -- علامت‌دار: + شارژ، − مصرف/انقضا
  `balance_after` BIGINT       NOT NULL DEFAULT 0,
  `reason`        VARCHAR(255) DEFAULT NULL,
  `ref_invoice_id`BIGINT UNSIGNED DEFAULT NULL, -- cw_payments.id هنگام مصرف در فاکتور
  `gift_code_id`  INT UNSIGNED DEFAULT NULL,
  `expires_at`    DATETIME     DEFAULT NULL,    -- برای اعتبارِ زمان‌دار (مثلِ هدیه‌ی تولد ۲۴ساعته)
  `is_expired`    TINYINT(1)   NOT NULL DEFAULT 0,
  `created_by`    INT UNSIGNED DEFAULT NULL,
  `created_at`    DATETIME     NOT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_patient` (`patient_id`),
  KEY `idx_type` (`tx_type`),
  KEY `idx_expires` (`expires_at`,`is_expired`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- ───────────────────────── ۲) کدهای هدیه / لایسنس ───────────────────────────
CREATE TABLE IF NOT EXISTS `cw_gift_codes` (
  `id`               INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `code`             VARCHAR(60)  NOT NULL,
  `code_type`        VARCHAR(24)  NOT NULL DEFAULT 'gift',  -- gift|license|shadiclub|promo
  `amount`           BIGINT       NOT NULL DEFAULT 0,
  `max_redemptions`  INT          NOT NULL DEFAULT 1,       -- 0 = نامحدود
  `per_patient_limit`INT          NOT NULL DEFAULT 1,
  `used_count`       INT          NOT NULL DEFAULT 0,
  `valid_from`       DATE         DEFAULT NULL,
  `valid_to`         DATE         DEFAULT NULL,
  `credit_ttl_hours` INT          DEFAULT NULL,             -- اگر پر باشد، اعتبارِ حاصل زمان‌دار می‌شود
  `is_active`        TINYINT(1)   NOT NULL DEFAULT 1,
  `note`             VARCHAR(255) DEFAULT NULL,
  `created_by`       INT UNSIGNED DEFAULT NULL,
  `created_at`       DATETIME     NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uq_code` (`code`),
  KEY `idx_active` (`is_active`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS `cw_gift_code_redemptions` (
  `id`          BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `code_id`     INT UNSIGNED NOT NULL,
  `patient_id`  INT UNSIGNED NOT NULL,
  `amount`      BIGINT       NOT NULL DEFAULT 0,
  `wallet_tx_id`BIGINT UNSIGNED DEFAULT NULL,
  `redeemed_by` INT UNSIGNED DEFAULT NULL,
  `created_at`  DATETIME     NOT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_code` (`code_id`),
  KEY `idx_patient` (`patient_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- ───────────────────────── ۳) امتیازِ ارزشمندیِ بیمار (دوگانه) ───────────────
-- الگوریتمی (خودکار) + دستی (مهسا) + نهایی (بیشینه/سیاست). هر دو کنارِ هم دیده می‌شوند.
CREATE TABLE IF NOT EXISTS `cw_patient_value` (
  `patient_id`     INT UNSIGNED NOT NULL,
  `algo_score`     INT          NOT NULL DEFAULT 0,   -- 0..100
  `algo_json`      MEDIUMTEXT   DEFAULT NULL,         -- تفکیکِ عواملِ امتیاز (شفافیت)
  `manual_score`   INT          DEFAULT NULL,         -- 0..100 (اختیاری، دستیِ مدیریت)
  `manual_reason`  VARCHAR(255) DEFAULT NULL,
  `manual_by`      INT UNSIGNED DEFAULT NULL,
  `final_score`    INT          NOT NULL DEFAULT 0,
  `computed_at`    DATETIME     DEFAULT NULL,
  PRIMARY KEY (`patient_id`),
  KEY `idx_final` (`final_score`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- ───────────────────────── ۴) نرخِ ارز (نرمال‌سازیِ تاریخیِ هزینه به دلار) ────
CREATE TABLE IF NOT EXISTS `cw_exchange_rates` (
  `id`         INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `rate_date`  DATE         NOT NULL,
  `usd_toman`  BIGINT       NOT NULL,               -- ۱ دلار = ? تومان در آن تاریخ
  `source`     VARCHAR(60)  DEFAULT 'manual',
  `created_at` DATETIME     NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uq_date` (`rate_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- ───────────────────────── ۵) پرچم‌های رفتاری/تجربه‌ی بیمار ──────────────────
CREATE TABLE IF NOT EXISTS `cw_patient_flags` (
  `id`          BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `patient_id`  INT UNSIGNED NOT NULL,
  `flag_key`    VARCHAR(40)  NOT NULL,   -- difficult|vip|friend|colleague_doctor|price_sensitive|pain_sensitive|...
  `created_by`  INT UNSIGNED DEFAULT NULL,
  `created_at`  DATETIME     NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uq_patient_flag` (`patient_id`,`flag_key`),
  KEY `idx_flag` (`flag_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- یادداشت‌های ساختاریافته/داخلی (حساس‌ها با دسترسی محدود دیده می‌شوند)
CREATE TABLE IF NOT EXISTS `cw_patient_notes` (
  `id`          BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `patient_id`  INT UNSIGNED NOT NULL,
  `note_type`   VARCHAR(30)  DEFAULT 'general',   -- general|experience|financial|medical|sensitive
  `body`        VARCHAR(500) NOT NULL,
  `is_sensitive`TINYINT(1)   NOT NULL DEFAULT 0,
  `created_by`  INT UNSIGNED DEFAULT NULL,
  `created_at`  DATETIME     NOT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_patient` (`patient_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- ───────────────────────── ۶) پلنِ مشاوره‌ی ساختاریافته (میز پزشک) ───────────
-- جایگزینِ حرفه‌ایِ plan_json (که برای سازگاری حفظ می‌شود). هر پلن چند آیتم دارد.
CREATE TABLE IF NOT EXISTS `cw_consult_plans` (
  `id`          BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `visit_id`    INT UNSIGNED DEFAULT NULL,
  `patient_id`  INT UNSIGNED NOT NULL,
  `author_id`   INT UNSIGNED DEFAULT NULL,
  `author_role` VARCHAR(24)  NOT NULL DEFAULT 'doctor',  -- doctor|free_consult|counselor
  `source_type` VARCHAR(24)  NOT NULL DEFAULT 'doctor_plan', -- doctor_plan|free_consult_plan|counselor_plan
  `status`      VARCHAR(20)  NOT NULL DEFAULT 'draft',   -- draft|final|sent_parvizi|decided|archived
  `chief_complaint` VARCHAR(255) DEFAULT NULL,
  `final_cost`  BIGINT       NOT NULL DEFAULT 0,
  `note`        VARCHAR(500) DEFAULT NULL,
  `created_at`  DATETIME     NOT NULL,
  `updated_at`  DATETIME     DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_visit` (`visit_id`),
  KEY `idx_patient` (`patient_id`),
  KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS `cw_consult_plan_items` (
  `id`               BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `plan_id`          BIGINT UNSIGNED NOT NULL,
  `row_no`           INT          NOT NULL DEFAULT 1,
  `diagnosis`        VARCHAR(190) DEFAULT NULL,       -- تشخیص
  `service_id`       INT UNSIGNED DEFAULT NULL,       -- cw_services.id (اگر از کاتالوگ)
  `procedure_title`  VARCHAR(190) DEFAULT NULL,       -- روش درمان/پروسیجر (متن)
  `device`           VARCHAR(120) DEFAULT NULL,       -- دستگاه
  `area`             VARCHAR(120) DEFAULT NULL,       -- ناحیه‌ی آناتومیک
  `sessions`         INT          NOT NULL DEFAULT 1, -- تعداد جلسات
  `interval_days`    INT          DEFAULT NULL,       -- فاصله‌ی جلسات (روز)
  `expected_response`VARCHAR(40)  DEFAULT NULL,       -- میزان پاسخ‌دهی
  `risk_note`        VARCHAR(255) DEFAULT NULL,       -- ریسک/منع مصرف
  `price`            BIGINT       NOT NULL DEFAULT 0, -- هزینه‌ی درمان
  `final_price`      BIGINT       NOT NULL DEFAULT 0, -- هزینه‌ی نهایی
  `priority`         TINYINT      NOT NULL DEFAULT 3, -- 1=فوری..5=کم‌اولویت
  `requires_photo`   TINYINT(1)   NOT NULL DEFAULT 0,
  `requires_numbing` TINYINT(1)   NOT NULL DEFAULT 0,
  `requires_nurse`   TINYINT(1)   NOT NULL DEFAULT 0,
  `requires_doctor`  TINYINT(1)   NOT NULL DEFAULT 0,
  `aftercare_url`    VARCHAR(255) DEFAULT NULL,
  `internal_note`    VARCHAR(255) DEFAULT NULL,
  `doctor_note`      VARCHAR(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_plan` (`plan_id`),
  KEY `idx_service` (`service_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- تصمیمِ کانتر پرویزی برای هر آیتمِ پلن (تیک/رد/فکر می‌کند/…)
CREATE TABLE IF NOT EXISTS `cw_plan_item_decisions` (
  `id`         BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `item_id`    BIGINT UNSIGNED NOT NULL,
  `visit_id`   INT UNSIGNED DEFAULT NULL,
  `decision`   VARCHAR(30)  NOT NULL,   -- accepted|rejected|thinking|price_objection|family_consult|
                                        -- postponed|another_doctor|fear|booked_later|callcenter_followup|not_today
  `to_cashier` TINYINT(1)   NOT NULL DEFAULT 0,
  `booked_appt_id` BIGINT UNSIGNED DEFAULT NULL, -- اگر برای جلسه‌ی بعد وقت گرفته شد
  `note`       VARCHAR(255) DEFAULT NULL,
  `decided_by` INT UNSIGNED DEFAULT NULL,
  `created_at` DATETIME     NOT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_item` (`item_id`),
  KEY `idx_visit` (`visit_id`),
  KEY `idx_decision` (`decision`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- ───────────────────────── ۷) الزامِ عکسِ قبل/بعد (گِیت) ─────────────────────
CREATE TABLE IF NOT EXISTS `cw_photo_requirements` (
  `id`            BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `visit_id`      INT UNSIGNED DEFAULT NULL,
  `patient_id`    INT UNSIGNED NOT NULL,
  `plan_item_id`  BIGINT UNSIGNED DEFAULT NULL,
  `service_id`    INT UNSIGNED DEFAULT NULL,
  `phase`         ENUM('before','after') NOT NULL DEFAULT 'before',
  `status`        VARCHAR(16)  NOT NULL DEFAULT 'pending', -- pending|done|waived
  `photo_id`      INT UNSIGNED DEFAULT NULL,   -- cw_photos.id هنگام تکمیل
  `waived_by`     INT UNSIGNED DEFAULT NULL,
  `waived_reason` VARCHAR(255) DEFAULT NULL,
  `created_at`    DATETIME     NOT NULL,
  `updated_at`    DATETIME     DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_visit` (`visit_id`),
  KEY `idx_patient` (`patient_id`),
  KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- برچسب‌های بیشتر برای عکس‌ها (follow-up/consent/document) بدونِ شکستنِ enum فعلی
SET @c:=(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='cw_photos' AND COLUMN_NAME='tag');
SET @s:=IF(@c=0,"ALTER TABLE `cw_photos` ADD COLUMN `tag` VARCHAR(20) DEFAULT NULL AFTER `phase`",'SELECT 1'); PREPARE st FROM @s; EXECUTE st; DEALLOCATE PREPARE st;
SET @c:=(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='cw_photos' AND COLUMN_NAME='service_id');
SET @s:=IF(@c=0,"ALTER TABLE `cw_photos` ADD COLUMN `service_id` INT UNSIGNED DEFAULT NULL AFTER `visit_id`",'SELECT 1'); PREPARE st FROM @s; EXECUTE st; DEALLOCATE PREPARE st;

-- ───────────────────────── ۸) تخصیصِ پرستار (مهارت + تخصیص + توصیه‌ی شفاف) ───
CREATE TABLE IF NOT EXISTS `cw_nurse_skills` (
  `id`          INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `nurse_id`    INT UNSIGNED NOT NULL,
  `service_id`  INT UNSIGNED DEFAULT NULL,   -- cw_services.id
  `procedure_id`INT UNSIGNED DEFAULT NULL,   -- procedures.id (سیستم پرستاری)
  `skill_level` TINYINT      NOT NULL DEFAULT 3,  -- 1..5 (۵=ماهرترین)
  `avg_minutes` INT          DEFAULT NULL,        -- میانگینِ سرعتِ تاریخی
  `is_active`   TINYINT(1)   NOT NULL DEFAULT 1,
  `updated_at`  DATETIME     DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_nurse` (`nurse_id`),
  KEY `idx_service` (`service_id`),
  KEY `idx_proc` (`procedure_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS `cw_nurse_assignments` (
  `id`             BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `visit_id`       INT UNSIGNED DEFAULT NULL,
  `record_id`      INT UNSIGNED DEFAULT NULL,   -- nursing_records.id
  `performed_id`   INT UNSIGNED DEFAULT NULL,   -- cw_performed_services.id
  `nurse_id`       INT UNSIGNED NOT NULL,
  `is_auto`        TINYINT(1)   NOT NULL DEFAULT 1,  -- توصیه‌ی الگوریتمی یا دستی
  `override_reason`VARCHAR(255) DEFAULT NULL,        -- در صورتِ override دستی، الزامی
  `assigned_by`    INT UNSIGNED DEFAULT NULL,
  `created_at`     DATETIME     NOT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_visit` (`visit_id`),
  KEY `idx_nurse` (`nurse_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS `cw_nurse_assign_recos` (
  `id`           BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `visit_id`     INT UNSIGNED DEFAULT NULL,
  `context_hash` VARCHAR(40)  DEFAULT NULL,   -- برای گروه‌بندیِ یک نوبتِ توصیه
  `nurse_id`     INT UNSIGNED NOT NULL,
  `score`        DECIMAL(6,2) NOT NULL DEFAULT 0,
  `rank_no`      TINYINT      NOT NULL DEFAULT 0,
  `factors_json` MEDIUMTEXT   DEFAULT NULL,   -- «چرا این پرستار» (شفافیت)
  `created_at`   DATETIME     NOT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_visit` (`visit_id`),
  KEY `idx_nurse` (`nurse_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- ───────────────────────── ۹) ارتقاء CRM کال‌سنتر (روی cw_appointments) ──────
-- «نتیجه‌ی تماس» جدا از «وضعیت» نگه‌داری می‌شود تا enum وضعیت شلوغ نشود.
SET @c:=(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='cw_appointments' AND COLUMN_NAME='outcome');
SET @s:=IF(@c=0,"ALTER TABLE `cw_appointments` ADD COLUMN `outcome` VARCHAR(30) DEFAULT NULL AFTER `status`",'SELECT 1'); PREPARE st FROM @s; EXECUTE st; DEALLOCATE PREPARE st;
SET @c:=(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='cw_appointments' AND COLUMN_NAME='first_contact_at');
SET @s:=IF(@c=0,"ALTER TABLE `cw_appointments` ADD COLUMN `first_contact_at` DATETIME DEFAULT NULL AFTER `outcome`",'SELECT 1'); PREPARE st FROM @s; EXECUTE st; DEALLOCATE PREPARE st;
SET @c:=(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='cw_appointments' AND COLUMN_NAME='call_attempts');
SET @s:=IF(@c=0,"ALTER TABLE `cw_appointments` ADD COLUMN `call_attempts` INT NOT NULL DEFAULT 0 AFTER `first_contact_at`",'SELECT 1'); PREPARE st FROM @s; EXECUTE st; DEALLOCATE PREPARE st;
SET @c:=(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='cw_appointments' AND COLUMN_NAME='claimed_by');
SET @s:=IF(@c=0,"ALTER TABLE `cw_appointments` ADD COLUMN `claimed_by` INT UNSIGNED DEFAULT NULL AFTER `operator_id`",'SELECT 1'); PREPARE st FROM @s; EXECUTE st; DEALLOCATE PREPARE st;
SET @c:=(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='cw_appointments' AND COLUMN_NAME='claimed_at');
SET @s:=IF(@c=0,"ALTER TABLE `cw_appointments` ADD COLUMN `claimed_at` DATETIME DEFAULT NULL AFTER `claimed_by`",'SELECT 1'); PREPARE st FROM @s; EXECUTE st; DEALLOCATE PREPARE st;
SET @c:=(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='cw_appointments' AND COLUMN_NAME='has_file');
SET @s:=IF(@c=0,"ALTER TABLE `cw_appointments` ADD COLUMN `has_file` TINYINT DEFAULT NULL AFTER `cw_patient_id`",'SELECT 1'); PREPARE st FROM @s; EXECUTE st; DEALLOCATE PREPARE st;

-- بازه‌ی زمانیِ اسلات (کدِ inc/appt.php این ستون را می‌خواند؛ اگر نبود می‌سازیم)
SET @c:=(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='cw_appt_slot_rules' AND COLUMN_NAME='slot_interval_minutes');
SET @s:=IF(@c=0,"ALTER TABLE `cw_appt_slot_rules` ADD COLUMN `slot_interval_minutes` INT NOT NULL DEFAULT 30 AFTER `max_bookings`",'SELECT 1'); PREPARE st FROM @s; EXECUTE st; DEALLOCATE PREPARE st;

-- ───────────────────────── ۱۰) تسک‌های تماس (تولد/VIP/پیگیری) ────────────────
CREATE TABLE IF NOT EXISTS `cw_call_tasks` (
  `id`            BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `patient_id`    INT UNSIGNED DEFAULT NULL,
  `appointment_id`BIGINT UNSIGNED DEFAULT NULL,
  `task_type`     VARCHAR(24)  NOT NULL DEFAULT 'followup', -- followup|birthday|vip|no_answer|win_back
  `title`         VARCHAR(190) DEFAULT NULL,
  `priority`      TINYINT      NOT NULL DEFAULT 3,          -- 1=بالا..5=پایین
  `due_at`        DATETIME     DEFAULT NULL,
  `assigned_to`   INT UNSIGNED DEFAULT NULL,
  `status`        VARCHAR(16)  NOT NULL DEFAULT 'open',     -- open|done|snoozed|cancelled
  `script_key`    VARCHAR(60)  DEFAULT NULL,                -- اسکریپتِ پیشنهادی
  `note`          VARCHAR(500) DEFAULT NULL,
  `created_by`    INT UNSIGNED DEFAULT NULL,
  `created_at`    DATETIME     NOT NULL,
  `done_at`       DATETIME     DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_patient` (`patient_id`),
  KEY `idx_type` (`task_type`),
  KEY `idx_status` (`status`),
  KEY `idx_due` (`due_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- ───────────────────────── ۱۱) اسکریپت/دانشِ پروسیجر (کشوی راهنما) ───────────
CREATE TABLE IF NOT EXISTS `cw_scripts` (
  `id`         INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `script_key` VARCHAR(60)  NOT NULL,
  `category`   VARCHAR(40)  DEFAULT 'general',  -- faq|objection|aftercare|birthday|procedure|general
  `title`      VARCHAR(190) NOT NULL,
  `body`       TEXT         NOT NULL,
  `context`    VARCHAR(60)  DEFAULT NULL,        -- website|price_objection|fear|... (پیشنهادِ خودکار)
  `sort`       INT          NOT NULL DEFAULT 0,
  `is_active`  TINYINT(1)   NOT NULL DEFAULT 1,
  `updated_at` DATETIME     DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uq_key` (`script_key`),
  KEY `idx_cat` (`category`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- دانشِ قیمت/پروسیجر برای جستجوی اپراتور: توسعه‌ی cw_services (نه جدولِ موازی)
SET @c:=(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='cw_services' AND COLUMN_NAME='price_min');
SET @s:=IF(@c=0,"ALTER TABLE `cw_services` ADD COLUMN `price_min` BIGINT DEFAULT NULL, ADD COLUMN `price_max` BIGINT DEFAULT NULL, ADD COLUMN `default_sessions` INT DEFAULT NULL, ADD COLUMN `interval_days` INT DEFAULT NULL, ADD COLUMN `patient_explanation` VARCHAR(500) DEFAULT NULL, ADD COLUMN `aftercare_url` VARCHAR(255) DEFAULT NULL, ADD COLUMN `operator_note` VARCHAR(500) DEFAULT NULL, ADD COLUMN `contraindication` VARCHAR(500) DEFAULT NULL",'SELECT 1'); PREPARE st FROM @s; EXECUTE st; DEALLOCATE PREPARE st;

-- ───────────────────────── ۱۲) تولد: لاگِ اتوماسیون (idempotency) ────────────
CREATE TABLE IF NOT EXISTS `cw_birthday_log` (
  `id`          BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `patient_id`  INT UNSIGNED NOT NULL,
  `year`        SMALLINT     NOT NULL,          -- سالِ شمسیِ ارسال (جلوگیری از تکرار)
  `sms_sent_at` DATETIME     DEFAULT NULL,
  `credit_tx_id`BIGINT UNSIGNED DEFAULT NULL,
  `credit_used` TINYINT(1)   NOT NULL DEFAULT 0,
  `call_task_id`BIGINT UNSIGNED DEFAULT NULL,
  `created_at`  DATETIME     NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uq_patient_year` (`patient_id`,`year`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- ───────────────────────── ۱۳) لاگِ اجراهای sync سایت (خلاصه‌ی هر ران) ────────
CREATE TABLE IF NOT EXISTS `cw_site_sync_log` (
  `id`         BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `source`     VARCHAR(40)  NOT NULL DEFAULT 'site',
  `run_at`     DATETIME     NOT NULL,
  `pulled`     INT          NOT NULL DEFAULT 0,
  `created`    INT          NOT NULL DEFAULT 0,
  `updated`    INT          NOT NULL DEFAULT 0,
  `skipped`    INT          NOT NULL DEFAULT 0,
  `errors`     INT          NOT NULL DEFAULT 0,
  `ok`         TINYINT(1)   NOT NULL DEFAULT 1,
  `note`       VARCHAR(500) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_run` (`run_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- ───────────────────────── ۱۴) اسکلتِ ایمپورتِ آینده «سلاک طب» ───────────────
CREATE TABLE IF NOT EXISTS `cw_external_import_refs` (
  `id`                 BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `patient_id`         INT UNSIGNED DEFAULT NULL,   -- پس از تطبیق با cw_patients
  `source`             VARCHAR(30)  NOT NULL DEFAULT 'selaak',
  `external_patient_id`VARCHAR(64)  DEFAULT NULL,
  `external_file_no`   VARCHAR(64)  DEFAULT NULL,
  `imported_total_spend` BIGINT     DEFAULT NULL,
  `imported_spend_usd` BIGINT       DEFAULT NULL,   -- نرمال‌شده به دلار (اگر نرخ موجود بود)
  `imported_visit_count` INT        DEFAULT NULL,
  `imported_last_visit`  DATE       DEFAULT NULL,
  `imported_json`      MEDIUMTEXT   DEFAULT NULL,    -- تراکنش‌ها/خدماتِ خام
  `conflict_status`    VARCHAR(20)  NOT NULL DEFAULT 'none', -- none|matched|ambiguous|conflict
  `import_batch`       VARCHAR(40)  DEFAULT NULL,
  `import_date`        DATETIME     DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_patient` (`patient_id`),
  KEY `idx_ext` (`source`,`external_patient_id`),
  KEY `idx_file` (`external_file_no`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- ───────────────────────── ۱۵) تنظیماتِ پیش‌فرضِ زیرسیستم‌ها (key/value) ──────
INSERT IGNORE INTO `cw_settings` (`k`,`v`,`updated_at`) VALUES
 ('birthday_enabled','1',NOW()),
 ('birthday_credit_amount','300000',NOW()),   -- ۳۰۰٬۰۰۰ تومان هدیه‌ی تولد
 ('birthday_credit_ttl_hours','24',NOW()),
 ('birthday_sms_template','birthday',NOW()),
 ('birthday_call_min_score','70',NOW()),      -- فقط بالای این امتیاز، تسکِ تماسِ تولد ساخته شود
 ('wallet_enabled','1',NOW()),
 ('nurse_assign_crowd_threshold','8',NOW()),  -- تعدادِ در صف که «شلوغ» تلقی می‌شود
 ('value_weight_spend','40',NOW()),
 ('value_weight_frequency','20',NOW()),
 ('value_weight_recency','15',NOW()),
 ('value_weight_membership','10',NOW()),
 ('value_weight_referral','15',NOW());

-- ───────────────────────── ۱۶) داده‌ی نمونه: اسکریپت‌های کال‌سنتر ─────────────
DROP TEMPORARY TABLE IF EXISTS `_seed_cw_scripts`;
CREATE TEMPORARY TABLE `_seed_cw_scripts` LIKE `cw_scripts`;
INSERT INTO `_seed_cw_scripts` (`script_key`,`category`,`title`,`body`,`context`,`sort`,`is_active`,`updated_at`) VALUES
 ('greeting','faq','معرفی و خوش‌آمد','سلام، وقت‌تون بخیر. از کلینیک تخصصی پوست، مو و لیزر دکتر شادی مظلومی تماس می‌گیرم. در خدمتم.','website',1,1,NOW()),
 ('obj_price','objection','پاسخ به اعتراضِ قیمت','کاملاً درک می‌کنم. کیفیت و ایمنیِ درمان برای ما در اولویت است؛ اجازه بدید بر اساس شرایط شما بهترین پلن با مناسب‌ترین هزینه رو خدمتتون پیشنهاد بدم. امکانِ تقسیطِ جلسات هم داریم.','price_objection',2,1,NOW()),
 ('obj_fear','objection','پاسخ به ترس از درد/عارضه','این درمان کاملاً تحتِ نظرِ پزشک انجام میشه و در صورت نیاز بی‌حسی موضعی داریم تا کاملاً بی‌درد باشه. عوارضِ جدی بسیار نادره و مراقبت‌های بعدش رو هم کامل بهتون آموزش می‌دیم.','fear',3,1,NOW()),
 ('birthday_greet','birthday','تبریکِ تولد (محترمانه)','سلام، روزتون بخیر. از طرفِ کلینیک شادی فقط تماس گرفتیم که تولدتون رو صمیمانه تبریک بگیم. امیدواریم سالِ خوبی پیشِ رو داشته باشید. یک هدیه‌ی کوچک هم به حسابتون در کلینیک اضافه شده که خوشحال می‌شیم ازش استفاده کنید.','birthday',4,1,NOW()),
 ('aftercare_laser','aftercare','مراقبت بعد از لیزر','تا ۴۸ ساعت از آب داغ، سونا و آفتابِ مستقیم پرهیز کنید. ضدآفتاب و مرطوب‌کننده طبقِ توصیه استفاده بشه. در صورتِ قرمزیِ شدید یا تاول با کلینیک تماس بگیرید.',NULL,5,1,NOW());
INSERT INTO `cw_scripts` (`script_key`,`category`,`title`,`body`,`context`,`sort`,`is_active`,`updated_at`)
SELECT s.`script_key`,s.`category`,s.`title`,s.`body`,s.`context`,s.`sort`,s.`is_active`,s.`updated_at`
FROM `_seed_cw_scripts` s
WHERE NOT EXISTS (SELECT 1 FROM `cw_scripts` c WHERE c.`script_key`=s.`script_key`);
DROP TEMPORARY TABLE `_seed_cw_scripts`;

SET FOREIGN_KEY_CHECKS = 1;
-- ============================================================================
--  پایانِ اسپرینت ۳۰. تمام تغییرات افزایشی‌اند؛ ماژول‌های موجود دست‌نخورده‌اند.
-- ----------------------------------------------------------------------------
--  ROLLBACK (فقط در صورتِ نیاز، دستی و با احتیاط اجرا شود):
--   DROP TABLE IF EXISTS `cw_external_import_refs`,`cw_site_sync_log`,`cw_birthday_log`,
--     `cw_scripts`,`cw_call_tasks`,`cw_nurse_assign_recos`,`cw_nurse_assignments`,
--     `cw_nurse_skills`,`cw_photo_requirements`,`cw_plan_item_decisions`,
--     `cw_consult_plan_items`,`cw_consult_plans`,`cw_patient_notes`,`cw_patient_flags`,
--     `cw_exchange_rates`,`cw_patient_value`,`cw_gift_code_redemptions`,`cw_gift_codes`,
--     `cw_wallet_tx`;
--   -- ستون‌های افزوده‌شده (wallet_balance, outcome, ...) را در صورتِ نیاز DROP کنید.
-- ============================================================================
