-- ╔══════════════════════════════════════════════════════════════════════╗
-- ║  THE CLUB ERP — COMPLETE DATABASE SCHEMA                           ║
-- ║  MySQL 8.0+ · utf8mb4 · Strict Mode · All 15 Phases               ║
-- ║                                                                    ║
-- ║  CONVENTIONS:                                                      ║
-- ║  • BIGINT UNSIGNED AUTO_INCREMENT for all PKs                      ║
-- ║  • DECIMAL(15,2) for money, DECIMAL(5,2) for percentages          ║
-- ║  • TIMESTAMP for created_at/updated_at                             ║
-- ║  • JSON columns: NO defaults (app must provide)                    ║
-- ║  • created_by/updated_by: NO FK constraints (app-managed)          ║
-- ║  • Domain FKs enforced (member_id, branch_id, role_id, etc.)       ║
-- ║  • Soft-delete: is_archived + archived_at + archived_by            ║
-- ║  • Immutable tables: INSERT only, NO updated_at                    ║
-- ╚══════════════════════════════════════════════════════════════════════╝

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
SET SQL_MODE = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';

DROP DATABASE IF EXISTS `the_club_erp`;
CREATE DATABASE `the_club_erp`
    CHARACTER SET utf8mb4
    COLLATE utf8mb4_unicode_ci;

USE `the_club_erp`;

-- ════════════════════════════════════════════════════════════════
-- PHASE 01: SYSTEM KERNEL & INFRASTRUCTURE
-- ════════════════════════════════════════════════════════════════

-- ──────────────────────────────────────────────
-- Migration tracking
-- ──────────────────────────────────────────────
CREATE TABLE `migrations` (
    `id`          INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `migration`   VARCHAR(255) NOT NULL,
    `batch`       INT UNSIGNED NOT NULL,
    `executed_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY `uq_migrations_name` (`migration`)
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Seed tracking
-- ──────────────────────────────────────────────
CREATE TABLE `seeds` (
    `id`          INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `seed`        VARCHAR(255) NOT NULL,
    `executed_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY `uq_seeds_name` (`seed`)
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- System configuration (DB-backed config overrides)
-- ──────────────────────────────────────────────
CREATE TABLE `system_config` (
    `id`             BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `config_key`     VARCHAR(255) NOT NULL,
    `config_value`   TEXT NULL,
    `config_type`    ENUM('string','integer','float','boolean','json') NOT NULL DEFAULT 'string',
    `group_name`     VARCHAR(100) NOT NULL DEFAULT 'general',
    `description_ar` VARCHAR(500) NULL,
    `description_en` VARCHAR(500) NULL,
    `is_editable`    TINYINT(1) NOT NULL DEFAULT 1,
    `created_at`     TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`     TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    UNIQUE KEY `uq_system_config_key` (`config_key`),
    INDEX `idx_system_config_group` (`group_name`)
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Async event queue (for EventBus::dispatchAsync)
-- ──────────────────────────────────────────────
CREATE TABLE `async_event_queue` (
    `id`             BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `event_name`     VARCHAR(200) NOT NULL,
    `event_data_json` JSON NULL,
    `status`         VARCHAR(30) NOT NULL DEFAULT 'pending',
    `attempts`       INT UNSIGNED NOT NULL DEFAULT 0,
    `max_attempts`   INT UNSIGNED NOT NULL DEFAULT 3,
    `created_at`     TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `processed_at`   TIMESTAMP NULL DEFAULT NULL,
    `failed_at`      TIMESTAMP NULL DEFAULT NULL,
    `error_message`  TEXT NULL,
    INDEX `idx_async_events_status` (`status`),
    INDEX `idx_async_events_created` (`created_at`)
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Cron job execution log
-- ──────────────────────────────────────────────
CREATE TABLE `cron_job_log` (
    `id`                BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `job_name`          VARCHAR(200) NOT NULL,
    `started_at`        TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `finished_at`       TIMESTAMP NULL DEFAULT NULL,
    `status`            VARCHAR(30) NOT NULL DEFAULT 'running',
    `records_processed` INT UNSIGNED NOT NULL DEFAULT 0,
    `error_message`     TEXT NULL,
    `execution_time_ms` INT UNSIGNED NULL,
    INDEX `idx_cron_job_name` (`job_name`),
    INDEX `idx_cron_job_started` (`started_at`)
) ENGINE=InnoDB;


-- ════════════════════════════════════════════════════════════════
-- PHASE 02: AUTHENTICATION, USERS, ROLES & PERMISSIONS
-- ════════════════════════════════════════════════════════════════

-- ──────────────────────────────────────────────
-- Branches (created before employees to allow FK)
-- Phase 03 table, placed here for FK dependency
-- ──────────────────────────────────────────────
CREATE TABLE `branches` (
    `id`                 BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `branch_code`        VARCHAR(50) NOT NULL,
    `name_ar`            VARCHAR(200) NOT NULL,
    `name_en`            VARCHAR(200) NULL,
    `address`            TEXT NULL,
    `phone`              VARCHAR(20) NULL,
    `manager_name`       VARCHAR(200) NULL,
    `is_active`          TINYINT(1) NOT NULL DEFAULT 1,
    `member_count_cache` INT UNSIGNED NOT NULL DEFAULT 0,
    `created_at`         TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`         TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`         BIGINT UNSIGNED NULL,
    `updated_by`         BIGINT UNSIGNED NULL,
    UNIQUE KEY `uq_branches_code` (`branch_code`),
    INDEX `idx_branches_active` (`is_active`)
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Employees (system users — NOT club members)
-- ──────────────────────────────────────────────
CREATE TABLE `employees` (
    `id`                    BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `username`              VARCHAR(50) NOT NULL,
    `password_hash`         VARCHAR(255) NOT NULL,
    `full_name_ar`          VARCHAR(200) NOT NULL,
    `full_name_en`          VARCHAR(200) NULL,
    `email`                 VARCHAR(255) NULL,
    `phone`                 VARCHAR(20) NULL,
    `branch_id`             BIGINT UNSIGNED NULL,
    `is_active`             TINYINT(1) NOT NULL DEFAULT 1,
    `force_password_change` TINYINT(1) NOT NULL DEFAULT 0,
    `password_changed_at`   TIMESTAMP NULL DEFAULT NULL,
    `last_login_at`         TIMESTAMP NULL DEFAULT NULL,
    `last_login_ip`         VARCHAR(45) NULL,
    `failed_login_count`    INT UNSIGNED NOT NULL DEFAULT 0,
    `locked_until`          TIMESTAMP NULL DEFAULT NULL,
    `created_at`            TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`            TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`            BIGINT UNSIGNED NULL,
    `updated_by`            BIGINT UNSIGNED NULL,
    `is_archived`           TINYINT(1) NOT NULL DEFAULT 0,
    `archived_at`           TIMESTAMP NULL DEFAULT NULL,
    `archived_by`           BIGINT UNSIGNED NULL,
    UNIQUE KEY `uq_employees_username` (`username`),
    INDEX `idx_employees_branch` (`branch_id`),
    INDEX `idx_employees_active` (`is_active`),
    INDEX `idx_employees_archived` (`is_archived`),
    CONSTRAINT `fk_employees_branch` FOREIGN KEY (`branch_id`) REFERENCES `branches`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Roles
-- ──────────────────────────────────────────────
CREATE TABLE `roles` (
    `id`              BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `role_code`       VARCHAR(50) NOT NULL,
    `name_ar`         VARCHAR(200) NOT NULL,
    `name_en`         VARCHAR(200) NULL,
    `description_ar`  VARCHAR(500) NULL,
    `description_en`  VARCHAR(500) NULL,
    `is_system`       TINYINT(1) NOT NULL DEFAULT 0,
    `is_active`       TINYINT(1) NOT NULL DEFAULT 1,
    `parent_role_id`  BIGINT UNSIGNED NULL,
    `created_at`      TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`      TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`      BIGINT UNSIGNED NULL,
    `updated_by`      BIGINT UNSIGNED NULL,
    UNIQUE KEY `uq_roles_code` (`role_code`),
    INDEX `idx_roles_parent` (`parent_role_id`),
    CONSTRAINT `fk_roles_parent` FOREIGN KEY (`parent_role_id`) REFERENCES `roles`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Role ↔ Permission mapping
-- ──────────────────────────────────────────────
CREATE TABLE `role_permissions` (
    `id`              BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `role_id`         BIGINT UNSIGNED NOT NULL,
    `permission_key`  VARCHAR(100) NOT NULL,
    `granted_at`      TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `granted_by`      BIGINT UNSIGNED NULL,
    UNIQUE KEY `uq_role_perm` (`role_id`, `permission_key`),
    INDEX `idx_role_permissions_key` (`permission_key`),
    CONSTRAINT `fk_role_permissions_role` FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Employee ↔ Role assignment
-- ──────────────────────────────────────────────
CREATE TABLE `employee_roles` (
    `id`           BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `employee_id`  BIGINT UNSIGNED NOT NULL,
    `role_id`      BIGINT UNSIGNED NOT NULL,
    `assigned_at`  TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `assigned_by`  BIGINT UNSIGNED NULL,
    `expires_at`   TIMESTAMP NULL DEFAULT NULL,
    `is_active`    TINYINT(1) NOT NULL DEFAULT 1,
    UNIQUE KEY `uq_emp_role_active` (`employee_id`, `role_id`, `is_active`),
    INDEX `idx_employee_roles_role` (`role_id`),
    INDEX `idx_employee_roles_expires` (`expires_at`),
    CONSTRAINT `fk_employee_roles_emp` FOREIGN KEY (`employee_id`) REFERENCES `employees`(`id`) ON DELETE CASCADE,
    CONSTRAINT `fk_employee_roles_role` FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Login attempts (IMMUTABLE — insert only)
-- ──────────────────────────────────────────────
CREATE TABLE `login_attempts` (
    `id`             BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `username`       VARCHAR(50) NOT NULL,
    `ip_address`     VARCHAR(45) NOT NULL,
    `user_agent`     VARCHAR(500) NULL,
    `success`        TINYINT(1) NOT NULL DEFAULT 0,
    `failure_reason` VARCHAR(200) NULL,
    `attempted_at`   TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    INDEX `idx_login_attempts_user` (`username`),
    INDEX `idx_login_attempts_ip` (`ip_address`),
    INDEX `idx_login_attempts_time` (`attempted_at`)
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Active sessions
-- ──────────────────────────────────────────────
CREATE TABLE `active_sessions` (
    `id`               BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `employee_id`      BIGINT UNSIGNED NOT NULL,
    `session_id`       VARCHAR(128) NOT NULL,
    `ip_address`       VARCHAR(45) NOT NULL,
    `user_agent`       VARCHAR(500) NULL,
    `logged_in_at`     TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `last_activity_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `is_active`        TINYINT(1) NOT NULL DEFAULT 1,
    INDEX `idx_active_sessions_emp` (`employee_id`),
    INDEX `idx_active_sessions_session` (`session_id`),
    INDEX `idx_active_sessions_active` (`is_active`),
    CONSTRAINT `fk_active_sessions_emp` FOREIGN KEY (`employee_id`) REFERENCES `employees`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Password history (prevent reuse)
-- ──────────────────────────────────────────────
CREATE TABLE `password_history` (
    `id`            BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `employee_id`   BIGINT UNSIGNED NOT NULL,
    `password_hash` VARCHAR(255) NOT NULL,
    `created_at`    TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    INDEX `idx_password_history_emp` (`employee_id`),
    CONSTRAINT `fk_password_history_emp` FOREIGN KEY (`employee_id`) REFERENCES `employees`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB;


-- ════════════════════════════════════════════════════════════════
-- PHASE 03: BRANCHES, SETTINGS & AUDIT TRAIL
-- (branches table already created above for FK ordering)
-- ════════════════════════════════════════════════════════════════

-- ──────────────────────────────────────────────
-- Egyptian governorates (NID positions 8-9)
-- ──────────────────────────────────────────────
CREATE TABLE `governorates` (
    `id`        BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `code`      VARCHAR(2) NOT NULL,
    `name_ar`   VARCHAR(100) NOT NULL,
    `name_en`   VARCHAR(100) NOT NULL,
    `is_active` TINYINT(1) NOT NULL DEFAULT 1,
    UNIQUE KEY `uq_governorates_code` (`code`)
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Countries (nationality, passport)
-- ──────────────────────────────────────────────
CREATE TABLE `countries` (
    `id`              BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `iso_code`        VARCHAR(3) NOT NULL,
    `name_ar`         VARCHAR(200) NOT NULL,
    `name_en`         VARCHAR(200) NOT NULL,
    `nationality_ar`  VARCHAR(200) NOT NULL,
    `nationality_en`  VARCHAR(200) NULL,
    `phone_code`      VARCHAR(10) NULL,
    `is_active`       TINYINT(1) NOT NULL DEFAULT 1,
    UNIQUE KEY `uq_countries_iso` (`iso_code`),
    INDEX `idx_countries_name_ar` (`name_ar`)
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Qualifications (affects pricing)
-- ──────────────────────────────────────────────
CREATE TABLE `qualifications` (
    `id`         BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `code`       VARCHAR(20) NOT NULL,
    `name_ar`    VARCHAR(100) NOT NULL,
    `name_en`    VARCHAR(100) NOT NULL,
    `sort_order` INT UNSIGNED NOT NULL DEFAULT 0,
    `is_active`  TINYINT(1) NOT NULL DEFAULT 1,
    UNIQUE KEY `uq_qualifications_code` (`code`)
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Audit trail — IMMUTABLE: INSERT ONLY
-- No updated_at, no is_archived, no deletes. EVER.
-- ──────────────────────────────────────────────
CREATE TABLE `audit_trail` (
    `id`                 BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `employee_id`        BIGINT UNSIGNED NULL,
    `employee_name`      VARCHAR(200) NULL,
    `action`             VARCHAR(50) NOT NULL,
    `entity_type`        VARCHAR(100) NULL,
    `entity_id`          BIGINT UNSIGNED NULL,
    `entity_label`       VARCHAR(255) NULL,
    `before_data_json`   JSON NULL,
    `after_data_json`    JSON NULL,
    `changed_fields_json` JSON NULL,
    `ip_address`         VARCHAR(45) NULL,
    `user_agent`         VARCHAR(500) NULL,
    `session_id`         VARCHAR(128) NULL,
    `route`              VARCHAR(255) NULL,
    `notes`              TEXT NULL,
    `created_at`         TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    INDEX `idx_audit_entity` (`entity_type`, `entity_id`),
    INDEX `idx_audit_employee` (`employee_id`),
    INDEX `idx_audit_date` (`created_at`),
    INDEX `idx_audit_action` (`action`)
) ENGINE=InnoDB;


-- ════════════════════════════════════════════════════════════════
-- PHASE 04: ARCHIVE ENGINE
-- ════════════════════════════════════════════════════════════════

-- ──────────────────────────────────────────────
-- Archive snapshots — IMMUTABLE: INSERT ONLY
-- Complete record snapshots for lifecycle events
-- ──────────────────────────────────────────────
CREATE TABLE `archive_snapshots` (
    `id`                BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `entity_type`       VARCHAR(100) NOT NULL,
    `entity_id`         BIGINT UNSIGNED NOT NULL,
    `membership_number` VARCHAR(20) NULL,
    `snapshot_reason`   VARCHAR(50) NOT NULL,
    `full_data_json`    JSON NOT NULL,
    `related_data_json` JSON NULL,
    `snapshot_taken_by` BIGINT UNSIGNED NULL,
    `snapshot_taken_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `notes`             TEXT NULL,
    INDEX `idx_archive_entity` (`entity_type`, `entity_id`),
    INDEX `idx_archive_membership` (`membership_number`),
    INDEX `idx_archive_date` (`snapshot_taken_at`),
    INDEX `idx_archive_reason` (`snapshot_reason`)
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Membership number ownership chain
-- Tracks who held which number and when
-- ──────────────────────────────────────────────
CREATE TABLE `membership_number_chain` (
    `id`                  BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `membership_number`   VARCHAR(20) NOT NULL,
    `holder_type`         VARCHAR(50) NOT NULL,
    `holder_entity_type`  VARCHAR(100) NOT NULL,
    `holder_entity_id`    BIGINT UNSIGNED NOT NULL,
    `previous_holder_id`  BIGINT UNSIGNED NULL,
    `held_from`           DATETIME NOT NULL,
    `held_until`          DATETIME NULL DEFAULT NULL,
    `created_at`          TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    INDEX `idx_number_chain_number` (`membership_number`),
    INDEX `idx_number_chain_holder` (`holder_entity_type`, `holder_entity_id`),
    CONSTRAINT `fk_number_chain_prev` FOREIGN KEY (`previous_holder_id`) REFERENCES `membership_number_chain`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB;


-- ════════════════════════════════════════════════════════════════
-- PHASE 05: RULES ENGINE, PRICING ENGINE & SERVICE CATALOG
-- ════════════════════════════════════════════════════════════════

-- ──────────────────────────────────────────────
-- Business rules (the heart of configuration)
-- ──────────────────────────────────────────────
CREATE TABLE `business_rules` (
    `id`                 BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `rule_code`          VARCHAR(100) NOT NULL,
    `category`           VARCHAR(50) NOT NULL,
    `name_ar`            VARCHAR(300) NOT NULL,
    `name_en`            VARCHAR(300) NULL,
    `description_ar`     TEXT NULL,
    `description_en`     TEXT NULL,
    `parameters_json`    JSON NULL,
    `current_value_json` JSON NOT NULL,
    `data_type`          VARCHAR(50) NOT NULL DEFAULT 'string',
    `branch_id`          BIGINT UNSIGNED NULL,
    `effective_from`     DATE NOT NULL,
    `effective_to`       DATE NULL DEFAULT NULL,
    `is_active`          TINYINT(1) NOT NULL DEFAULT 1,
    `version`            INT UNSIGNED NOT NULL DEFAULT 1,
    `created_at`         TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`         TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`         BIGINT UNSIGNED NULL,
    `updated_by`         BIGINT UNSIGNED NULL,
    UNIQUE KEY `uq_business_rules_code_branch` (`rule_code`, `branch_id`),
    INDEX `idx_business_rules_category` (`category`),
    INDEX `idx_business_rules_branch` (`branch_id`),
    INDEX `idx_business_rules_active` (`is_active`),
    INDEX `idx_business_rules_effective` (`effective_from`, `effective_to`),
    CONSTRAINT `fk_business_rules_branch` FOREIGN KEY (`branch_id`) REFERENCES `branches`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Rule version history (IMMUTABLE)
-- ──────────────────────────────────────────────
CREATE TABLE `rule_versions` (
    `id`              BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `rule_id`         BIGINT UNSIGNED NOT NULL,
    `version_number`  INT UNSIGNED NOT NULL,
    `old_value_json`  JSON NULL,
    `new_value_json`  JSON NOT NULL,
    `changed_by`      BIGINT UNSIGNED NULL,
    `changed_at`      TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `change_reason`   TEXT NULL,
    INDEX `idx_rule_versions_rule` (`rule_id`),
    CONSTRAINT `fk_rule_versions_rule` FOREIGN KEY (`rule_id`) REFERENCES `business_rules`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Pricing configurations (per branch per qualification)
-- ──────────────────────────────────────────────
CREATE TABLE `pricing_configs` (
    `id`               BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `branch_id`        BIGINT UNSIGNED NOT NULL,
    `qualification_id` BIGINT UNSIGNED NOT NULL,
    `membership_type`  VARCHAR(50) NOT NULL DEFAULT 'working',
    `price`            DECIMAL(15,2) NOT NULL,
    `currency`         VARCHAR(3) NOT NULL DEFAULT 'EGP',
    `effective_from`   DATE NOT NULL,
    `effective_to`     DATE NULL DEFAULT NULL,
    `is_active`        TINYINT(1) NOT NULL DEFAULT 1,
    `notes`            TEXT NULL,
    `created_at`       TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`       TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`       BIGINT UNSIGNED NULL,
    `updated_by`       BIGINT UNSIGNED NULL,
    INDEX `idx_pricing_branch` (`branch_id`),
    INDEX `idx_pricing_qual` (`qualification_id`),
    INDEX `idx_pricing_type` (`membership_type`),
    INDEX `idx_pricing_effective` (`effective_from`, `effective_to`),
    CONSTRAINT `fk_pricing_branch` FOREIGN KEY (`branch_id`) REFERENCES `branches`(`id`),
    CONSTRAINT `fk_pricing_qual` FOREIGN KEY (`qualification_id`) REFERENCES `qualifications`(`id`)
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Service price catalog
-- ──────────────────────────────────────────────
CREATE TABLE `service_catalog` (
    `id`              BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `service_code`    VARCHAR(50) NOT NULL,
    `name_ar`         VARCHAR(200) NOT NULL,
    `name_en`         VARCHAR(200) NULL,
    `price_type`      VARCHAR(50) NOT NULL DEFAULT 'fixed',
    `base_amount`     DECIMAL(15,2) NULL,
    `percentage`      DECIMAL(5,2) NULL,
    `annual_amount`   DECIMAL(15,2) NULL,
    `currency`        VARCHAR(3) NOT NULL DEFAULT 'EGP',
    `applies_to`      VARCHAR(100) NULL,
    `branch_id`       BIGINT UNSIGNED NULL,
    `effective_from`  DATE NOT NULL,
    `effective_to`    DATE NULL DEFAULT NULL,
    `is_active`       TINYINT(1) NOT NULL DEFAULT 1,
    `created_at`      TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`      TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`      BIGINT UNSIGNED NULL,
    `updated_by`      BIGINT UNSIGNED NULL,
    UNIQUE KEY `uq_service_catalog_code_branch` (`service_code`, `branch_id`),
    INDEX `idx_service_catalog_active` (`is_active`),
    CONSTRAINT `fk_service_catalog_branch` FOREIGN KEY (`branch_id`) REFERENCES `branches`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Discount rules
-- ──────────────────────────────────────────────
CREATE TABLE `discount_rules` (
    `id`                      BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `discount_code`           VARCHAR(50) NOT NULL,
    `name_ar`                 VARCHAR(200) NOT NULL,
    `name_en`                 VARCHAR(200) NULL,
    `discount_type`           VARCHAR(30) NOT NULL DEFAULT 'percentage',
    `value`                   DECIMAL(15,2) NOT NULL,
    `min_quantity`            INT UNSIGNED NULL,
    `max_quantity`            INT UNSIGNED NULL,
    `stackable`               TINYINT(1) NOT NULL DEFAULT 0,
    `max_discount_percentage` DECIMAL(5,2) NULL,
    `branch_id`               BIGINT UNSIGNED NULL,
    `effective_from`          DATE NOT NULL,
    `effective_to`            DATE NULL DEFAULT NULL,
    `is_active`               TINYINT(1) NOT NULL DEFAULT 1,
    `created_at`              TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`              TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`              BIGINT UNSIGNED NULL,
    `updated_by`              BIGINT UNSIGNED NULL,
    INDEX `idx_discount_rules_code` (`discount_code`),
    INDEX `idx_discount_rules_active` (`is_active`),
    CONSTRAINT `fk_discount_rules_branch` FOREIGN KEY (`branch_id`) REFERENCES `branches`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Per-entity rule overrides
-- ──────────────────────────────────────────────
CREATE TABLE `rule_overrides` (
    `id`                  BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `rule_id`             BIGINT UNSIGNED NOT NULL,
    `entity_type`         VARCHAR(100) NOT NULL,
    `entity_id`           BIGINT UNSIGNED NOT NULL,
    `override_value_json` JSON NOT NULL,
    `reason`              TEXT NOT NULL,
    `approved_by`         BIGINT UNSIGNED NULL,
    `effective_from`      DATE NOT NULL,
    `effective_to`        DATE NULL DEFAULT NULL,
    `is_active`           TINYINT(1) NOT NULL DEFAULT 1,
    `created_at`          TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    INDEX `idx_rule_overrides_rule` (`rule_id`),
    INDEX `idx_rule_overrides_entity` (`entity_type`, `entity_id`),
    CONSTRAINT `fk_rule_overrides_rule` FOREIGN KEY (`rule_id`) REFERENCES `business_rules`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB;


-- ════════════════════════════════════════════════════════════════
-- PHASE 06: FORMS ENGINE
-- ════════════════════════════════════════════════════════════════

-- ──────────────────────────────────────────────
-- Form field type definitions
-- ──────────────────────────────────────────────
CREATE TABLE `form_field_types` (
    `id`                   BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `type_code`            VARCHAR(50) NOT NULL,
    `name_ar`              VARCHAR(200) NOT NULL,
    `name_en`              VARCHAR(200) NULL,
    `renderer_config_json` JSON NULL,
    `validator_rules_json` JSON NULL,
    `is_system`            TINYINT(1) NOT NULL DEFAULT 0,
    `is_active`            TINYINT(1) NOT NULL DEFAULT 1,
    UNIQUE KEY `uq_form_field_types_code` (`type_code`)
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Form schemas (JSON-defined dynamic forms)
-- ──────────────────────────────────────────────
CREATE TABLE `form_schemas` (
    `id`            BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `form_code`     VARCHAR(50) NOT NULL,
    `name_ar`       VARCHAR(200) NOT NULL,
    `name_en`       VARCHAR(200) NULL,
    `form_fee`      DECIMAL(15,2) NOT NULL DEFAULT 0.00,
    `validity_days` INT UNSIGNED NULL,
    `schema_json`   JSON NOT NULL,
    `version`       INT UNSIGNED NOT NULL DEFAULT 1,
    `published_at`  TIMESTAMP NULL DEFAULT NULL,
    `is_active`     TINYINT(1) NOT NULL DEFAULT 1,
    `created_at`    TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`    TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`    BIGINT UNSIGNED NULL,
    `updated_by`    BIGINT UNSIGNED NULL,
    UNIQUE KEY `uq_form_schemas_code` (`form_code`),
    INDEX `idx_form_schemas_active` (`is_active`)
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Form submissions
-- ──────────────────────────────────────────────
CREATE TABLE `form_submissions` (
    `id`                      BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `form_schema_id`          BIGINT UNSIGNED NOT NULL,
    `schema_version`          INT UNSIGNED NOT NULL DEFAULT 1,
    `form_number`             VARCHAR(50) NOT NULL,
    `submitted_data_json`     JSON NOT NULL,
    `status`                  VARCHAR(50) NOT NULL DEFAULT 'draft',
    `submitted_by_employee_id` BIGINT UNSIGNED NULL,
    `member_id`               BIGINT UNSIGNED NULL,
    `expires_at`              TIMESTAMP NULL DEFAULT NULL,
    `fee_receipt_number`      VARCHAR(50) NULL,
    `notes`                   TEXT NULL,
    `created_at`              TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`              TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`              BIGINT UNSIGNED NULL,
    `updated_by`              BIGINT UNSIGNED NULL,
    UNIQUE KEY `uq_form_submissions_number` (`form_number`),
    INDEX `idx_form_submissions_schema` (`form_schema_id`),
    INDEX `idx_form_submissions_status` (`status`),
    INDEX `idx_form_submissions_member` (`member_id`),
    INDEX `idx_form_submissions_expires` (`expires_at`),
    CONSTRAINT `fk_form_submissions_schema` FOREIGN KEY (`form_schema_id`) REFERENCES `form_schemas`(`id`)
) ENGINE=InnoDB;


-- ════════════════════════════════════════════════════════════════
-- PHASE 07: WORKFLOW ENGINE
-- ════════════════════════════════════════════════════════════════

-- ──────────────────────────────────────────────
-- Workflow definitions (state machines)
-- ──────────────────────────────────────────────
CREATE TABLE `workflow_definitions` (
    `id`              BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `workflow_code`   VARCHAR(50) NOT NULL,
    `name_ar`         VARCHAR(200) NOT NULL,
    `name_en`         VARCHAR(200) NULL,
    `description_ar`  TEXT NULL,
    `definition_json` JSON NOT NULL,
    `version`         INT UNSIGNED NOT NULL DEFAULT 1,
    `is_active`       TINYINT(1) NOT NULL DEFAULT 1,
    `created_at`      TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`      TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`      BIGINT UNSIGNED NULL,
    `updated_by`      BIGINT UNSIGNED NULL,
    UNIQUE KEY `uq_workflow_defs_code` (`workflow_code`)
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Workflow instances (active processes)
-- ──────────────────────────────────────────────
CREATE TABLE `workflow_instances` (
    `id`                     BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `workflow_definition_id` BIGINT UNSIGNED NOT NULL,
    `workflow_code`          VARCHAR(50) NOT NULL,
    `entity_type`            VARCHAR(100) NOT NULL,
    `entity_id`              BIGINT UNSIGNED NOT NULL,
    `current_state`          VARCHAR(50) NOT NULL,
    `state_entered_at`       TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `state_data_json`        JSON NULL,
    `is_completed`           TINYINT(1) NOT NULL DEFAULT 0,
    `completed_at`           TIMESTAMP NULL DEFAULT NULL,
    `created_at`             TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`             TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    INDEX `idx_workflow_inst_def` (`workflow_definition_id`),
    INDEX `idx_workflow_inst_entity` (`entity_type`, `entity_id`),
    INDEX `idx_workflow_inst_state` (`current_state`),
    INDEX `idx_workflow_inst_completed` (`is_completed`),
    CONSTRAINT `fk_workflow_inst_def` FOREIGN KEY (`workflow_definition_id`) REFERENCES `workflow_definitions`(`id`)
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Workflow transition log — IMMUTABLE
-- ──────────────────────────────────────────────
CREATE TABLE `workflow_transition_log` (
    `id`                       BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `workflow_instance_id`     BIGINT UNSIGNED NOT NULL,
    `from_state`               VARCHAR(50) NOT NULL,
    `to_state`                 VARCHAR(50) NOT NULL,
    `transition_name`          VARCHAR(100) NOT NULL,
    `triggered_by_employee_id` BIGINT UNSIGNED NULL,
    `trigger_type`             VARCHAR(30) NOT NULL DEFAULT 'manual',
    `guard_results_json`       JSON NULL,
    `notes`                    TEXT NULL,
    `created_at`               TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    INDEX `idx_wf_trans_log_inst` (`workflow_instance_id`),
    INDEX `idx_wf_trans_log_date` (`created_at`),
    CONSTRAINT `fk_wf_trans_log_inst` FOREIGN KEY (`workflow_instance_id`) REFERENCES `workflow_instances`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB;


-- ════════════════════════════════════════════════════════════════
-- PHASE 08: MEMBER CORE & NATIONAL ID SYSTEM
-- ════════════════════════════════════════════════════════════════

-- ──────────────────────────────────────────────
-- Members — THE central table of the entire system
-- Every field from spec Section 43.2
-- ──────────────────────────────────────────────
CREATE TABLE `members` (
    `id`                     BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,

    -- Membership identity
    `membership_number`      VARCHAR(20) NULL,
    `form_number`            VARCHAR(50) NULL,
    `form_date`              DATE NULL,
    `form_submission_id`     BIGINT UNSIGNED NULL,
    `branch_id`              BIGINT UNSIGNED NOT NULL,
    `membership_type`        VARCHAR(50) NOT NULL DEFAULT 'working',
    `member_category`        VARCHAR(50) NOT NULL DEFAULT 'working_member',
    `status`                 VARCHAR(50) NOT NULL DEFAULT 'potential',

    -- Personal information
    `full_name_ar`           VARCHAR(200) NOT NULL,
    `full_name_en`           VARCHAR(200) NULL,
    `national_id`            VARCHAR(14) NULL,
    `passport_number`        VARCHAR(50) NULL,
    `id_type`                VARCHAR(20) NOT NULL DEFAULT 'national_id',
    `id_issue_date`          DATE NULL,
    `id_expiry_date`         DATE NULL,
    `date_of_birth`          DATE NOT NULL,
    `age_years`              INT UNSIGNED NULL,
    `age_months`             INT UNSIGNED NULL,
    `gender`                 VARCHAR(10) NOT NULL,
    `place_of_birth`         VARCHAR(200) NULL,
    `nationality`            VARCHAR(100) NULL DEFAULT 'مصري',
    `governorate_code`       VARCHAR(2) NULL,
    `religion`               VARCHAR(50) NULL,
    `qualification_id`       BIGINT UNSIGNED NULL,
    `marital_status`         VARCHAR(30) NULL,

    -- Contact
    `phone_home`             VARCHAR(20) NULL,
    `phone_mobile`           VARCHAR(20) NOT NULL,
    `phone_international`    VARCHAR(30) NULL,
    `email`                  VARCHAR(255) NULL,
    `emergency_name`         VARCHAR(200) NULL,
    `emergency_phone`        VARCHAR(20) NULL,

    -- Residence
    `residence_type`         VARCHAR(30) NULL,
    `residence_address`      TEXT NULL,
    `landmark`               VARCHAR(200) NULL,
    `floor`                  VARCHAR(20) NULL,
    `apartment`              VARCHAR(20) NULL,
    `area`                   VARCHAR(100) NULL,
    `governorate`            VARCHAR(100) NULL,
    `correspondence_address` VARCHAR(50) NULL,

    -- Work
    `employment_type`        VARCHAR(50) NULL,
    `occupation`             VARCHAR(200) NULL,
    `job_title`              VARCHAR(200) NULL,
    `employment_date`        DATE NULL,
    `business_address`       TEXT NULL,
    `office_phone`           VARCHAR(20) NULL,
    `office_fax`             VARCHAR(20) NULL,
    `business_activity`      VARCHAR(200) NULL,

    -- Membership financial
    `membership_value`       DECIMAL(15,2) NULL,
    `payment_method`         VARCHAR(30) NULL,
    `referral_source`        VARCHAR(100) NULL,
    `photo_path`             VARCHAR(500) NULL,

    -- Workflow link
    `workflow_instance_id`   BIGINT UNSIGNED NULL,

    -- Standard audit columns
    `created_at`             TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`             TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`             BIGINT UNSIGNED NULL,
    `updated_by`             BIGINT UNSIGNED NULL,
    `is_archived`            TINYINT(1) NOT NULL DEFAULT 0,
    `archived_at`            TIMESTAMP NULL DEFAULT NULL,
    `archived_by`            BIGINT UNSIGNED NULL,

    UNIQUE KEY `uq_members_membership_number` (`membership_number`),
    UNIQUE KEY `uq_members_national_id` (`national_id`),
    INDEX `idx_members_branch` (`branch_id`),
    INDEX `idx_members_status` (`status`),
    INDEX `idx_members_type` (`membership_type`),
    INDEX `idx_members_name_ar` (`full_name_ar`),
    INDEX `idx_members_phone` (`phone_mobile`),
    INDEX `idx_members_passport` (`passport_number`),
    INDEX `idx_members_form` (`form_number`),
    INDEX `idx_members_archived` (`is_archived`),
    INDEX `idx_members_qualification` (`qualification_id`),
    INDEX `idx_members_workflow` (`workflow_instance_id`),
    CONSTRAINT `fk_members_branch` FOREIGN KEY (`branch_id`) REFERENCES `branches`(`id`),
    CONSTRAINT `fk_members_qualification` FOREIGN KEY (`qualification_id`) REFERENCES `qualifications`(`id`) ON DELETE SET NULL,
    CONSTRAINT `fk_members_form_sub` FOREIGN KEY (`form_submission_id`) REFERENCES `form_submissions`(`id`) ON DELETE SET NULL,
    CONSTRAINT `fk_members_workflow` FOREIGN KEY (`workflow_instance_id`) REFERENCES `workflow_instances`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Member notes (append-only)
-- ──────────────────────────────────────────────
CREATE TABLE `member_notes` (
    `id`          BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `member_id`   BIGINT UNSIGNED NOT NULL,
    `note_text`   TEXT NOT NULL,
    `created_at`  TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `created_by`  BIGINT UNSIGNED NULL,
    INDEX `idx_member_notes_member` (`member_id`),
    CONSTRAINT `fk_member_notes_member` FOREIGN KEY (`member_id`) REFERENCES `members`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB;


-- ════════════════════════════════════════════════════════════════
-- PHASE 09: SPOUSE & CHILDREN MANAGEMENT
-- ════════════════════════════════════════════════════════════════

-- ──────────────────────────────────────────────
-- Spouses
-- ──────────────────────────────────────────────
CREATE TABLE `spouses` (
    `id`                 BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `member_id`          BIGINT UNSIGNED NOT NULL,
    `spouse_order`       INT UNSIGNED NOT NULL DEFAULT 1,
    `full_name_ar`       VARCHAR(200) NOT NULL,
    `full_name_en`       VARCHAR(200) NULL,
    `national_id`        VARCHAR(14) NULL,
    `passport_number`    VARCHAR(50) NULL,
    `date_of_birth`      DATE NOT NULL,
    `age_years`          INT UNSIGNED NULL,
    `age_months`         INT UNSIGNED NULL,
    `gender`             VARCHAR(10) NOT NULL,
    `nationality`        VARCHAR(100) NULL DEFAULT 'مصري',
    `religion`           VARCHAR(50) NULL,
    `qualification_id`   BIGINT UNSIGNED NULL,
    `occupation`         VARCHAR(200) NULL,
    `work_address`       TEXT NULL,
    `work_phone`         VARCHAR(20) NULL,
    `mobile`             VARCHAR(20) NULL,
    `marriage_date`      DATE NOT NULL,
    `join_date`          DATE NOT NULL,
    `classification`     VARCHAR(30) NOT NULL DEFAULT 'working',
    `addition_fee`       DECIMAL(15,2) NOT NULL DEFAULT 0.00,
    `fee_receipt_number` VARCHAR(50) NULL,
    `status`             VARCHAR(50) NOT NULL DEFAULT 'active',
    `photo_path`         VARCHAR(500) NULL,
    `is_archived`        TINYINT(1) NOT NULL DEFAULT 0,
    `archived_at`        TIMESTAMP NULL DEFAULT NULL,
    `archived_by`        BIGINT UNSIGNED NULL,
    `created_at`         TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`         TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`         BIGINT UNSIGNED NULL,
    `updated_by`         BIGINT UNSIGNED NULL,
    INDEX `idx_spouses_member` (`member_id`),
    INDEX `idx_spouses_nid` (`national_id`),
    INDEX `idx_spouses_status` (`status`),
    INDEX `idx_spouses_archived` (`is_archived`),
    CONSTRAINT `fk_spouses_member` FOREIGN KEY (`member_id`) REFERENCES `members`(`id`),
    CONSTRAINT `fk_spouses_qualification` FOREIGN KEY (`qualification_id`) REFERENCES `qualifications`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Children
-- ──────────────────────────────────────────────
CREATE TABLE `children` (
    `id`                       BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `member_id`                BIGINT UNSIGNED NOT NULL,
    `child_order`              INT UNSIGNED NOT NULL DEFAULT 1,
    `full_name_ar`             VARCHAR(200) NOT NULL,
    `full_name_en`             VARCHAR(200) NULL,
    `national_id`              VARCHAR(14) NULL,
    `birth_certificate_number` VARCHAR(50) NULL,
    `date_of_birth`            DATE NOT NULL,
    `age_years`                INT UNSIGNED NULL,
    `age_months`               INT UNSIGNED NULL,
    `gender`                   VARCHAR(10) NOT NULL,
    `relationship`             VARCHAR(30) NOT NULL DEFAULT 'son',
    `school_faculty`           VARCHAR(200) NULL,
    `nationality`              VARCHAR(100) NULL DEFAULT 'مصري',
    `classification`           VARCHAR(50) NOT NULL DEFAULT 'included',
    `addition_fee`             DECIMAL(15,2) NOT NULL DEFAULT 0.00,
    `fee_receipt_number`       VARCHAR(50) NULL,
    `status`                   VARCHAR(50) NOT NULL DEFAULT 'active',
    `is_frozen`                TINYINT(1) NOT NULL DEFAULT 0,
    `frozen_at`                TIMESTAMP NULL DEFAULT NULL,
    `frozen_reason`            VARCHAR(200) NULL,
    `photo_path`               VARCHAR(500) NULL,
    `remarks`                  TEXT NULL,
    `is_archived`              TINYINT(1) NOT NULL DEFAULT 0,
    `archived_at`              TIMESTAMP NULL DEFAULT NULL,
    `archived_by`              BIGINT UNSIGNED NULL,
    `created_at`               TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`               TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`               BIGINT UNSIGNED NULL,
    `updated_by`               BIGINT UNSIGNED NULL,
    INDEX `idx_children_member` (`member_id`),
    INDEX `idx_children_nid` (`national_id`),
    INDEX `idx_children_status` (`status`),
    INDEX `idx_children_classification` (`classification`),
    INDEX `idx_children_frozen` (`is_frozen`),
    INDEX `idx_children_dob` (`date_of_birth`),
    INDEX `idx_children_archived` (`is_archived`),
    CONSTRAINT `fk_children_member` FOREIGN KEY (`member_id`) REFERENCES `members`(`id`)
) ENGINE=InnoDB;


-- ════════════════════════════════════════════════════════════════
-- PHASE 10: TEMPORARY, SEASONAL, SPORTS, HONORARY & FOREIGN
-- ════════════════════════════════════════════════════════════════

-- ──────────────────────────────────────────────
-- Temporary members (8 categories)
-- ──────────────────────────────────────────────
CREATE TABLE `temporary_members` (
    `id`                          BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `member_id`                   BIGINT UNSIGNED NOT NULL,
    `category`                    VARCHAR(50) NOT NULL,
    `full_name_ar`                VARCHAR(200) NOT NULL,
    `full_name_en`                VARCHAR(200) NULL,
    `national_id`                 VARCHAR(14) NULL,
    `passport_number`             VARCHAR(50) NULL,
    `date_of_birth`               DATE NOT NULL,
    `age_years`                   INT UNSIGNED NULL,
    `age_months`                  INT UNSIGNED NULL,
    `gender`                      VARCHAR(10) NOT NULL,
    `nationality`                 VARCHAR(100) NULL DEFAULT 'مصري',
    `relationship_to_member`      VARCHAR(100) NULL,
    `has_championship`            TINYINT(1) NOT NULL DEFAULT 0,
    `disability_documentation`    TINYINT(1) NOT NULL DEFAULT 0,
    `addition_fee`                DECIMAL(15,2) NOT NULL DEFAULT 0.00,
    `fee_receipt_number`          VARCHAR(50) NULL,
    `can_separate`                TINYINT(1) NOT NULL DEFAULT 0,
    `can_get_independent`         TINYINT(1) NOT NULL DEFAULT 0,
    `status`                      VARCHAR(50) NOT NULL DEFAULT 'active',
    `photo_path`                  VARCHAR(500) NULL,
    `notes`                       TEXT NULL,
    `is_archived`                 TINYINT(1) NOT NULL DEFAULT 0,
    `archived_at`                 TIMESTAMP NULL DEFAULT NULL,
    `archived_by`                 BIGINT UNSIGNED NULL,
    `created_at`                  TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`                  TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`                  BIGINT UNSIGNED NULL,
    `updated_by`                  BIGINT UNSIGNED NULL,
    INDEX `idx_temp_members_member` (`member_id`),
    INDEX `idx_temp_members_category` (`category`),
    INDEX `idx_temp_members_nid` (`national_id`),
    INDEX `idx_temp_members_status` (`status`),
    INDEX `idx_temp_members_archived` (`is_archived`),
    CONSTRAINT `fk_temp_members_member` FOREIGN KEY (`member_id`) REFERENCES `members`(`id`)
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Seasonal memberships
-- ──────────────────────────────────────────────
CREATE TABLE `seasonal_memberships` (
    `id`                 BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `member_id`          BIGINT UNSIGNED NOT NULL,
    `branch_id`          BIGINT UNSIGNED NOT NULL,
    `start_date`         DATE NOT NULL,
    `end_date`           DATE NOT NULL,
    `fee_amount`         DECIMAL(15,2) NOT NULL,
    `fee_receipt_number` VARCHAR(50) NULL,
    `status`             VARCHAR(50) NOT NULL DEFAULT 'active',
    `carnet_marking`     VARCHAR(100) NULL,
    `notes`              TEXT NULL,
    `is_archived`        TINYINT(1) NOT NULL DEFAULT 0,
    `archived_at`        TIMESTAMP NULL DEFAULT NULL,
    `archived_by`        BIGINT UNSIGNED NULL,
    `created_at`         TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`         TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`         BIGINT UNSIGNED NULL,
    `updated_by`         BIGINT UNSIGNED NULL,
    INDEX `idx_seasonal_member` (`member_id`),
    INDEX `idx_seasonal_status` (`status`),
    INDEX `idx_seasonal_dates` (`start_date`, `end_date`),
    CONSTRAINT `fk_seasonal_member` FOREIGN KEY (`member_id`) REFERENCES `members`(`id`),
    CONSTRAINT `fk_seasonal_branch` FOREIGN KEY (`branch_id`) REFERENCES `branches`(`id`)
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Sports members (federation tracking + conversion)
-- ──────────────────────────────────────────────
CREATE TABLE `sports_members` (
    `id`                       BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `member_id`                BIGINT UNSIGNED NOT NULL,
    `sport_name`               VARCHAR(200) NOT NULL,
    `federation_name`          VARCHAR(200) NULL,
    `federation_registration`  VARCHAR(100) NULL,
    `registration_date`        DATE NULL,
    `years_of_service`         INT UNSIGNED NOT NULL DEFAULT 0,
    `highest_competitive_level` VARCHAR(200) NULL,
    `is_conversion_eligible`   TINYINT(1) NOT NULL DEFAULT 0,
    `conversion_requested`     TINYINT(1) NOT NULL DEFAULT 0,
    `conversion_date`          DATE NULL,
    `conversion_fee`           DECIMAL(15,2) NULL,
    `conversion_receipt`       VARCHAR(50) NULL,
    `status`                   VARCHAR(50) NOT NULL DEFAULT 'active',
    `notes`                    TEXT NULL,
    `is_archived`              TINYINT(1) NOT NULL DEFAULT 0,
    `archived_at`              TIMESTAMP NULL DEFAULT NULL,
    `archived_by`              BIGINT UNSIGNED NULL,
    `created_at`               TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`               TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`               BIGINT UNSIGNED NULL,
    `updated_by`               BIGINT UNSIGNED NULL,
    INDEX `idx_sports_member` (`member_id`),
    INDEX `idx_sports_status` (`status`),
    CONSTRAINT `fk_sports_member` FOREIGN KEY (`member_id`) REFERENCES `members`(`id`)
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Honorary members (Board-granted, zero fees)
-- ──────────────────────────────────────────────
CREATE TABLE `honorary_members` (
    `id`                      BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `member_id`               BIGINT UNSIGNED NOT NULL,
    `granted_by_decision`     VARCHAR(200) NULL,
    `reason`                  TEXT NOT NULL,
    `start_date`              DATE NOT NULL,
    `end_date`                DATE NOT NULL,
    `is_renewable`            TINYINT(1) NOT NULL DEFAULT 1,
    `renewal_count`           INT UNSIGNED NOT NULL DEFAULT 0,
    `last_renewed_at`         TIMESTAMP NULL DEFAULT NULL,
    `status`                  VARCHAR(50) NOT NULL DEFAULT 'active',
    `notes`                   TEXT NULL,
    `is_archived`             TINYINT(1) NOT NULL DEFAULT 0,
    `archived_at`             TIMESTAMP NULL DEFAULT NULL,
    `archived_by`             BIGINT UNSIGNED NULL,
    `created_at`              TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`              TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`              BIGINT UNSIGNED NULL,
    `updated_by`              BIGINT UNSIGNED NULL,
    INDEX `idx_honorary_member` (`member_id`),
    INDEX `idx_honorary_status` (`status`),
    INDEX `idx_honorary_end_date` (`end_date`),
    CONSTRAINT `fk_honorary_member` FOREIGN KEY (`member_id`) REFERENCES `members`(`id`)
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Foreign member details (passport-based, USD pricing)
-- ──────────────────────────────────────────────
CREATE TABLE `foreign_member_details` (
    `id`                       BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `member_id`                BIGINT UNSIGNED NOT NULL,
    `passport_number`          VARCHAR(50) NOT NULL,
    `issuing_country_id`       BIGINT UNSIGNED NOT NULL,
    `nationality_country_id`   BIGINT UNSIGNED NOT NULL,
    `passport_issue_date`      DATE NOT NULL,
    `passport_expiry_date`     DATE NOT NULL,
    `place_of_birth`           VARCHAR(200) NULL,
    `fee_amount_usd`           DECIMAL(15,2) NOT NULL,
    `exchange_rate`            DECIMAL(15,4) NULL,
    `fee_amount_egp`           DECIMAL(15,2) NULL,
    `fee_receipt_number`       VARCHAR(50) NULL,
    `status`                   VARCHAR(50) NOT NULL DEFAULT 'active',
    `notes`                    TEXT NULL,
    `is_archived`              TINYINT(1) NOT NULL DEFAULT 0,
    `archived_at`              TIMESTAMP NULL DEFAULT NULL,
    `archived_by`              BIGINT UNSIGNED NULL,
    `created_at`               TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`               TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`               BIGINT UNSIGNED NULL,
    `updated_by`               BIGINT UNSIGNED NULL,
    INDEX `idx_foreign_member` (`member_id`),
    INDEX `idx_foreign_passport` (`passport_number`),
    INDEX `idx_foreign_expiry` (`passport_expiry_date`),
    CONSTRAINT `fk_foreign_member` FOREIGN KEY (`member_id`) REFERENCES `members`(`id`),
    CONSTRAINT `fk_foreign_issuing_country` FOREIGN KEY (`issuing_country_id`) REFERENCES `countries`(`id`),
    CONSTRAINT `fk_foreign_nationality_country` FOREIGN KEY (`nationality_country_id`) REFERENCES `countries`(`id`)
) ENGINE=InnoDB;


-- ════════════════════════════════════════════════════════════════
-- PHASE 11: PAYMENT, TREASURY & RECEIPT MANAGEMENT
-- ════════════════════════════════════════════════════════════════

-- ──────────────────────────────────────────────
-- Payment methods (reference table)
-- ──────────────────────────────────────────────
CREATE TABLE `payment_methods` (
    `id`         BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `code`       VARCHAR(30) NOT NULL,
    `name_ar`    VARCHAR(100) NOT NULL,
    `name_en`    VARCHAR(100) NULL,
    `is_active`  TINYINT(1) NOT NULL DEFAULT 1,
    `sort_order` INT UNSIGNED NOT NULL DEFAULT 0,
    UNIQUE KEY `uq_payment_methods_code` (`code`)
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Payments (receipt_id FK added via ALTER TABLE below)
-- ──────────────────────────────────────────────
CREATE TABLE `payments` (
    `id`                      BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `member_id`               BIGINT UNSIGNED NOT NULL,
    `receipt_id`              BIGINT UNSIGNED NULL,
    `payment_type`            VARCHAR(50) NOT NULL,
    `amount`                  DECIMAL(15,2) NOT NULL,
    `currency`                VARCHAR(3) NOT NULL DEFAULT 'EGP',
    `payment_method`          VARCHAR(30) NOT NULL DEFAULT 'cash',
    `check_number`            VARCHAR(50) NULL,
    `check_bank`              VARCHAR(200) NULL,
    `check_date`              DATE NULL,
    `check_status`            VARCHAR(30) NULL,
    `visa_reference`          VARCHAR(100) NULL,
    `transfer_reference`      VARCHAR(100) NULL,
    `transfer_bank`           VARCHAR(200) NULL,
    `related_entity_type`     VARCHAR(100) NULL,
    `related_entity_id`       BIGINT UNSIGNED NULL,
    `notes`                   TEXT NULL,
    `payment_date`            DATE NOT NULL,
    `received_by_employee_id` BIGINT UNSIGNED NULL,
    `is_voided`               TINYINT(1) NOT NULL DEFAULT 0,
    `voided_at`               TIMESTAMP NULL DEFAULT NULL,
    `voided_by`               BIGINT UNSIGNED NULL,
    `void_reason`             TEXT NULL,
    `created_at`              TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`              TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`              BIGINT UNSIGNED NULL,
    `updated_by`              BIGINT UNSIGNED NULL,
    INDEX `idx_payments_member` (`member_id`),
    INDEX `idx_payments_receipt` (`receipt_id`),
    INDEX `idx_payments_type` (`payment_type`),
    INDEX `idx_payments_method` (`payment_method`),
    INDEX `idx_payments_date` (`payment_date`),
    INDEX `idx_payments_voided` (`is_voided`),
    INDEX `idx_payments_related` (`related_entity_type`, `related_entity_id`),
    INDEX `idx_payments_check_status` (`check_status`),
    CONSTRAINT `fk_payments_member` FOREIGN KEY (`member_id`) REFERENCES `members`(`id`),
    CONSTRAINT `chk_payments_amount` CHECK (`amount` >= 0)
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Receipts
-- ──────────────────────────────────────────────
CREATE TABLE `receipts` (
    `id`                      BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `receipt_number`          VARCHAR(50) NOT NULL,
    `member_id`               BIGINT UNSIGNED NOT NULL,
    `payment_id`              BIGINT UNSIGNED NULL,
    `receipt_type`            VARCHAR(30) NOT NULL DEFAULT 'payment',
    `amount`                  DECIMAL(15,2) NOT NULL,
    `amount_in_words_ar`      TEXT NULL,
    `description_ar`          TEXT NULL,
    `issued_by_employee_id`   BIGINT UNSIGNED NULL,
    `issued_at`               TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `is_voided`               TINYINT(1) NOT NULL DEFAULT 0,
    `voided_at`               TIMESTAMP NULL DEFAULT NULL,
    `voided_by`               BIGINT UNSIGNED NULL,
    `void_reason`             TEXT NULL,
    `print_count`             INT UNSIGNED NOT NULL DEFAULT 0,
    `last_printed_at`         TIMESTAMP NULL DEFAULT NULL,
    `last_printed_by`         BIGINT UNSIGNED NULL,
    `created_at`              TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY `uq_receipts_number` (`receipt_number`),
    INDEX `idx_receipts_member` (`member_id`),
    INDEX `idx_receipts_payment` (`payment_id`),
    INDEX `idx_receipts_type` (`receipt_type`),
    INDEX `idx_receipts_voided` (`is_voided`),
    INDEX `idx_receipts_date` (`issued_at`),
    CONSTRAINT `fk_receipts_member` FOREIGN KEY (`member_id`) REFERENCES `members`(`id`),
    CONSTRAINT `fk_receipts_payment` FOREIGN KEY (`payment_id`) REFERENCES `payments`(`id`) ON DELETE SET NULL,
    CONSTRAINT `chk_receipts_amount` CHECK (`amount` >= 0)
) ENGINE=InnoDB;

-- Circular FK: payments.receipt_id → receipts.id
ALTER TABLE `payments`
    ADD CONSTRAINT `fk_payments_receipt` FOREIGN KEY (`receipt_id`) REFERENCES `receipts`(`id`) ON DELETE SET NULL;


-- ════════════════════════════════════════════════════════════════
-- PHASE 12: INSTALLMENTS, SUBSCRIPTIONS & FINES
-- ════════════════════════════════════════════════════════════════

-- ──────────────────────────────────────────────
-- Installment plans
-- ──────────────────────────────────────────────
CREATE TABLE `installment_plans` (
    `id`                   BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `member_id`            BIGINT UNSIGNED NOT NULL,
    `related_entity_type`  VARCHAR(100) NULL,
    `related_entity_id`    BIGINT UNSIGNED NULL,
    `total_amount`         DECIMAL(15,2) NOT NULL,
    `down_payment`         DECIMAL(15,2) NOT NULL,
    `remaining_balance`    DECIMAL(15,2) NOT NULL,
    `interest_rate`        DECIMAL(5,2) NOT NULL DEFAULT 22.00,
    `total_interest`       DECIMAL(15,2) NOT NULL DEFAULT 0.00,
    `total_with_interest`  DECIMAL(15,2) NOT NULL,
    `number_of_months`     INT UNSIGNED NOT NULL,
    `monthly_payment`      DECIMAL(15,2) NOT NULL,
    `start_date`           DATE NOT NULL,
    `down_payment_receipt` VARCHAR(50) NULL,
    `cash_settlement_date` DATE NULL,
    `is_cash_settled`      TINYINT(1) NOT NULL DEFAULT 0,
    `status`               VARCHAR(50) NOT NULL DEFAULT 'active',
    `notes`                TEXT NULL,
    `created_at`           TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`           TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`           BIGINT UNSIGNED NULL,
    `updated_by`           BIGINT UNSIGNED NULL,
    INDEX `idx_installment_plans_member` (`member_id`),
    INDEX `idx_installment_plans_status` (`status`),
    CONSTRAINT `fk_installment_plans_member` FOREIGN KEY (`member_id`) REFERENCES `members`(`id`),
    CONSTRAINT `chk_installment_down` CHECK (`down_payment` >= 0),
    CONSTRAINT `chk_installment_total` CHECK (`total_amount` > 0)
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Installment schedule items
-- ──────────────────────────────────────────────
CREATE TABLE `installment_schedule` (
    `id`                  BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `installment_plan_id` BIGINT UNSIGNED NOT NULL,
    `installment_number`  INT UNSIGNED NOT NULL,
    `due_date`            DATE NOT NULL,
    `amount`              DECIMAL(15,2) NOT NULL,
    `principal`           DECIMAL(15,2) NOT NULL,
    `interest`            DECIMAL(15,2) NOT NULL DEFAULT 0.00,
    `remaining_after`     DECIMAL(15,2) NOT NULL DEFAULT 0.00,
    `paid_amount`         DECIMAL(15,2) NOT NULL DEFAULT 0.00,
    `payment_id`          BIGINT UNSIGNED NULL,
    `status`              VARCHAR(30) NOT NULL DEFAULT 'pending',
    `paid_at`             TIMESTAMP NULL DEFAULT NULL,
    `created_at`          TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`          TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    INDEX `idx_installment_sched_plan` (`installment_plan_id`),
    INDEX `idx_installment_sched_due` (`due_date`),
    INDEX `idx_installment_sched_status` (`status`),
    CONSTRAINT `fk_installment_sched_plan` FOREIGN KEY (`installment_plan_id`) REFERENCES `installment_plans`(`id`) ON DELETE CASCADE,
    CONSTRAINT `fk_installment_sched_payment` FOREIGN KEY (`payment_id`) REFERENCES `payments`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Annual subscriptions
-- ──────────────────────────────────────────────
CREATE TABLE `subscriptions` (
    `id`               BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `member_id`        BIGINT UNSIGNED NOT NULL,
    `financial_year`   VARCHAR(10) NOT NULL,
    `person_type`      VARCHAR(50) NOT NULL,
    `person_id`        BIGINT UNSIGNED NULL,
    `person_name`      VARCHAR(200) NULL,
    `base_amount`      DECIMAL(15,2) NOT NULL DEFAULT 0.00,
    `development_fee`  DECIMAL(15,2) NOT NULL DEFAULT 0.00,
    `discount_amount`  DECIMAL(15,2) NOT NULL DEFAULT 0.00,
    `total_amount`     DECIMAL(15,2) NOT NULL DEFAULT 0.00,
    `paid_amount`      DECIMAL(15,2) NOT NULL DEFAULT 0.00,
    `fine_amount`      DECIMAL(15,2) NOT NULL DEFAULT 0.00,
    `status`           VARCHAR(50) NOT NULL DEFAULT 'pending',
    `paid_at`          TIMESTAMP NULL DEFAULT NULL,
    `payment_id`       BIGINT UNSIGNED NULL,
    `exempted_by`      BIGINT UNSIGNED NULL,
    `exemption_reason` TEXT NULL,
    `created_at`       TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`       TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`       BIGINT UNSIGNED NULL,
    `updated_by`       BIGINT UNSIGNED NULL,
    INDEX `idx_subscriptions_member` (`member_id`),
    INDEX `idx_subscriptions_year` (`financial_year`),
    INDEX `idx_subscriptions_status` (`status`),
    INDEX `idx_subscriptions_person` (`person_type`, `person_id`),
    CONSTRAINT `fk_subscriptions_member` FOREIGN KEY (`member_id`) REFERENCES `members`(`id`),
    CONSTRAINT `fk_subscriptions_payment` FOREIGN KEY (`payment_id`) REFERENCES `payments`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Violations
-- ──────────────────────────────────────────────
CREATE TABLE `violations` (
    `id`              BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `member_id`       BIGINT UNSIGNED NOT NULL,
    `violation_date`  DATE NOT NULL,
    `description`     TEXT NOT NULL,
    `reported_by`     BIGINT UNSIGNED NULL,
    `evidence_notes`  TEXT NULL,
    `status`          VARCHAR(50) NOT NULL DEFAULT 'reported',
    `created_at`      TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`      TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`      BIGINT UNSIGNED NULL,
    `updated_by`      BIGINT UNSIGNED NULL,
    INDEX `idx_violations_member` (`member_id`),
    INDEX `idx_violations_status` (`status`),
    INDEX `idx_violations_date` (`violation_date`),
    CONSTRAINT `fk_violations_member` FOREIGN KEY (`member_id`) REFERENCES `members`(`id`)
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Fines (from violations or late subscriptions)
-- ──────────────────────────────────────────────
CREATE TABLE `fines` (
    `id`                  BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `member_id`           BIGINT UNSIGNED NOT NULL,
    `violation_id`        BIGINT UNSIGNED NULL,
    `fine_type`           VARCHAR(50) NOT NULL DEFAULT 'violation_fine',
    `amount`              DECIMAL(15,2) NOT NULL,
    `penalty_type`        VARCHAR(50) NOT NULL DEFAULT 'fine',
    `suspension_from`     DATE NULL,
    `suspension_to`       DATE NULL,
    `appeal_submitted`    TINYINT(1) NOT NULL DEFAULT 0,
    `appeal_date`         DATE NULL,
    `appeal_notes`        TEXT NULL,
    `appeal_decision`     VARCHAR(50) NULL,
    `appeal_decided_by`   BIGINT UNSIGNED NULL,
    `appeal_decided_at`   TIMESTAMP NULL DEFAULT NULL,
    `status`              VARCHAR(50) NOT NULL DEFAULT 'imposed',
    `paid_amount`         DECIMAL(15,2) NOT NULL DEFAULT 0.00,
    `payment_id`          BIGINT UNSIGNED NULL,
    `paid_at`             TIMESTAMP NULL DEFAULT NULL,
    `notes`               TEXT NULL,
    `created_at`          TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`          TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`          BIGINT UNSIGNED NULL,
    `updated_by`          BIGINT UNSIGNED NULL,
    INDEX `idx_fines_member` (`member_id`),
    INDEX `idx_fines_violation` (`violation_id`),
    INDEX `idx_fines_type` (`fine_type`),
    INDEX `idx_fines_penalty` (`penalty_type`),
    INDEX `idx_fines_status` (`status`),
    INDEX `idx_fines_suspension` (`suspension_from`, `suspension_to`),
    CONSTRAINT `fk_fines_member` FOREIGN KEY (`member_id`) REFERENCES `members`(`id`),
    CONSTRAINT `fk_fines_violation` FOREIGN KEY (`violation_id`) REFERENCES `violations`(`id`) ON DELETE SET NULL,
    CONSTRAINT `fk_fines_payment` FOREIGN KEY (`payment_id`) REFERENCES `payments`(`id`) ON DELETE SET NULL,
    CONSTRAINT `chk_fines_amount` CHECK (`amount` >= 0)
) ENGINE=InnoDB;


-- ════════════════════════════════════════════════════════════════
-- PHASE 13: TRANSFERS, SEPARATIONS, DIVORCE, DEATH & WAIVER
-- ════════════════════════════════════════════════════════════════

-- ──────────────────────────────────────────────
-- Transfer / Separation requests
-- ──────────────────────────────────────────────
CREATE TABLE `transfer_requests` (
    `id`                         BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `source_member_id`           BIGINT UNSIGNED NOT NULL,
    `target_member_id`           BIGINT UNSIGNED NULL,
    `transfer_type`              VARCHAR(50) NOT NULL,
    `child_id`                   BIGINT UNSIGNED NULL,
    `spouse_id`                  BIGINT UNSIGNED NULL,
    `source_membership_number`   VARCHAR(20) NULL,
    `new_membership_number`      VARCHAR(20) NULL,
    `new_membership_value`       DECIMAL(15,2) NULL,
    `years_since_acquisition`    INT UNSIGNED NULL,
    `qualification_code`         VARCHAR(20) NULL,
    `fee_percentage`             DECIMAL(5,2) NULL,
    `separation_fee`             DECIMAL(15,2) NULL,
    `form_fee`                   DECIMAL(15,2) NULL,
    `annual_subscription_fee`    DECIMAL(15,2) NULL,
    `total_fee`                  DECIMAL(15,2) NULL,
    `archive_snapshot_id`        BIGINT UNSIGNED NULL,
    `workflow_instance_id`       BIGINT UNSIGNED NULL,
    `board_decision_notes`       TEXT NULL,
    `approved_by`                BIGINT UNSIGNED NULL,
    `approved_at`                TIMESTAMP NULL DEFAULT NULL,
    `completed_at`               TIMESTAMP NULL DEFAULT NULL,
    `status`                     VARCHAR(50) NOT NULL DEFAULT 'requested',
    `notes`                      TEXT NULL,
    `created_at`                 TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`                 TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`                 BIGINT UNSIGNED NULL,
    `updated_by`                 BIGINT UNSIGNED NULL,
    INDEX `idx_transfers_source` (`source_member_id`),
    INDEX `idx_transfers_target` (`target_member_id`),
    INDEX `idx_transfers_type` (`transfer_type`),
    INDEX `idx_transfers_status` (`status`),
    INDEX `idx_transfers_child` (`child_id`),
    INDEX `idx_transfers_spouse` (`spouse_id`),
    CONSTRAINT `fk_transfers_source` FOREIGN KEY (`source_member_id`) REFERENCES `members`(`id`),
    CONSTRAINT `fk_transfers_target` FOREIGN KEY (`target_member_id`) REFERENCES `members`(`id`) ON DELETE SET NULL,
    CONSTRAINT `fk_transfers_child` FOREIGN KEY (`child_id`) REFERENCES `children`(`id`) ON DELETE SET NULL,
    CONSTRAINT `fk_transfers_spouse` FOREIGN KEY (`spouse_id`) REFERENCES `spouses`(`id`) ON DELETE SET NULL,
    CONSTRAINT `fk_transfers_snapshot` FOREIGN KEY (`archive_snapshot_id`) REFERENCES `archive_snapshots`(`id`) ON DELETE SET NULL,
    CONSTRAINT `fk_transfers_workflow` FOREIGN KEY (`workflow_instance_id`) REFERENCES `workflow_instances`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Divorce cases
-- ──────────────────────────────────────────────
CREATE TABLE `divorce_cases` (
    `id`                            BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `member_id`                     BIGINT UNSIGNED NOT NULL,
    `spouse_id`                     BIGINT UNSIGNED NOT NULL,
    `divorce_date`                  DATE NOT NULL,
    `divorce_case_type`             VARCHAR(50) NOT NULL,
    `request_date`                  DATE NOT NULL,
    `membership_acquisition_date`   DATE NULL,
    `years_of_membership`           INT UNSIGNED NULL,
    `has_children_on_membership`    TINYINT(1) NOT NULL DEFAULT 0,
    `fee_percentage`                DECIMAL(5,2) NULL,
    `fee_amount`                    DECIMAL(15,2) NULL,
    `spouse_new_member_id`          BIGINT UNSIGNED NULL,
    `spouse_new_membership_number`  VARCHAR(20) NULL,
    `children_assignment_json`      JSON NULL,
    `archive_snapshot_id`           BIGINT UNSIGNED NULL,
    `workflow_instance_id`          BIGINT UNSIGNED NULL,
    `status`                        VARCHAR(50) NOT NULL DEFAULT 'submitted',
    `notes`                         TEXT NULL,
    `created_at`                    TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`                    TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`                    BIGINT UNSIGNED NULL,
    `updated_by`                    BIGINT UNSIGNED NULL,
    INDEX `idx_divorce_member` (`member_id`),
    INDEX `idx_divorce_spouse` (`spouse_id`),
    INDEX `idx_divorce_status` (`status`),
    INDEX `idx_divorce_date` (`divorce_date`),
    CONSTRAINT `fk_divorce_member` FOREIGN KEY (`member_id`) REFERENCES `members`(`id`),
    CONSTRAINT `fk_divorce_spouse` FOREIGN KEY (`spouse_id`) REFERENCES `spouses`(`id`),
    CONSTRAINT `fk_divorce_new_member` FOREIGN KEY (`spouse_new_member_id`) REFERENCES `members`(`id`) ON DELETE SET NULL,
    CONSTRAINT `fk_divorce_snapshot` FOREIGN KEY (`archive_snapshot_id`) REFERENCES `archive_snapshots`(`id`) ON DELETE SET NULL,
    CONSTRAINT `fk_divorce_workflow` FOREIGN KEY (`workflow_instance_id`) REFERENCES `workflow_instances`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Death cases
-- ──────────────────────────────────────────────
CREATE TABLE `death_cases` (
    `id`                         BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `member_id`                  BIGINT UNSIGNED NOT NULL,
    `deceased_type`              VARCHAR(30) NOT NULL,
    `death_date`                 DATE NOT NULL,
    `death_certificate_number`   VARCHAR(100) NULL,
    `death_certificate_path`     VARCHAR(500) NULL,
    `spouse_id`                  BIGINT UNSIGNED NULL,
    `child_id`                   BIGINT UNSIGNED NULL,
    `transferred_to_member_id`   BIGINT UNSIGNED NULL,
    `same_membership_number`     TINYINT(1) NOT NULL DEFAULT 0,
    `fee_amount`                 DECIMAL(15,2) NULL,
    `archive_snapshot_id`        BIGINT UNSIGNED NULL,
    `workflow_instance_id`       BIGINT UNSIGNED NULL,
    `status`                     VARCHAR(50) NOT NULL DEFAULT 'recorded',
    `notes`                      TEXT NULL,
    `created_at`                 TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`                 TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`                 BIGINT UNSIGNED NULL,
    `updated_by`                 BIGINT UNSIGNED NULL,
    INDEX `idx_death_member` (`member_id`),
    INDEX `idx_death_status` (`status`),
    INDEX `idx_death_date` (`death_date`),
    CONSTRAINT `fk_death_member` FOREIGN KEY (`member_id`) REFERENCES `members`(`id`),
    CONSTRAINT `fk_death_spouse` FOREIGN KEY (`spouse_id`) REFERENCES `spouses`(`id`) ON DELETE SET NULL,
    CONSTRAINT `fk_death_child` FOREIGN KEY (`child_id`) REFERENCES `children`(`id`) ON DELETE SET NULL,
    CONSTRAINT `fk_death_transferred` FOREIGN KEY (`transferred_to_member_id`) REFERENCES `members`(`id`) ON DELETE SET NULL,
    CONSTRAINT `fk_death_snapshot` FOREIGN KEY (`archive_snapshot_id`) REFERENCES `archive_snapshots`(`id`) ON DELETE SET NULL,
    CONSTRAINT `fk_death_workflow` FOREIGN KEY (`workflow_instance_id`) REFERENCES `workflow_instances`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Waiver requests (membership transfer to others)
-- ──────────────────────────────────────────────
CREATE TABLE `waiver_requests` (
    `id`                         BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `source_member_id`           BIGINT UNSIGNED NOT NULL,
    `target_member_id`           BIGINT UNSIGNED NULL,
    `membership_number`          VARCHAR(20) NOT NULL,
    `membership_value_at_waiver` DECIMAL(15,2) NOT NULL,
    `waiver_fee_percentage`      DECIMAL(5,2) NOT NULL DEFAULT 30.00,
    `waiver_fee_amount`          DECIMAL(15,2) NOT NULL,
    `original_dependent_count`   INT UNSIGNED NOT NULL DEFAULT 0,
    `new_dependent_count`        INT UNSIGNED NULL,
    `board_approval_required`    TINYINT(1) NOT NULL DEFAULT 1,
    `board_decision_reference`   VARCHAR(100) NULL,
    `approved_by`                BIGINT UNSIGNED NULL,
    `approved_at`                TIMESTAMP NULL DEFAULT NULL,
    `annual_renewal_paid`        TINYINT(1) NOT NULL DEFAULT 0,
    `archive_snapshot_id`        BIGINT UNSIGNED NULL,
    `workflow_instance_id`       BIGINT UNSIGNED NULL,
    `status`                     VARCHAR(50) NOT NULL DEFAULT 'requested',
    `notes`                      TEXT NULL,
    `created_at`                 TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`                 TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`                 BIGINT UNSIGNED NULL,
    `updated_by`                 BIGINT UNSIGNED NULL,
    INDEX `idx_waiver_source` (`source_member_id`),
    INDEX `idx_waiver_target` (`target_member_id`),
    INDEX `idx_waiver_number` (`membership_number`),
    INDEX `idx_waiver_status` (`status`),
    CONSTRAINT `fk_waiver_source` FOREIGN KEY (`source_member_id`) REFERENCES `members`(`id`),
    CONSTRAINT `fk_waiver_target` FOREIGN KEY (`target_member_id`) REFERENCES `members`(`id`) ON DELETE SET NULL,
    CONSTRAINT `fk_waiver_snapshot` FOREIGN KEY (`archive_snapshot_id`) REFERENCES `archive_snapshots`(`id`) ON DELETE SET NULL,
    CONSTRAINT `fk_waiver_workflow` FOREIGN KEY (`workflow_instance_id`) REFERENCES `workflow_instances`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB;


-- ════════════════════════════════════════════════════════════════
-- PHASE 14: INTERVIEWS, CARNETS & DOCUMENT MANAGEMENT
-- ════════════════════════════════════════════════════════════════

-- ──────────────────────────────────────────────
-- Interviews (Board decisions)
-- ──────────────────────────────────────────────
CREATE TABLE `interviews` (
    `id`                       BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `member_id`                BIGINT UNSIGNED NOT NULL,
    `form_submission_id`       BIGINT UNSIGNED NULL,
    `scheduled_date`           DATE NOT NULL,
    `scheduled_time`           TIME NULL,
    `location`                 VARCHAR(200) NULL,
    `rescheduled_from`         DATE NULL,
    `reschedule_reason`        TEXT NULL,
    `reschedule_count`         INT UNSIGNED NOT NULL DEFAULT 0,
    `decision`                 VARCHAR(30) NOT NULL DEFAULT 'pending',
    `decision_notes`           TEXT NULL,
    `decision_date`            TIMESTAMP NULL DEFAULT NULL,
    `board_member_names`       TEXT NULL,
    `board_decision_reference` VARCHAR(100) NULL,
    `notification_sent`        TINYINT(1) NOT NULL DEFAULT 0,
    `notification_sent_at`     TIMESTAMP NULL DEFAULT NULL,
    `workflow_instance_id`     BIGINT UNSIGNED NULL,
    `status`                   VARCHAR(50) NOT NULL DEFAULT 'scheduled',
    `created_at`               TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`               TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`               BIGINT UNSIGNED NULL,
    `updated_by`               BIGINT UNSIGNED NULL,
    INDEX `idx_interviews_member` (`member_id`),
    INDEX `idx_interviews_date` (`scheduled_date`),
    INDEX `idx_interviews_decision` (`decision`),
    INDEX `idx_interviews_status` (`status`),
    CONSTRAINT `fk_interviews_member` FOREIGN KEY (`member_id`) REFERENCES `members`(`id`),
    CONSTRAINT `fk_interviews_form` FOREIGN KEY (`form_submission_id`) REFERENCES `form_submissions`(`id`) ON DELETE SET NULL,
    CONSTRAINT `fk_interviews_workflow` FOREIGN KEY (`workflow_instance_id`) REFERENCES `workflow_instances`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Carnets (membership cards)
-- ──────────────────────────────────────────────
CREATE TABLE `carnets` (
    `id`                  BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `member_id`           BIGINT UNSIGNED NOT NULL,
    `carnet_number`       VARCHAR(50) NOT NULL,
    `carnet_type`         VARCHAR(30) NOT NULL DEFAULT 'regular',
    `qr_code_data`        VARCHAR(500) NULL,
    `is_active`           TINYINT(1) NOT NULL DEFAULT 1,
    `issued_at`           TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `issued_by`           BIGINT UNSIGNED NULL,
    `deactivated_at`      TIMESTAMP NULL DEFAULT NULL,
    `deactivated_reason`  VARCHAR(200) NULL,
    `replacement_count`   INT UNSIGNED NOT NULL DEFAULT 0,
    `previous_carnet_id`  BIGINT UNSIGNED NULL,
    `print_count`         INT UNSIGNED NOT NULL DEFAULT 0,
    `last_printed_at`     TIMESTAMP NULL DEFAULT NULL,
    `last_printed_by`     BIGINT UNSIGNED NULL,
    `created_at`          TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`          TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`          BIGINT UNSIGNED NULL,
    `updated_by`          BIGINT UNSIGNED NULL,
    UNIQUE KEY `uq_carnets_number` (`carnet_number`),
    INDEX `idx_carnets_member` (`member_id`),
    INDEX `idx_carnets_active` (`is_active`),
    INDEX `idx_carnets_type` (`carnet_type`),
    CONSTRAINT `fk_carnets_member` FOREIGN KEY (`member_id`) REFERENCES `members`(`id`),
    CONSTRAINT `fk_carnets_previous` FOREIGN KEY (`previous_carnet_id`) REFERENCES `carnets`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Documents (uploaded files)
-- ──────────────────────────────────────────────
CREATE TABLE `documents` (
    `id`                   BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `member_id`            BIGINT UNSIGNED NOT NULL,
    `document_type`        VARCHAR(50) NOT NULL,
    `original_filename`    VARCHAR(500) NOT NULL,
    `stored_filename`      VARCHAR(500) NOT NULL,
    `file_path`            VARCHAR(1000) NOT NULL,
    `file_size`            INT UNSIGNED NOT NULL DEFAULT 0,
    `mime_type`            VARCHAR(100) NOT NULL,
    `related_entity_type`  VARCHAR(100) NULL,
    `related_entity_id`    BIGINT UNSIGNED NULL,
    `description`          TEXT NULL,
    `uploaded_by`          BIGINT UNSIGNED NULL,
    `uploaded_at`          TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `is_archived`          TINYINT(1) NOT NULL DEFAULT 0,
    `archived_at`          TIMESTAMP NULL DEFAULT NULL,
    `archived_by`          BIGINT UNSIGNED NULL,
    `created_at`           TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`           TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    INDEX `idx_documents_member` (`member_id`),
    INDEX `idx_documents_type` (`document_type`),
    INDEX `idx_documents_related` (`related_entity_type`, `related_entity_id`),
    INDEX `idx_documents_archived` (`is_archived`),
    CONSTRAINT `fk_documents_member` FOREIGN KEY (`member_id`) REFERENCES `members`(`id`)
) ENGINE=InnoDB;


-- ════════════════════════════════════════════════════════════════
-- PHASE 15: NOTIFICATIONS, REPORTS, DASHBOARD & BACKGROUND JOBS
-- ════════════════════════════════════════════════════════════════

-- ──────────────────────────────────────────────
-- SMS templates
-- ──────────────────────────────────────────────
CREATE TABLE `sms_templates` (
    `id`                   BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `template_code`        VARCHAR(50) NOT NULL,
    `name_ar`              VARCHAR(200) NOT NULL,
    `name_en`              VARCHAR(200) NULL,
    `message_template_ar`  TEXT NOT NULL,
    `message_template_en`  TEXT NULL,
    `variables_json`       JSON NULL,
    `trigger_event`        VARCHAR(100) NULL,
    `is_active`            TINYINT(1) NOT NULL DEFAULT 1,
    `created_at`           TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`           TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`           BIGINT UNSIGNED NULL,
    `updated_by`           BIGINT UNSIGNED NULL,
    UNIQUE KEY `uq_sms_templates_code` (`template_code`),
    INDEX `idx_sms_templates_trigger` (`trigger_event`)
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- SMS send log — IMMUTABLE
-- ──────────────────────────────────────────────
CREATE TABLE `sms_log` (
    `id`                   BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `member_id`            BIGINT UNSIGNED NULL,
    `phone_number`         VARCHAR(20) NOT NULL,
    `template_id`          BIGINT UNSIGNED NULL,
    `message_text`         TEXT NOT NULL,
    `message_type`         VARCHAR(20) NOT NULL DEFAULT 'single',
    `status`               VARCHAR(30) NOT NULL DEFAULT 'queued',
    `provider_message_id`  VARCHAR(200) NULL,
    `provider_response`    TEXT NULL,
    `cost`                 DECIMAL(10,4) NULL,
    `retry_count`          INT UNSIGNED NOT NULL DEFAULT 0,
    `max_retries`          INT UNSIGNED NOT NULL DEFAULT 3,
    `sent_at`              TIMESTAMP NULL DEFAULT NULL,
    `delivered_at`         TIMESTAMP NULL DEFAULT NULL,
    `failed_at`            TIMESTAMP NULL DEFAULT NULL,
    `failure_reason`       TEXT NULL,
    `sent_by`              BIGINT UNSIGNED NULL,
    `created_at`           TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    INDEX `idx_sms_log_member` (`member_id`),
    INDEX `idx_sms_log_phone` (`phone_number`),
    INDEX `idx_sms_log_status` (`status`),
    INDEX `idx_sms_log_date` (`created_at`),
    INDEX `idx_sms_log_template` (`template_id`),
    CONSTRAINT `fk_sms_log_member` FOREIGN KEY (`member_id`) REFERENCES `members`(`id`) ON DELETE SET NULL,
    CONSTRAINT `fk_sms_log_template` FOREIGN KEY (`template_id`) REFERENCES `sms_templates`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Notification queue (multi-channel)
-- ──────────────────────────────────────────────
CREATE TABLE `notification_queue` (
    `id`              BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `type`            VARCHAR(20) NOT NULL DEFAULT 'sms',
    `recipient_type`  VARCHAR(20) NOT NULL DEFAULT 'member',
    `recipient_id`    BIGINT UNSIGNED NOT NULL,
    `template_id`     BIGINT UNSIGNED NULL,
    `subject`         VARCHAR(500) NULL,
    `message`         TEXT NOT NULL,
    `data_json`       JSON NULL,
    `priority`        INT NOT NULL DEFAULT 0,
    `status`          VARCHAR(30) NOT NULL DEFAULT 'pending',
    `attempts`        INT UNSIGNED NOT NULL DEFAULT 0,
    `max_attempts`    INT UNSIGNED NOT NULL DEFAULT 3,
    `scheduled_at`    TIMESTAMP NULL DEFAULT NULL,
    `processed_at`    TIMESTAMP NULL DEFAULT NULL,
    `created_at`      TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    INDEX `idx_notif_queue_status` (`status`),
    INDEX `idx_notif_queue_type` (`type`),
    INDEX `idx_notif_queue_recipient` (`recipient_type`, `recipient_id`),
    INDEX `idx_notif_queue_scheduled` (`scheduled_at`),
    INDEX `idx_notif_queue_priority` (`priority`)
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Report definitions (predefined + custom)
-- ──────────────────────────────────────────────
CREATE TABLE `report_definitions` (
    `id`                     BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `report_code`            VARCHAR(50) NOT NULL,
    `name_ar`                VARCHAR(200) NOT NULL,
    `name_en`                VARCHAR(200) NULL,
    `description_ar`         TEXT NULL,
    `category`               VARCHAR(50) NOT NULL DEFAULT 'general',
    `query_definition_json`  JSON NULL,
    `column_definitions_json` JSON NULL,
    `default_filters_json`   JSON NULL,
    `required_permission`    VARCHAR(100) NULL,
    `is_system`              TINYINT(1) NOT NULL DEFAULT 1,
    `is_active`              TINYINT(1) NOT NULL DEFAULT 1,
    `created_at`             TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`             TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`             BIGINT UNSIGNED NULL,
    `updated_by`             BIGINT UNSIGNED NULL,
    UNIQUE KEY `uq_report_defs_code` (`report_code`),
    INDEX `idx_report_defs_category` (`category`),
    INDEX `idx_report_defs_active` (`is_active`)
) ENGINE=InnoDB;

-- ──────────────────────────────────────────────
-- Scheduled reports
-- ──────────────────────────────────────────────
CREATE TABLE `scheduled_reports` (
    `id`                   BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `report_definition_id` BIGINT UNSIGNED NOT NULL,
    `name_ar`              VARCHAR(200) NOT NULL,
    `schedule_type`        VARCHAR(30) NOT NULL DEFAULT 'monthly',
    `schedule_config_json` JSON NULL,
    `filters_json`         JSON NULL,
    `format`               VARCHAR(20) NOT NULL DEFAULT 'pdf',
    `last_generated_at`    TIMESTAMP NULL DEFAULT NULL,
    `next_run_at`          TIMESTAMP NULL DEFAULT NULL,
    `is_active`            TINYINT(1) NOT NULL DEFAULT 1,
    `created_at`           TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at`           TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `created_by`           BIGINT UNSIGNED NULL,
    `updated_by`           BIGINT UNSIGNED NULL,
    INDEX `idx_sched_reports_def` (`report_definition_id`),
    INDEX `idx_sched_reports_next` (`next_run_at`),
    INDEX `idx_sched_reports_active` (`is_active`),
    CONSTRAINT `fk_sched_reports_def` FOREIGN KEY (`report_definition_id`) REFERENCES `report_definitions`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB;


-- ════════════════════════════════════════════════════════════════
-- BACKFILL: form_submissions.member_id FK
-- (members table created after form_submissions)
-- ════════════════════════════════════════════════════════════════

ALTER TABLE `form_submissions`
    ADD CONSTRAINT `fk_form_submissions_member` FOREIGN KEY (`member_id`) REFERENCES `members`(`id`) ON DELETE SET NULL;


-- ════════════════════════════════════════════════════════════════
-- RE-ENABLE CHECKS
-- ════════════════════════════════════════════════════════════════

SET FOREIGN_KEY_CHECKS = 1;


-- ════════════════════════════════════════════════════════════════
-- VERIFICATION: Table count
-- Should output 59 tables
-- ════════════════════════════════════════════════════════════════
-- SELECT COUNT(*) AS total_tables FROM information_schema.tables
-- WHERE table_schema = 'the_club_erp' AND table_type = 'BASE TABLE';