<?php
// ============================================================
//  MediCore — Customer Web Ordering Portal (shared schema + helpers)
//  File: includes/customer_portal.php
//  Require this from includes/header.php (staff side, for the
//  Online Orders approval queue + nav badge) and from every
//  api/customer-*.php / shop/*.php file (public side).
//
//  Design notes:
//  - Phone/OTP auth fields are bolted onto the existing `customers`
//    table (same pattern as ensure_soft_delete()) rather than a new
//    table, so a portal account and a walk-in customer record are
//    literally the same row — a phone number that already exists
//    from an in-store sale just "claims" itself via OTP instead of
//    creating a duplicate customer.
//  - online_orders / online_order_items are new tables: a portal
//    order does NOT touch stock or create a real `sales` row until
//    staff approves it from sale/online-orders.php (see
//    api/online-orders.php's api_approve()) — mirrors the existing
//    PO Approval workflow pattern in includes/po_approval.php.
//  - No real SMS gateway is wired up yet (Settings has no gateway
//    credentials to plug in). request_otp() in api/customer-auth.php
//    returns the OTP directly in the JSON response so the portal can
//    display it on-screen — swap that for a real gateway call later
//    without touching anything else.
// ============================================================

// ── Auto-migration: OTP/portal columns on customers ─────────────
function ensure_customer_portal_columns(): void {
    static $done = false;
    if ($done) return;
    $done = true;

    try {
        $hasCol = db_val(
            "SELECT COUNT(*) FROM information_schema.COLUMNS
              WHERE TABLE_SCHEMA = DATABASE()
                AND TABLE_NAME   = 'customers'
                AND COLUMN_NAME  = 'portal_verified'"
        );
        if (!$hasCol) {
            db_run("ALTER TABLE customers
                ADD COLUMN portal_verified   TINYINT(1)   DEFAULT 0,
                ADD COLUMN otp_code          VARCHAR(10)  DEFAULT NULL,
                ADD COLUMN otp_expires_at    DATETIME     DEFAULT NULL,
                ADD COLUMN otp_attempts      TINYINT UNSIGNED DEFAULT 0,
                ADD COLUMN portal_last_login DATETIME     DEFAULT NULL");
            db_run("ALTER TABLE customers ADD INDEX idx_customers_phone (phone)");
        }

        // Optional password login + profile picture — bolted on
        // separately so an existing install upgrades cleanly even if
        // it already has the columns above from an earlier deploy.
        $hasPass = db_val(
            "SELECT COUNT(*) FROM information_schema.COLUMNS
              WHERE TABLE_SCHEMA = DATABASE()
                AND TABLE_NAME   = 'customers'
                AND COLUMN_NAME  = 'password_hash'"
        );
        if (!$hasPass) {
            db_run("ALTER TABLE customers
                ADD COLUMN password_hash VARCHAR(255) DEFAULT NULL,
                ADD COLUMN profile_pic   LONGTEXT     DEFAULT NULL");
        }

        // Optional email — lets the Email notification gateway reach a
        // customer for order confirmations / OTP codes. Blank by default;
        // no staff-side field exists for it either, it's portal-only.
        $hasEmail = db_val(
            "SELECT COUNT(*) FROM information_schema.COLUMNS
              WHERE TABLE_SCHEMA = DATABASE()
                AND TABLE_NAME   = 'customers'
                AND COLUMN_NAME  = 'email'"
        );
        if (!$hasEmail) {
            db_run("ALTER TABLE customers ADD COLUMN email VARCHAR(150) DEFAULT NULL");
        }
    } catch (Throwable $e) {
        error_log('ensure_customer_portal_columns failed: ' . $e->getMessage());
    }
}

// ── Auto-migration: online order tables ──────────────────────────
function ensure_online_order_tables(): void {
    static $done = false;
    if ($done) return;
    $done = true;

    try {
        db_run("CREATE TABLE IF NOT EXISTS online_orders (
            id                INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
            order_no          VARCHAR(30)   NOT NULL UNIQUE,
            customer_id       INT UNSIGNED  NOT NULL,
            customer_name     VARCHAR(100)  DEFAULT '',
            customer_phone    VARCHAR(30)   DEFAULT '',
            delivery_address  TEXT,
            sub_total         DECIMAL(12,2) DEFAULT 0.00,
            total             DECIMAL(12,2) DEFAULT 0.00,
            status            ENUM('pending','approved','rejected','cancelled') DEFAULT 'pending',
            notes             VARCHAR(500)  DEFAULT '',
            rejection_reason  VARCHAR(500)  DEFAULT '',
            reviewed_by       INT UNSIGNED  DEFAULT NULL,
            reviewed_at       DATETIME      DEFAULT NULL,
            converted_sale_id INT UNSIGNED  DEFAULT NULL,
            created_at        TIMESTAMP     DEFAULT CURRENT_TIMESTAMP,
            INDEX idx_oo_customer (customer_id),
            INDEX idx_oo_status   (status)
        ) ENGINE=InnoDB");

        db_run("CREATE TABLE IF NOT EXISTS online_order_items (
            id               INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
            online_order_id  INT UNSIGNED NOT NULL,
            product_id       INT UNSIGNED DEFAULT NULL,
            product_name     VARCHAR(150) DEFAULT '',
            form             VARCHAR(30)  DEFAULT '',
            qty              INT UNSIGNED DEFAULT 1,
            price            DECIMAL(10,2) DEFAULT 0.00,
            cost             DECIMAL(10,2) DEFAULT 0.00,
            total            DECIMAL(12,2) DEFAULT 0.00,
            INDEX idx_ooi_order (online_order_id)
        ) ENGINE=InnoDB");
    } catch (Throwable $e) {
        error_log('ensure_online_order_tables failed: ' . $e->getMessage());
    }
}

function ensure_customer_portal_schema(): void {
    ensure_customer_portal_columns();
    ensure_online_order_tables();
}

// ── Settings readers ──────────────────────────────────────────
function portal_enabled(): bool {
    $cfg = get_settings();
    return ($cfg['portal_enabled'] ?? '0') === '1';
}

function portal_shop_name(): string {
    $cfg = get_settings();
    return $cfg['portal_shop_name'] ?: $cfg['shop_name'];
}

function portal_welcome_text(): string {
    $cfg = get_settings();
    return $cfg['portal_welcome_text']
        ?: 'Order your medicines online — browse products and place an order for pickup.';
}

function portal_min_order(): float {
    $cfg = get_settings();
    return (float) ($cfg['portal_min_order'] ?? 0);
}

// ── OTP helpers ────────────────────────────────────────────────
function generate_otp(): string {
    return str_pad((string) random_int(0, 999999), 6, '0', STR_PAD_LEFT);
}

// Who on the staff side can approve/reject online orders — same
// roles as PO approval, since this is the equivalent "commit to
// stock" gate for the customer-ordering flow.
function can_approve_online_order(): bool {
    return is_admin() || current_user_role() === 'manager';
}
