<?php
// MJ Marketplace v3.0.3 - Unified leads inbox helpers with listing/company enquiry forms.
// Business rule: leads are for follow-up only; customers do not pay sellers through MJ Marketplace.

if (!function_exists('mj_leads_ensure_schema')) {
function mj_leads_ensure_schema(): void {
    if (!mj_is_installed()) { return; }
    if (function_exists('mj_crm_ensure_schema')) { try { mj_crm_ensure_schema(); } catch (Throwable $e) {} }

    try {
        q("CREATE TABLE IF NOT EXISTS mj_listing_enquiries (
            id BIGINT AUTO_INCREMENT PRIMARY KEY,
            listing_id BIGINT NOT NULL,
            seller_user_id BIGINT NOT NULL,
            company_id BIGINT NULL,
            customer_user_id BIGINT NULL,
            name VARCHAR(190) NOT NULL,
            email VARCHAR(190) NULL,
            phone VARCHAR(80) NULL,
            preferred_contact VARCHAR(40) NULL,
            message TEXT NOT NULL,
            status VARCHAR(40) NOT NULL DEFAULT 'new',
            ip_address VARCHAR(64) NULL,
            user_agent VARCHAR(255) NULL,
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
            updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            INDEX(listing_id), INDEX(seller_user_id), INDEX(company_id), INDEX(customer_user_id), INDEX(status), INDEX(created_at)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
    } catch (Throwable $e) {}
    try {
        q("CREATE TABLE IF NOT EXISTS mj_company_enquiries (
            id BIGINT AUTO_INCREMENT PRIMARY KEY,
            company_id BIGINT NOT NULL,
            owner_user_id BIGINT NOT NULL,
            customer_user_id BIGINT NULL,
            name VARCHAR(190) NOT NULL,
            email VARCHAR(190) NULL,
            phone VARCHAR(80) NULL,
            service_interested VARCHAR(190) NULL,
            preferred_contact VARCHAR(40) NULL,
            message TEXT NOT NULL,
            status VARCHAR(40) NOT NULL DEFAULT 'new',
            ip_address VARCHAR(64) NULL,
            user_agent VARCHAR(255) NULL,
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
            updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            INDEX(company_id), INDEX(owner_user_id), INDEX(customer_user_id), INDEX(status), INDEX(created_at)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
    } catch (Throwable $e) {}
    try {
        q("CREATE TABLE IF NOT EXISTS mj_lead_notes (
            id BIGINT AUTO_INCREMENT PRIMARY KEY,
            customer_id BIGINT NOT NULL,
            actor_user_id BIGINT NULL,
            actor_admin_id BIGINT NULL,
            note TEXT NULL,
            status_from VARCHAR(40) NULL,
            status_to VARCHAR(40) NULL,
            followup_at DATETIME NULL,
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
            INDEX(customer_id), INDEX(actor_user_id), INDEX(actor_admin_id), INDEX(created_at)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
    } catch (Throwable $e) {}
    $defs = [
        'user_leads_inbox_enabled'=>'1',
        'global_lead_popup_enabled'=>'1',
        'lead_browser_notification_enabled'=>'1',
        'lead_email_notification_enabled'=>'1'
    ];
    foreach ($defs as $k=>$v) {
        try { q('INSERT INTO mj_settings(setting_key,setting_value) VALUES(?,?) ON DUPLICATE KEY UPDATE setting_value=setting_value', [$k,$v]); } catch (Throwable $e) {}
    }
}
}

if (!function_exists('mj_leads_statuses')) {
function mj_leads_statuses(): array {
    return [
        'new'=>'New',
        'contacted'=>'Contacted',
        'interested'=>'Interested',
        'quoted'=>'Quotation Sent',
        'follow_up'=>'Follow Up Later',
        'converted'=>'Converted Outside System',
        'lost'=>'Not Interested',
        'closed'=>'Closed',
        'spam'=>'Spam'
    ];
}
}

if (!function_exists('mj_leads_status_class')) {
function mj_leads_status_class(string $s): string {
    $map = ['new'=>'primary','contacted'=>'info','interested'=>'warning','quoted'=>'secondary','follow_up'=>'warning','converted'=>'success','lost'=>'dark','closed'=>'success','spam'=>'danger'];
    return $map[strtolower($s)] ?? 'secondary';
}
}

if (!function_exists('mj_leads_source_label')) {
function mj_leads_source_label(string $s): string {
    $map = [
        'deal'=>'Deal Enquiry', 'deal_enquiry'=>'Deal Enquiry', 'chat'=>'Chat Contact', 'quote'=>'Quote Request',
        'booking'=>'Booking Request', 'listing'=>'Listing Enquiry', 'listing_enquiry'=>'Listing Enquiry', 'company'=>'Company Enquiry', 'company_enquiry'=>'Company Enquiry', 'offer'=>'Offer', 'manual'=>'Manual Lead',
        'order'=>'Order Contact', 'whatsapp'=>'WhatsApp Click', 'call'=>'Call Click', 'email'=>'Email Click'
    ];
    return $map[$s] ?? ucwords(str_replace('_',' ', $s ?: 'Lead'));
}
}

if (!function_exists('mj_leads_source_icon')) {
function mj_leads_source_icon(string $s): string {
    return [
        'deal'=>'bi-fire', 'deal_enquiry'=>'bi-fire', 'chat'=>'bi-chat-dots', 'quote'=>'bi-file-earmark-text',
        'booking'=>'bi-calendar-check', 'listing'=>'bi-tag', 'listing_enquiry'=>'bi-tag', 'company'=>'bi-building', 'company_enquiry'=>'bi-building', 'offer'=>'bi-hand-thumbs-up',
        'manual'=>'bi-person-plus', 'whatsapp'=>'bi-whatsapp', 'call'=>'bi-telephone', 'email'=>'bi-envelope'
    ][$s] ?? 'bi-person-lines-fill';
}
}

if (!function_exists('mj_leads_timeline_exists')) {
function mj_leads_timeline_exists(int $customerId, string $relatedType, int $relatedId): bool {
    try { return (bool)one('SELECT id FROM mj_customer_timeline WHERE customer_id=? AND related_type=? AND related_id=? LIMIT 1', [$customerId,$relatedType,$relatedId]); }
    catch (Throwable $e) { return false; }
}
}

if (!function_exists('mj_leads_record_deal_enquiry')) {
function mj_leads_record_deal_enquiry(array $deal, int $enquiryId, array $data): int {
    mj_leads_ensure_schema();
    $ownerId = (int)($deal['user_id'] ?? $deal['seller_user_id'] ?? 0);
    if ($ownerId <= 0) { return 0; }
    $customerId = mj_crm_find_or_create_customer([
        'owner_user_id'=>$ownerId,
        'company_id'=>(int)($deal['company_id'] ?? 0),
        'customer_user_id'=>(int)($_SESSION['user_id'] ?? 0) ?: null,
        'name'=>(string)($data['name'] ?? ''),
        'email'=>(string)($data['email'] ?? ''),
        'phone'=>(string)($data['phone'] ?? ''),
        'whatsapp'=>(string)($data['phone'] ?? ''),
        'country_id'=>$deal['country_id'] ?? null,
        'city_id'=>$deal['city_id'] ?? null,
        'source_type'=>'deal',
        'source_id'=>$enquiryId,
        'source_label'=>(string)($deal['title'] ?? 'Deal enquiry'),
        'status'=>'new'
    ]);
    if ($customerId && !mj_leads_timeline_exists($customerId, 'deal_enquiry', $enquiryId)) {
        $note = trim((string)($data['message'] ?? ''));
        if (!empty($data['preferred_datetime'])) { $note .= ($note ? "\n" : '') . 'Preferred: ' . (string)$data['preferred_datetime']; }
        mj_crm_timeline_add($customerId, 'deal_enquiry', 'New deal enquiry', $note, 'deal_enquiry', $enquiryId, 0);
    }
    return (int)$customerId;
}
}



if (!function_exists('mj_leads_validate_enquiry_payload')) {
function mj_leads_validate_enquiry_payload(array $data): array {
    $name = trim((string)($data['name'] ?? ''));
    $email = trim((string)($data['email'] ?? ''));
    $phone = trim((string)($data['phone'] ?? ''));
    $message = trim((string)($data['message'] ?? ''));
    $preferred = trim((string)($data['preferred_contact'] ?? ''));
    if ($name === '') { throw new RuntimeException('Please enter your name.'); }
    if ($email === '' && $phone === '') { throw new RuntimeException('Please enter email or phone/WhatsApp so the seller can contact you.'); }
    if ($email !== '' && !filter_var($email, FILTER_VALIDATE_EMAIL)) { throw new RuntimeException('Please enter a valid email address.'); }
    if ($message === '') { throw new RuntimeException('Please enter your enquiry message.'); }
    if (mb_strlen($message) > 3000) { $message = mb_substr($message, 0, 3000); }
    $allowed = ['','whatsapp','call','email'];
    if (!in_array($preferred, $allowed, true)) { $preferred = ''; }
    return ['name'=>$name,'email'=>$email,'phone'=>$phone,'message'=>$message,'preferred_contact'=>$preferred];
}
}

if (!function_exists('mj_leads_record_listing_enquiry')) {
function mj_leads_record_listing_enquiry(array $listing, array $data): int {
    mj_leads_ensure_schema();
    $payload = mj_leads_validate_enquiry_payload($data);
    $ownerId = (int)($listing['user_id'] ?? $listing['seller_user_id'] ?? 0);
    if ($ownerId <= 0) { throw new RuntimeException('Seller account is not available for this listing.'); }
    $listingId = (int)($listing['id'] ?? 0);
    if ($listingId <= 0) { throw new RuntimeException('Listing not found.'); }
    $companyId = !empty($listing['company_id']) ? (int)$listing['company_id'] : 0;
    q('INSERT INTO mj_listing_enquiries(listing_id,seller_user_id,company_id,customer_user_id,name,email,phone,preferred_contact,message,status,ip_address,user_agent,created_at,updated_at) VALUES(?,?,?,?,?,?,?,?,?,"new",?,?,NOW(),NOW())', [
        $listingId,$ownerId,$companyId ?: null,(int)($_SESSION['user_id'] ?? 0) ?: null,$payload['name'],$payload['email'],$payload['phone'],$payload['preferred_contact'],$payload['message'],$_SERVER['REMOTE_ADDR'] ?? '', substr((string)($_SERVER['HTTP_USER_AGENT'] ?? ''),0,255)
    ]);
    $enquiryId = (int)db()->lastInsertId();
    $customerId = mj_crm_find_or_create_customer([
        'owner_user_id'=>$ownerId,
        'company_id'=>$companyId ?: null,
        'customer_user_id'=>(int)($_SESSION['user_id'] ?? 0) ?: null,
        'name'=>$payload['name'], 'email'=>$payload['email'], 'phone'=>$payload['phone'], 'whatsapp'=>$payload['phone'],
        'country_id'=>$listing['country_id'] ?? null, 'city_id'=>$listing['city_id'] ?? null,
        'source_type'=>'listing', 'source_id'=>$enquiryId, 'source_label'=>(string)($listing['title'] ?? 'Listing enquiry'), 'status'=>'new'
    ]);
    if ($customerId && !mj_leads_timeline_exists($customerId, 'listing_enquiry', $enquiryId)) {
        $note = $payload['message'];
        if ($payload['preferred_contact'] !== '') { $note .= "\nPreferred contact: ".$payload['preferred_contact']; }
        mj_crm_timeline_add($customerId, 'listing_enquiry', 'New listing enquiry', $note, 'listing_enquiry', $enquiryId, 0);
    }
    $leadUrl = 'my-leads.php?source=listing'.($customerId ? '&lead='.$customerId : '');
    try { if (function_exists('mjv3041_record_seller_lead')) { mjv3041_record_seller_lead(['seller_user_id'=>$ownerId,'source_type'=>'listing','source_id'=>$listingId,'source_title'=>(string)($listing['title'] ?? 'Listing'),'country'=>(string)($listing['country'] ?? ''),'customer_name'=>$payload['name'],'customer_email'=>$payload['email'],'customer_phone'=>$payload['phone'],'customer_message'=>$payload['message']]); } } catch(Throwable $ignore) {}
    // v3.0.4.2.9: mjv3041_record_seller_lead creates the seller/admin notifications with de-duplication.
    return $customerId ?: $enquiryId;
}
}

if (!function_exists('mj_leads_record_company_enquiry')) {
function mj_leads_record_company_enquiry(array $company, array $data): int {
    mj_leads_ensure_schema();
    $payload = mj_leads_validate_enquiry_payload($data);
    $ownerId = (int)($company['user_id'] ?? $company['owner_user_id'] ?? 0);
    if ($ownerId <= 0) { throw new RuntimeException('Company owner account is not available.'); }
    $companyId = (int)($company['id'] ?? 0);
    if ($companyId <= 0) { throw new RuntimeException('Company not found.'); }
    $serviceInterested = trim((string)($data['service_interested'] ?? ''));
    q('INSERT INTO mj_company_enquiries(company_id,owner_user_id,customer_user_id,name,email,phone,service_interested,preferred_contact,message,status,ip_address,user_agent,created_at,updated_at) VALUES(?,?,?,?,?,?,?,?,?,"new",?,?,NOW(),NOW())', [
        $companyId,$ownerId,(int)($_SESSION['user_id'] ?? 0) ?: null,$payload['name'],$payload['email'],$payload['phone'],$serviceInterested,$payload['preferred_contact'],$payload['message'],$_SERVER['REMOTE_ADDR'] ?? '', substr((string)($_SERVER['HTTP_USER_AGENT'] ?? ''),0,255)
    ]);
    $enquiryId = (int)db()->lastInsertId();
    $customerId = mj_crm_find_or_create_customer([
        'owner_user_id'=>$ownerId,
        'company_id'=>$companyId,
        'customer_user_id'=>(int)($_SESSION['user_id'] ?? 0) ?: null,
        'name'=>$payload['name'], 'email'=>$payload['email'], 'phone'=>$payload['phone'], 'whatsapp'=>$payload['phone'],
        'country_id'=>$company['country_id'] ?? null, 'city_id'=>$company['city_id'] ?? null,
        'source_type'=>'company', 'source_id'=>$enquiryId, 'source_label'=>(string)($company['name'] ?? 'Company enquiry'), 'status'=>'new'
    ]);
    if ($customerId && !mj_leads_timeline_exists($customerId, 'company_enquiry', $enquiryId)) {
        $note = $payload['message'];
        if ($serviceInterested !== '') { $note .= "\nService interested: ".$serviceInterested; }
        if ($payload['preferred_contact'] !== '') { $note .= "\nPreferred contact: ".$payload['preferred_contact']; }
        mj_crm_timeline_add($customerId, 'company_enquiry', 'New company enquiry', $note, 'company_enquiry', $enquiryId, 0);
    }
    $leadUrl = 'my-leads.php?source=company'.($customerId ? '&lead='.$customerId : '');
    try { if (function_exists('mjv3041_record_seller_lead')) { mjv3041_record_seller_lead(['seller_user_id'=>$ownerId,'source_type'=>'company','source_id'=>$companyId,'source_title'=>(string)($company['name'] ?? 'Company'),'country'=>(string)($company['country'] ?? ''),'customer_name'=>$payload['name'],'customer_email'=>$payload['email'],'customer_phone'=>$payload['phone'],'customer_message'=>$payload['message']]); } } catch(Throwable $ignore) {}
    // v3.0.4.2.9: mjv3041_record_seller_lead creates the seller/admin notifications with de-duplication.
    return $customerId ?: $enquiryId;
}
}

if (!function_exists('mj_leads_notify_admins')) {
function mj_leads_notify_admins(string $title, string $message, string $url='leads.php', string $type='lead_alert'): void {
    if (function_exists('mjv3041_notify_admins')) { mjv3041_notify_admins($title, $message, 'lead', $url, ['legacy_type'=>$type]); return; }
    mj263_schema();
    try {
        if (!table_exists('mj_admin_users') || !table_exists('mj_notifications')) { return; }
        $admins = all_rows("SELECT id FROM mj_admin_users WHERE status IN ('active','enabled','1') OR status IS NULL OR status='' LIMIT 50");
        if (!$admins) { $admins = all_rows('SELECT id FROM mj_admin_users LIMIT 20'); }
        foreach ($admins as $a) {
            q('INSERT INTO mj_notifications(user_id,admin_id,type,title,message,priority,action_url,created_at) VALUES(NULL,?,?,?,?,?,?,NOW())', [(int)$a['id'],$type,$title,$message,'normal',$url]);
        }
    } catch (Throwable $e) {}
}
}

if (!function_exists('mj_leads_record_chat_message')) {
function mj_leads_record_chat_message(array $chat, int $senderId, int $receiverId, string $message): int {
    mj_leads_ensure_schema();
    // A chat becomes a seller lead only when the seller receives a customer/buyer message.
    if ((int)($chat['seller_id'] ?? 0) !== $receiverId || (int)($chat['buyer_id'] ?? 0) !== $senderId) { return 0; }
    try {
        $buyer = one('SELECT name,email,mobile FROM mj_users WHERE id=? LIMIT 1', [$senderId]) ?: [];
        $listing = !empty($chat['listing_id']) && table_exists('mj_listings') ? one('SELECT title,company_id,country_id,city_id FROM mj_listings WHERE id=? LIMIT 1', [(int)$chat['listing_id']]) : null;
        $company = !empty($chat['company_id']) && table_exists('mj_companies') ? one('SELECT name FROM mj_companies WHERE id=? LIMIT 1', [(int)$chat['company_id']]) : null;
        $label = (string)($listing['title'] ?? $company['name'] ?? 'Chat contact');
        $customerId = mj_crm_find_or_create_customer([
            'owner_user_id'=>$receiverId,
            'company_id'=>(int)($chat['company_id'] ?? ($listing['company_id'] ?? 0)),
            'customer_user_id'=>$senderId,
            'name'=>(string)($buyer['name'] ?? 'Customer'),
            'email'=>(string)($buyer['email'] ?? ''),
            'phone'=>(string)($buyer['mobile'] ?? ''),
            'whatsapp'=>(string)($buyer['mobile'] ?? ''),
            'country_id'=>$listing['country_id'] ?? null,
            'city_id'=>$listing['city_id'] ?? null,
            'source_type'=>'chat',
            'source_id'=>(int)($chat['id'] ?? 0),
            'source_label'=>$label,
            'status'=>'new'
        ]);
        if ($customerId && !mj_leads_timeline_exists($customerId, 'chat', (int)($chat['id'] ?? 0))) {
            mj_crm_timeline_add($customerId, 'chat', 'New chat contact', mb_strimwidth($message,0,500,'...'), 'chat', (int)$chat['id'], $senderId);
        }
        try { if ($customerId && function_exists('mjv3041_notify_user')) { mjv3041_notify_user($receiverId, 'New chat lead', mb_strimwidth($message,0,140,'...'), 'chat', 'messages.php', ['chat_id'=>(int)($chat['id'] ?? 0),'lead_id'=>$customerId]); mjv3041_notify_admins('New chat contact', 'New chat lead received by seller #'.$receiverId, 'chat', 'admin/leads.php?source=chat', ['chat_id'=>(int)($chat['id'] ?? 0),'seller_user_id'=>$receiverId]); } } catch(Throwable $ignore) {}
        return (int)$customerId;
    } catch (Throwable $e) { return 0; }
}
}

if (!function_exists('mj_leads_sync_user')) {
function mj_leads_sync_user(int $userId): array {
    mj_leads_ensure_schema();
    $out = ['deal'=>0,'listing'=>0,'company'=>0,'chat'=>0,'crm'=>0];
    try { if (function_exists('mj_crm_sync_from_marketplace')) { $sync=mj_crm_sync_from_marketplace(); $out['crm']=(int)($sync['updated'] ?? 0); } } catch (Throwable $e) {}
    try {
        if (table_exists('mj_deal_enquiries') && table_exists('mj_deals')) {
            $rows = all_rows('SELECT e.*, d.title deal_title, d.user_id deal_owner_id, d.company_id deal_company_id, d.country_id, d.city_id FROM mj_deal_enquiries e INNER JOIN mj_deals d ON d.id=e.deal_id WHERE COALESCE(e.seller_user_id,d.user_id)=? ORDER BY e.id DESC LIMIT 1000', [$userId]);
            foreach ($rows as $r) {
                $cid = mj_crm_find_or_create_customer([
                    'owner_user_id'=>$userId,
                    'company_id'=>(int)($r['company_id'] ?: $r['deal_company_id'] ?: 0),
                    'customer_user_id'=>(int)($r['customer_user_id'] ?? 0) ?: null,
                    'name'=>(string)($r['name'] ?? ''), 'email'=>(string)($r['email'] ?? ''), 'phone'=>(string)($r['phone'] ?? ''), 'whatsapp'=>(string)($r['phone'] ?? ''),
                    'country_id'=>$r['country_id'] ?? null, 'city_id'=>$r['city_id'] ?? null,
                    'source_type'=>'deal', 'source_id'=>(int)$r['id'], 'source_label'=>(string)($r['deal_title'] ?? 'Deal enquiry'), 'status'=>(string)($r['status'] ?: 'new')
                ]);
                if ($cid && !mj_leads_timeline_exists($cid, 'deal_enquiry', (int)$r['id'])) {
                    $note=(string)($r['message'] ?? ''); if(!empty($r['preferred_datetime'])){ $note .= ($note?"\n":'').'Preferred: '.$r['preferred_datetime']; }
                    mj_crm_timeline_add($cid, 'deal_enquiry', 'New deal enquiry', $note, 'deal_enquiry', (int)$r['id']); $out['deal']++;
                }
            }
        }
    } catch (Throwable $e) {}

    try {
        if (table_exists('mj_listing_enquiries') && table_exists('mj_listings')) {
            $rows = all_rows('SELECT e.*, l.title listing_title, l.country_id, l.city_id FROM mj_listing_enquiries e INNER JOIN mj_listings l ON l.id=e.listing_id WHERE e.seller_user_id=? ORDER BY e.id DESC LIMIT 1000', [$userId]);
            foreach ($rows as $r) {
                $cid = mj_crm_find_or_create_customer([
                    'owner_user_id'=>$userId,
                    'company_id'=>(int)($r['company_id'] ?? 0) ?: null,
                    'customer_user_id'=>(int)($r['customer_user_id'] ?? 0) ?: null,
                    'name'=>(string)($r['name'] ?? ''), 'email'=>(string)($r['email'] ?? ''), 'phone'=>(string)($r['phone'] ?? ''), 'whatsapp'=>(string)($r['phone'] ?? ''),
                    'country_id'=>$r['country_id'] ?? null, 'city_id'=>$r['city_id'] ?? null,
                    'source_type'=>'listing', 'source_id'=>(int)$r['id'], 'source_label'=>(string)($r['listing_title'] ?? 'Listing enquiry'), 'status'=>(string)($r['status'] ?: 'new')
                ]);
                if ($cid && !mj_leads_timeline_exists($cid, 'listing_enquiry', (int)$r['id'])) {
                    $note=(string)($r['message'] ?? ''); if(!empty($r['preferred_contact'])){ $note .= ($note?"\n":'').'Preferred contact: '.$r['preferred_contact']; }
                    mj_crm_timeline_add($cid, 'listing_enquiry', 'New listing enquiry', $note, 'listing_enquiry', (int)$r['id']); $out['listing']++;
                }
            }
        }
    } catch (Throwable $e) {}
    try {
        if (table_exists('mj_company_enquiries') && table_exists('mj_companies')) {
            $rows = all_rows('SELECT e.*, co.name company_name, co.country_id, co.city_id FROM mj_company_enquiries e INNER JOIN mj_companies co ON co.id=e.company_id WHERE e.owner_user_id=? ORDER BY e.id DESC LIMIT 1000', [$userId]);
            foreach ($rows as $r) {
                $cid = mj_crm_find_or_create_customer([
                    'owner_user_id'=>$userId,
                    'company_id'=>(int)($r['company_id'] ?? 0),
                    'customer_user_id'=>(int)($r['customer_user_id'] ?? 0) ?: null,
                    'name'=>(string)($r['name'] ?? ''), 'email'=>(string)($r['email'] ?? ''), 'phone'=>(string)($r['phone'] ?? ''), 'whatsapp'=>(string)($r['phone'] ?? ''),
                    'country_id'=>$r['country_id'] ?? null, 'city_id'=>$r['city_id'] ?? null,
                    'source_type'=>'company', 'source_id'=>(int)$r['id'], 'source_label'=>(string)($r['company_name'] ?? 'Company enquiry'), 'status'=>(string)($r['status'] ?: 'new')
                ]);
                if ($cid && !mj_leads_timeline_exists($cid, 'company_enquiry', (int)$r['id'])) {
                    $note=(string)($r['message'] ?? ''); if(!empty($r['service_interested'])){ $note .= ($note?"\n":'').'Service interested: '.$r['service_interested']; } if(!empty($r['preferred_contact'])){ $note .= ($note?"\n":'').'Preferred contact: '.$r['preferred_contact']; }
                    mj_crm_timeline_add($cid, 'company_enquiry', 'New company enquiry', $note, 'company_enquiry', (int)$r['id']); $out['company']++;
                }
            }
        }
    } catch (Throwable $e) {}
    try {
        if (table_exists('mj_chats')) {
            $rows = all_rows('SELECT ch.*, b.name buyer_name, b.email buyer_email, b.mobile buyer_mobile, l.title listing_title, l.company_id listing_company_id, l.country_id, l.city_id, co.name company_name FROM mj_chats ch LEFT JOIN mj_users b ON b.id=ch.buyer_id LEFT JOIN mj_listings l ON l.id=ch.listing_id LEFT JOIN mj_companies co ON co.id=ch.company_id WHERE ch.seller_id=? ORDER BY COALESCE(ch.last_message_at,ch.created_at) DESC LIMIT 500', [$userId]);
            foreach ($rows as $r) {
                $cid = mj_crm_find_or_create_customer([
                    'owner_user_id'=>$userId, 'company_id'=>(int)($r['company_id'] ?: $r['listing_company_id'] ?: 0), 'customer_user_id'=>(int)($r['buyer_id'] ?? 0) ?: null,
                    'name'=>(string)($r['buyer_name'] ?? 'Customer'), 'email'=>(string)($r['buyer_email'] ?? ''), 'phone'=>(string)($r['buyer_mobile'] ?? ''), 'whatsapp'=>(string)($r['buyer_mobile'] ?? ''),
                    'country_id'=>$r['country_id'] ?? null, 'city_id'=>$r['city_id'] ?? null, 'source_type'=>'chat', 'source_id'=>(int)$r['id'], 'source_label'=>(string)($r['listing_title'] ?: $r['company_name'] ?: 'Chat contact'), 'status'=>'new'
                ]);
                if ($cid && !mj_leads_timeline_exists($cid, 'chat', (int)$r['id'])) {
                    mj_crm_timeline_add($cid, 'chat', 'Chat contact', mb_strimwidth((string)($r['last_message'] ?? ''),0,500,'...'), 'chat', (int)$r['id']); $out['chat']++;
                }
            }
        }
    } catch (Throwable $e) {}
    return $out;
}
}

if (!function_exists('mj_leads_counts')) {
function mj_leads_counts(int $userId): array {
    mj_leads_sync_user($userId);
    $base = ['total'=>0,'new'=>0,'today'=>0,'deal'=>0,'listing'=>0,'company'=>0,'chat'=>0,'follow_up'=>0,'converted'=>0];
    try {
        $base['total'] = safe_count('SELECT COUNT(*) c FROM mj_customers WHERE owner_user_id=?', [$userId]);
        $base['new'] = safe_count('SELECT COUNT(*) c FROM mj_customers WHERE owner_user_id=? AND status="new"', [$userId]);
        $base['today'] = safe_count('SELECT COUNT(*) c FROM mj_customers WHERE owner_user_id=? AND DATE(COALESCE(last_activity_at,created_at))=CURDATE()', [$userId]);
        $base['deal'] = safe_count('SELECT COUNT(*) c FROM mj_customers WHERE owner_user_id=? AND source_type IN ("deal","deal_enquiry")', [$userId]);
        $base['listing'] = safe_count('SELECT COUNT(*) c FROM mj_customers WHERE owner_user_id=? AND source_type IN ("listing","listing_enquiry")', [$userId]);
        $base['company'] = safe_count('SELECT COUNT(*) c FROM mj_customers WHERE owner_user_id=? AND source_type IN ("company","company_enquiry")', [$userId]);
        $base['chat'] = safe_count('SELECT COUNT(*) c FROM mj_customers WHERE owner_user_id=? AND source_type="chat"', [$userId]);
        $base['follow_up'] = safe_count('SELECT COUNT(*) c FROM mj_customers WHERE owner_user_id=? AND (status="follow_up" OR next_followup_at IS NOT NULL)', [$userId]);
        $base['converted'] = safe_count('SELECT COUNT(*) c FROM mj_customers WHERE owner_user_id=? AND status="converted"', [$userId]);
    } catch (Throwable $e) {}
    return $base;
}
}

if (!function_exists('mj_leads_fetch_user')) {
function mj_leads_fetch_user(int $userId, array $filters=[]): array {
    mj_leads_sync_user($userId);
    $where = ['owner_user_id=?']; $params = [$userId];
    $status = trim((string)($filters['status'] ?? ''));
    $source = trim((string)($filters['source'] ?? ''));
    $qv = trim((string)($filters['q'] ?? ''));
    if ($status !== '') { $where[] = 'status=?'; $params[] = $status; }
    if ($source !== '') { $where[] = 'source_type=?'; $params[] = $source; }
    if ($qv !== '') { $where[] = '(name LIKE ? OR email LIKE ? OR phone LIKE ? OR whatsapp LIKE ? OR source_label LIKE ? OR private_note LIKE ?)'; for($i=0;$i<6;$i++) $params[]='%'.$qv.'%'; }
    try { return all_rows('SELECT * FROM mj_customers WHERE '.implode(' AND ', $where).' ORDER BY COALESCE(last_activity_at,created_at) DESC, id DESC LIMIT 250', $params); }
    catch (Throwable $e) { return []; }
}
}

if (!function_exists('mj_leads_update_customer')) {
function mj_leads_update_customer(int $customerId, int $userId, string $status, string $note='', string $followup=''): void {
    mj_leads_ensure_schema();
    $lead = one('SELECT * FROM mj_customers WHERE id=? AND owner_user_id=? LIMIT 1', [$customerId,$userId]);
    if (!$lead) { throw new RuntimeException('Lead not found.'); }
    $statuses = array_keys(mj_leads_statuses());
    if (!in_array($status, $statuses, true)) { throw new RuntimeException('Invalid lead status.'); }
    $followupSql = null;
    if (trim($followup) !== '') { $ts = strtotime($followup); if (!$ts) { throw new RuntimeException('Invalid follow-up date.'); } $followupSql = date('Y-m-d H:i:s', $ts); }
    q('UPDATE mj_customers SET status=?, next_followup_at=?, private_note=IF(?<>"", ?, private_note), last_activity_at=NOW(), updated_at=NOW() WHERE id=? AND owner_user_id=?', [$status,$followupSql,$note,$note,$customerId,$userId]);
    try { q('INSERT INTO mj_lead_notes(customer_id,actor_user_id,note,status_from,status_to,followup_at,created_at) VALUES(?,?,?,?,?,?,NOW())', [$customerId,$userId,$note,(string)($lead['status']??''),$status,$followupSql]); } catch (Throwable $e) {}
    mj_crm_timeline_add($customerId, 'followup_note', 'Lead updated to '.mj_leads_statuses()[$status], $note, 'customer', $customerId, $userId);
}
}

if (!function_exists('mj_leads_action_url')) {
function mj_leads_action_url(array $lead): string {
    $type = (string)($lead['source_type'] ?? ''); $id = (int)($lead['source_id'] ?? 0);
    if ($type === 'deal' || $type === 'deal_enquiry') { return base_url('my-leads.php?source=deal&lead='.(int)$lead['id']); }
    if (($type === 'listing' || $type === 'listing_enquiry') && $id > 0) { try { $e = table_exists('mj_listing_enquiries') ? one('SELECT listing_id FROM mj_listing_enquiries WHERE id=? LIMIT 1', [$id]) : null; if ($e) return base_url('listing.php?id='.(int)$e['listing_id']); } catch(Throwable $ignore) {} return base_url('my-leads.php?source=listing&lead='.(int)$lead['id']); }
    if (($type === 'company' || $type === 'company_enquiry') && $id > 0) { try { $e = table_exists('mj_company_enquiries') ? one('SELECT company_id FROM mj_company_enquiries WHERE id=? LIMIT 1', [$id]) : null; if ($e) return base_url('company.php?id='.(int)$e['company_id']); } catch(Throwable $ignore) {} return base_url('my-leads.php?source=company&lead='.(int)$lead['id']); }
    if ($type === 'chat' && $id > 0) { return base_url('messages.php'); }
    if ($type === 'quote') { return base_url('my-quotes.php'); }
    if ($type === 'booking') { return base_url('appointments.php'); }
    return base_url('customer-view.php?id='.(int)$lead['id']);
}
}

if (!function_exists('mj_leads_contact_buttons')) {
function mj_leads_contact_buttons(array $lead): string {
    $phone = preg_replace('/[^0-9+]/','',(string)($lead['whatsapp'] ?: $lead['phone'] ?: ''));
    $phoneDigits = preg_replace('/[^0-9]/','',$phone);
    $email = trim((string)($lead['email'] ?? ''));
    $html = '<div class="d-flex flex-wrap gap-1">';
    if ($phoneDigits !== '') { $html .= '<a class="btn btn-sm btn-success rounded-pill" target="_blank" href="https://wa.me/'.e($phoneDigits).'"><i class="bi bi-whatsapp"></i> WhatsApp</a>'; $html .= '<a class="btn btn-sm btn-outline-primary rounded-pill" href="tel:'.e($phone).'"><i class="bi bi-telephone"></i> Call</a>'; }
    if ($email !== '') { $html .= '<a class="btn btn-sm btn-outline-secondary rounded-pill" href="mailto:'.e($email).'"><i class="bi bi-envelope"></i> Email</a>'; }
    return $html . '</div>';
}
}
?>
