<?php
require_once __DIR__ . '/functions.php';

function mj_csv_headers(array $row): array {
    $out = [];
    foreach ($row as $i => $h) {
        $key = strtolower(trim((string)$h));
        $key = preg_replace('/[^a-z0-9]+/', '_', $key);
        $key = trim((string)$key, '_');
        if ($key === '') { $key = 'col_'.$i; }
        $out[$i] = $key;
    }
    return $out;
}

function mj_read_csv_assoc(string $path, int $maxRows = 0): array {
    $handle = fopen($path, 'rb');
    if (!$handle) { throw new RuntimeException('Unable to open CSV file.'); }
    $first = fgets($handle, 4);
    if ($first !== "\xEF\xBB\xBF") { rewind($handle); }
    $header = fgetcsv($handle);
    if (!$header) { fclose($handle); throw new RuntimeException('CSV header row is missing.'); }
    $keys = mj_csv_headers($header);
    $rows = [];
    $n = 0;
    while (($data = fgetcsv($handle)) !== false) {
        $n++;
        if ($maxRows > 0 && $n > $maxRows) { break; }
        $assoc = [];
        foreach ($keys as $i => $key) {
            $assoc[$key] = isset($data[$i]) ? trim((string)$data[$i]) : '';
        }
        $nonEmpty = array_filter($assoc, static fn($v) => trim((string)$v) !== '');
        if ($nonEmpty) { $rows[] = $assoc; }
    }
    fclose($handle);
    return $rows;
}

function mj_val(array $row, array $keys, string $default = ''): string {
    foreach ($keys as $k) {
        $nk = strtolower(trim($k));
        $nk = preg_replace('/[^a-z0-9]+/', '_', $nk);
        $nk = trim((string)$nk, '_');
        if (isset($row[$nk]) && trim((string)$row[$nk]) !== '') { return trim((string)$row[$nk]); }
    }
    return $default;
}

function mj_country_id_by_any(string $value, string $fallbackIso = 'SG'): int {
    $value = trim($value);
    $row = null;
    if ($value !== '') {
        $row = one('SELECT id FROM mj_countries WHERE iso2=? OR slug=? OR name=? LIMIT 1', [strtoupper($value), slugify($value), $value]);
    }
    if (!$row) { $row = one('SELECT id FROM mj_countries WHERE iso2=? LIMIT 1', [strtoupper($fallbackIso)]); }
    if (!$row) { $row = one('SELECT id FROM mj_countries ORDER BY is_active DESC, id ASC LIMIT 1'); }
    return (int)($row['id'] ?? 0);
}

function mj_country_by_id(int $id): array {
    return one('SELECT * FROM mj_countries WHERE id=? LIMIT 1', [$id]) ?: [];
}

function mj_state_id_by_name(int $countryId, string $name, string $timezone = ''): ?int {
    $name = trim($name);
    if ($name === '') { return null; }
    $slug = slugify($name);
    $row = one('SELECT id FROM mj_states WHERE country_id=? AND slug=? LIMIT 1', [$countryId, $slug]);
    if ($row) { return (int)$row['id']; }
    q('INSERT INTO mj_states(country_id,name,slug,timezone,is_active) VALUES(?,?,?,?,1)', [$countryId, $name, $slug, $timezone ?: null]);
    return (int)db()->lastInsertId();
}

function mj_city_id_by_name(int $countryId, ?int $stateId, string $name, string $timezone = ''): ?int {
    $name = trim($name);
    if ($name === '') { return null; }
    $slug = slugify($name);
    $row = one('SELECT id FROM mj_cities WHERE country_id=? AND slug=? AND (state_id <=> ?) LIMIT 1', [$countryId, $slug, $stateId]);
    if ($row) { return (int)$row['id']; }
    q('INSERT INTO mj_cities(country_id,state_id,name,slug,timezone,is_active) VALUES(?,?,?,?,?,1)', [$countryId, $stateId, $name, $slug, $timezone ?: null]);
    return (int)db()->lastInsertId();
}

function mj_category_id_by_name(string $name, string $type = 'marketplace'): ?int {
    $name = trim($name);
    if ($name === '') { return null; }
    $slug = slugify($name);
    $row = one('SELECT id FROM mj_categories WHERE type=? AND slug=? LIMIT 1', [$type, $slug]);
    if ($row) { return (int)$row['id']; }
    q('INSERT INTO mj_categories(type,name,slug,is_active,sort_order) VALUES(?,?,?,1,99)', [$type, $name, $slug]);
    return (int)db()->lastInsertId();
}

function mj_user_id_by_email(string $email, string $name = '', int $countryId = 0, string $timezone = 'UTC'): int {
    $email = trim(strtolower($email));
    if ($email === '') { $email = 'imported_' . bin2hex(random_bytes(5)) . '@example.local'; }
    $row = one('SELECT id FROM mj_users WHERE email=? LIMIT 1', [$email]);
    if ($row) { return (int)$row['id']; }
    $name = trim($name) ?: explode('@', $email)[0];
    $hash = password_hash('ChangeMe123!', PASSWORD_DEFAULT);
    q('INSERT INTO mj_users(name,email,password_hash,country_id,timezone,preferred_currency,is_email_verified,is_active,created_at) VALUES(?,?,?,?,?,?,1,1,NOW())', [
        $name, $email, $hash, $countryId ?: null, $timezone ?: 'UTC', (mj_country_by_id($countryId)['currency_code'] ?? 'USD')
    ]);
    return (int)db()->lastInsertId();
}

function mj_import_users(array $rows): array {
    $ok = 0; $bad = 0; $errors = [];
    foreach ($rows as $i => $r) {
        try {
            $countryId = mj_country_id_by_any(mj_val($r, ['country','country_code','iso2'], 'SG'));
            $country = mj_country_by_id($countryId);
            $tz = mj_val($r, ['timezone'], $country['timezone_default'] ?? 'UTC');
            $stateId = mj_state_id_by_name($countryId, mj_val($r, ['state','province','region']), $tz);
            $cityId = mj_city_id_by_name($countryId, $stateId, mj_val($r, ['city']), $tz);
            $email = strtolower(mj_val($r, ['email']));
            if ($email === '') { throw new RuntimeException('email required'); }
            $existing = one('SELECT id FROM mj_users WHERE email=? LIMIT 1', [$email]);
            $name = mj_val($r, ['name','full_name','contact_name'], explode('@', $email)[0]);
            $mobile = mj_val($r, ['mobile','phone','contact_number']);
            $currency = mj_val($r, ['preferred_currency','currency'], $country['currency_code'] ?? 'USD');
            if ($existing) {
                q('UPDATE mj_users SET name=?, mobile=?, country_id=?, state_id=?, city_id=?, timezone=?, preferred_currency=?, is_active=1 WHERE id=?', [$name,$mobile,$countryId,$stateId,$cityId,$tz,$currency,(int)$existing['id']]);
            } else {
                $password = mj_val($r, ['password'], 'ChangeMe123!');
                q('INSERT INTO mj_users(name,email,mobile,password_hash,country_id,state_id,city_id,timezone,preferred_currency,is_email_verified,is_active,created_at) VALUES(?,?,?,?,?,?,?,?,?,1,1,NOW())', [$name,$email,$mobile,password_hash($password,PASSWORD_DEFAULT),$countryId,$stateId,$cityId,$tz,$currency]);
            }
            $ok++;
        } catch (Throwable $e) { $bad++; if(count($errors)<10) $errors[]='Row '.($i+2).': '.$e->getMessage(); }
    }
    return ['ok'=>$ok,'bad'=>$bad,'errors'=>$errors];
}

function mj_import_categories(array $rows): array {
    $ok = 0; $bad = 0; $errors = [];
    foreach ($rows as $i => $r) {
        try {
            $type = mj_val($r, ['type'], 'marketplace');
            $name = mj_val($r, ['name','category']);
            if ($name === '') { throw new RuntimeException('category name required'); }
            $slug = mj_val($r, ['slug'], slugify($name));
            $parentId = null;
            $parent = mj_val($r, ['parent','parent_name']);
            if ($parent !== '') { $parentId = mj_category_id_by_name($parent, $type); }
            q('INSERT INTO mj_categories(parent_id,type,name,slug,icon,requires_approval,is_active,sort_order) VALUES(?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE name=VALUES(name), icon=VALUES(icon), parent_id=VALUES(parent_id), is_active=VALUES(is_active), sort_order=VALUES(sort_order)', [
                $parentId,$type,$name,$slug,mj_val($r,['icon']),(int)mj_val($r,['requires_approval'],'0'),(int)mj_val($r,['is_active','active'],'1'),(int)mj_val($r,['sort_order'],'99')
            ]);
            $ok++;
        } catch (Throwable $e) { $bad++; if(count($errors)<10) $errors[]='Row '.($i+2).': '.$e->getMessage(); }
    }
    return ['ok'=>$ok,'bad'=>$bad,'errors'=>$errors];
}

function mj_import_listings(array $rows): array {
    $ok = 0; $bad = 0; $errors = [];
    foreach ($rows as $i => $r) {
        try {
            $title = mj_val($r, ['title','listing_title','name']);
            if ($title === '') { throw new RuntimeException('title required'); }
            $countryId = mj_country_id_by_any(mj_val($r, ['country','country_code','iso2'], 'SG'));
            $country = mj_country_by_id($countryId);
            $tz = mj_val($r, ['timezone'], $country['timezone_default'] ?? 'UTC');
            $stateId = mj_state_id_by_name($countryId, mj_val($r, ['state','province','region']), $tz);
            $cityId = mj_city_id_by_name($countryId, $stateId, mj_val($r, ['city']), $tz);
            $catId = mj_category_id_by_name(mj_val($r, ['category','category_name'], 'Others'), 'marketplace');
            $userId = mj_user_id_by_email(mj_val($r, ['seller_email','email','owner_email'], ''), mj_val($r, ['seller_name','owner_name','contact_name'], 'Imported Seller'), $countryId, $tz);
            $status = mj_val($r, ['status'], 'active');
            if (!in_array($status, ['draft','pending','active','reserved','sold','expired','rejected'], true)) { $status = 'active'; }
            $slug = slugify($title) . '-' . substr(bin2hex(random_bytes(3)), 0, 6);
            q('INSERT INTO mj_listings(user_id,category_id,country_id,state_id,city_id,timezone,listing_type,title,slug,description,price,currency_code,condition_label,brand,model,status,is_featured,is_urgent,quality_score,published_at,custom_fields_json,created_at) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,NOW())', [
                $userId,$catId,$countryId,$stateId,$cityId,$tz,mj_val($r,['listing_type','type'],'product'),$title,$slug,mj_val($r,['description','details','services']),
                (float)mj_val($r,['price'],'0'),mj_val($r,['currency','currency_code'],$country['currency_code'] ?? 'USD'),mj_val($r,['condition','condition_label']),mj_val($r,['brand']),mj_val($r,['model']),$status,
                (int)mj_val($r,['is_featured','featured'],'0'),(int)mj_val($r,['is_urgent','urgent'],'0'),85,$status==='active'?date('Y-m-d H:i:s'):null,
                json_encode(['source'=>mj_val($r,['source'],'csv_import'), 'source_url'=>mj_val($r,['source_url','url'])])
            ]);
            $listingId = (int)db()->lastInsertId();
            $images = preg_split('/[|,]+/', mj_val($r, ['image_urls','images','photo_urls']), -1, PREG_SPLIT_NO_EMPTY);
            foreach ($images as $idx => $img) {
                $img = trim($img);
                if ($img !== '') { q('INSERT INTO mj_listing_images(listing_id,image_path,sort_order) VALUES(?,?,?)', [$listingId,$img,$idx]); }
            }
            $ok++;
        } catch (Throwable $e) { $bad++; if(count($errors)<10) $errors[]='Row '.($i+2).': '.$e->getMessage(); }
    }
    return ['ok'=>$ok,'bad'=>$bad,'errors'=>$errors];
}

function mj_import_companies(array $rows): array {
    $ok = 0; $bad = 0; $errors = [];
    foreach ($rows as $i => $r) {
        try {
            $name = mj_val($r, ['company_name','name','business_name','entity_name']);
            if ($name === '') { throw new RuntimeException('company name required'); }
            $countryId = mj_country_id_by_any(mj_val($r, ['country','country_code','iso2'], 'SG'));
            $country = mj_country_by_id($countryId);
            $tz = mj_val($r, ['timezone'], $country['timezone_default'] ?? 'UTC');
            $stateId = mj_state_id_by_name($countryId, mj_val($r, ['state','province','region']), $tz);
            $cityId = mj_city_id_by_name($countryId, $stateId, mj_val($r, ['city']), $tz);
            $catId = mj_category_id_by_name(mj_val($r, ['category','category_name'], 'Other Businesses'), 'company');
            $userId = mj_user_id_by_email(mj_val($r, ['owner_email','email'], ''), mj_val($r, ['owner_name','contact_name'], $name.' Owner'), $countryId, $tz);
            $status = mj_val($r, ['status'], 'active');
            if (!in_array($status, ['draft','pending','active','rejected','suspended'], true)) { $status = 'active'; }
            $slug = slugify($name) . '-' . substr(bin2hex(random_bytes(3)), 0, 6);
            q('INSERT INTO mj_companies(user_id,category_id,country_id,state_id,city_id,timezone,name,slug,registration_no,logo,cover_image,description,phone,whatsapp,email,website,address,latitude,longitude,status,is_verified,is_featured,created_at) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,NOW())', [
                $userId,$catId,$countryId,$stateId,$cityId,$tz,$name,$slug,mj_val($r,['uen','registration_no','business_registration_no']),mj_val($r,['logo','logo_url']),mj_val($r,['cover_image','cover_url']),mj_val($r,['description','about','services']),
                mj_val($r,['phone','telephone','contact_number']),mj_val($r,['whatsapp','whatsapp_number']),mj_val($r,['company_email','business_email','email']),mj_val($r,['website','url']),mj_val($r,['address','premises_address','registered_address']),
                mj_val($r,['latitude','lat']) ?: null, mj_val($r,['longitude','lng','lon']) ?: null, $status,(int)mj_val($r,['is_verified','verified'],'0'),(int)mj_val($r,['is_featured','featured'],'0')
            ]);
            $companyId = (int)db()->lastInsertId();
            q('INSERT INTO mj_company_branches(company_id,country_id,state_id,city_id,name,timezone,phone,whatsapp,email,address,opening_hours_json,is_main,is_active) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,1)', [
                $companyId,$countryId,$stateId,$cityId,mj_val($r,['branch_name'],'Main Branch'),$tz,mj_val($r,['phone','telephone','contact_number']),mj_val($r,['whatsapp','whatsapp_number']),mj_val($r,['company_email','business_email','email']),mj_val($r,['address','premises_address','registered_address']),mj_val($r,['opening_hours_json'],'{}'),1
            ]);
            $services = preg_split('/[|;]+/', mj_val($r, ['services','service_names']), -1, PREG_SPLIT_NO_EMPTY);
            foreach ($services as $svc) {
                $svc = trim($svc);
                if ($svc !== '') { q('INSERT INTO mj_company_services(company_id,name,description,is_bookable) VALUES(?,?,?,0)', [$companyId,$svc,$svc]); }
            }
            $ok++;
        } catch (Throwable $e) { $bad++; if(count($errors)<10) $errors[]='Row '.($i+2).': '.$e->getMessage(); }
    }
    return ['ok'=>$ok,'bad'=>$bad,'errors'=>$errors];
}

function mj_import_company_services(array $rows): array {
    $ok = 0; $bad = 0; $errors = [];
    foreach ($rows as $i => $r) {
        try {
            $companyName = mj_val($r, ['company_name','company']);
            $serviceName = mj_val($r, ['service_name','name','service']);
            if ($companyName === '' || $serviceName === '') { throw new RuntimeException('company_name and service_name required'); }
            $company = one('SELECT id FROM mj_companies WHERE name=? ORDER BY id DESC LIMIT 1', [$companyName]);
            if (!$company) { throw new RuntimeException('company not found: '.$companyName); }
            q('INSERT INTO mj_company_services(company_id,name,price_from,duration_minutes,description,is_bookable) VALUES(?,?,?,?,?,?)', [(int)$company['id'],$serviceName,(float)mj_val($r,['price_from'],'0'),(int)mj_val($r,['duration_minutes'],'0'),mj_val($r,['description']), (int)mj_val($r,['is_bookable','bookable'],'0')]);
            $ok++;
        } catch (Throwable $e) { $bad++; if(count($errors)<10) $errors[]='Row '.($i+2).': '.$e->getMessage(); }
    }
    return ['ok'=>$ok,'bad'=>$bad,'errors'=>$errors];
}

function mj_import_company_seed(array $rows): array {
    $ok = 0; $bad = 0; $errors = [];
    foreach ($rows as $i => $r) {
        try {
            $name = mj_val($r, ['company_name','name','business_name','entity_name','licensee_name']);
            if ($name === '') { throw new RuntimeException('company/entity name required'); }
            $countryId = mj_country_id_by_any(mj_val($r, ['country','country_code','iso2'], 'SG'));
            $country = mj_country_by_id($countryId);
            $tz = mj_val($r, ['timezone'], $country['timezone_default'] ?? 'UTC');
            $stateId = mj_state_id_by_name($countryId, mj_val($r, ['state','province','region']), $tz);
            $cityId = mj_city_id_by_name($countryId, $stateId, mj_val($r, ['city']), $tz);
            q('INSERT INTO mj_company_seed(country_id,state_id,city_id,source,source_ref,uen,entity_name,entity_type,entity_status,registration_date,primary_activity,secondary_activity,address_text,postal_code,phone,email,website,services,category_text,latitude,longitude,timezone,is_claimed,raw_json,created_at) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,0,?,NOW()) ON DUPLICATE KEY UPDATE entity_name=VALUES(entity_name), entity_status=VALUES(entity_status), address_text=VALUES(address_text), phone=VALUES(phone), email=VALUES(email), website=VALUES(website), services=VALUES(services), raw_json=VALUES(raw_json)', [
                $countryId,$stateId,$cityId,mj_val($r,['source'],'csv'),mj_val($r,['source_ref','licence_number','place_id']),mj_val($r,['uen','registration_no','business_registration_no']),$name,mj_val($r,['entity_type','business_type','licence_type']),mj_val($r,['entity_status','status']),mj_val($r,['registration_date','licence_start_date']),mj_val($r,['primary_activity','primary_ssic_description']),mj_val($r,['secondary_activity','secondary_ssic_description']),mj_val($r,['address','premises_address','registered_address']),mj_val($r,['postal_code','postcode']),mj_val($r,['phone','telephone','contact_number']),mj_val($r,['email','company_email']),mj_val($r,['website','url']),mj_val($r,['services','description']),mj_val($r,['category','category_text']),mj_val($r,['latitude','lat']) ?: null,mj_val($r,['longitude','lng','lon']) ?: null,$tz,json_encode($r, JSON_UNESCAPED_UNICODE)
            ]);
            $ok++;
        } catch (Throwable $e) { $bad++; if(count($errors)<10) $errors[]='Row '.($i+2).': '.$e->getMessage(); }
    }
    return ['ok'=>$ok,'bad'=>$bad,'errors'=>$errors];
}


function mj_sample_data_schema_repair(): void {
    $sqls = [
        "CREATE TABLE IF NOT EXISTS mj_subscriptions (id BIGINT AUTO_INCREMENT PRIMARY KEY, user_id BIGINT NULL, company_id BIGINT NULL, plan_name VARCHAR(120) NULL, status VARCHAR(40) DEFAULT 'active', starts_at DATETIME NULL, ends_at DATETIME NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4",
        "ALTER TABLE mj_companies ADD COLUMN IF NOT EXISTS approved_at DATETIME NULL",
        "ALTER TABLE mj_companies ADD COLUMN IF NOT EXISTS approved_by BIGINT NULL",
        "ALTER TABLE mj_companies ADD COLUMN IF NOT EXISTS submitted_at DATETIME NULL",
        "ALTER TABLE mj_companies ADD COLUMN IF NOT EXISTS admin_note TEXT NULL",
        "ALTER TABLE mj_companies ADD COLUMN IF NOT EXISTS rejection_reason TEXT NULL",
        "ALTER TABLE mj_companies ADD COLUMN IF NOT EXISTS is_sponsored TINYINT(1) NOT NULL DEFAULT 0",
        "ALTER TABLE mj_companies ADD COLUMN IF NOT EXISTS sponsored_until DATETIME NULL",
        "ALTER TABLE mj_deals ADD COLUMN IF NOT EXISTS approved_at DATETIME NULL",
        "ALTER TABLE mj_deals ADD COLUMN IF NOT EXISTS approved_by BIGINT NULL",
        "ALTER TABLE mj_deals ADD COLUMN IF NOT EXISTS featured_until DATETIME NULL",
        "ALTER TABLE mj_deals ADD COLUMN IF NOT EXISTS sponsored_until DATETIME NULL",
        "ALTER TABLE mj_deals ADD COLUMN IF NOT EXISTS enquiry_count INT NOT NULL DEFAULT 0",
        "ALTER TABLE mj_deals ADD COLUMN IF NOT EXISTS view_count INT NOT NULL DEFAULT 0",
        "ALTER TABLE mj_listings ADD COLUMN IF NOT EXISTS approved_at DATETIME NULL",
        "ALTER TABLE mj_listings ADD COLUMN IF NOT EXISTS approved_by BIGINT NULL",
        "ALTER TABLE mj_listings ADD COLUMN IF NOT EXISTS company_id BIGINT NULL",
        "ALTER TABLE mj_listings ADD COLUMN IF NOT EXISTS branch_id BIGINT NULL",
        "ALTER TABLE mj_listings ADD COLUMN IF NOT EXISTS published_at DATETIME NULL",
        "ALTER TABLE mj_listings ADD COLUMN IF NOT EXISTS expires_at DATETIME NULL",
        "ALTER TABLE mj_subscriptions ADD COLUMN IF NOT EXISTS user_id BIGINT NULL",
        "ALTER TABLE mj_subscriptions ADD COLUMN IF NOT EXISTS company_id BIGINT NULL",
        "ALTER TABLE mj_subscriptions ADD COLUMN IF NOT EXISTS plan_name VARCHAR(120) NULL",
        "ALTER TABLE mj_subscriptions ADD COLUMN IF NOT EXISTS status VARCHAR(40) DEFAULT 'active'",
        "ALTER TABLE mj_subscriptions ADD COLUMN IF NOT EXISTS starts_at DATETIME NULL",
        "ALTER TABLE mj_subscriptions ADD COLUMN IF NOT EXISTS ends_at DATETIME NULL",
        "ALTER TABLE mj_subscriptions ADD COLUMN IF NOT EXISTS created_at DATETIME DEFAULT CURRENT_TIMESTAMP",
        "CREATE TABLE IF NOT EXISTS seller_leads (id BIGINT AUTO_INCREMENT PRIMARY KEY, seller_user_id BIGINT UNSIGNED NOT NULL DEFAULT 0, source_type VARCHAR(30) NOT NULL DEFAULT 'listing', source_id BIGINT UNSIGNED DEFAULT NULL, source_title VARCHAR(255) DEFAULT NULL, country VARCHAR(100) DEFAULT NULL, customer_name VARCHAR(160) DEFAULT NULL, customer_email VARCHAR(190) DEFAULT NULL, customer_phone VARCHAR(80) DEFAULT NULL, customer_message TEXT DEFAULT NULL, status VARCHAR(40) NOT NULL DEFAULT 'new', priority VARCHAR(20) NOT NULL DEFAULT 'normal', followup_at DATETIME DEFAULT NULL, last_activity_at DATETIME DEFAULT NULL, is_read TINYINT(1) NOT NULL DEFAULT 0, ip_address VARCHAR(80) DEFAULT NULL, user_agent VARCHAR(255) DEFAULT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, KEY idx_seller_status_created (seller_user_id,status,created_at), KEY idx_source (source_type,source_id), KEY idx_customer_email (customer_email), KEY idx_followup (seller_user_id,followup_at)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4",
        "CREATE TABLE IF NOT EXISTS seller_lead_activities (id BIGINT AUTO_INCREMENT PRIMARY KEY, lead_id BIGINT NOT NULL, user_id BIGINT NULL, user_type VARCHAR(20) DEFAULT 'seller', activity_type VARCHAR(40) NOT NULL DEFAULT 'note', note TEXT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, KEY idx_lead_created (lead_id,created_at)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4",
        "CREATE TABLE IF NOT EXISTS mj_seller_leads LIKE seller_leads",
        "CREATE TABLE IF NOT EXISTS mj_seller_lead_activities LIKE seller_lead_activities",
        "CREATE TABLE IF NOT EXISTS mj_seller_lead_notes (id BIGINT AUTO_INCREMENT PRIMARY KEY, lead_id BIGINT NOT NULL, user_id BIGINT NULL, note TEXT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, KEY idx_lead_created (lead_id,created_at)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4",
        "CREATE TABLE IF NOT EXISTS mj_seller_lead_followups (id BIGINT AUTO_INCREMENT PRIMARY KEY, lead_id BIGINT NOT NULL, user_id BIGINT NULL, followup_at DATETIME NULL, status VARCHAR(40) DEFAULT 'pending', note TEXT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, KEY idx_lead_followup (lead_id,followup_at), KEY idx_status_followup (status,followup_at)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"
    ];
    foreach ($sqls as $sql) {
        try { db()->exec($sql); } catch (Throwable $e) { /* Keep sample importer user-friendly; next insert will show exact issue if still critical. */ }
    }
}

function mj_run_sample_data(): array {
    $file = __DIR__ . '/../install/sample_data.sql';
    if (!file_exists($file)) { throw new RuntimeException('sample_data.sql missing.'); }
    mj_sample_data_schema_repair();
    db()->exec(file_get_contents($file));
    admin_log('install_sample_data', 'system', 0, []);
    return ['ok'=>1,'bad'=>0,'errors'=>[]];
}
