     1→<?php
     2→/**
     3→ * Thread View Page
     4→ *
     5→ * Dedicated page for viewing email threads and sending to AI API.
     6→ * Features:
     7→ * - View thread emails with actual sender names
     8→ * - Select additional threads from the same contact
     9→ * - Send to AI API with provider/model selection
    10→ * - Add custom questions and context
    11→ * - Save and load AI responses
    12→ *
    13→ * @package EmailIntelligence
    14→ */
    15→
    16→require_once dirname(__DIR__) . '/config/config.php';
    17→require_once dirname(__DIR__) . '/vendor/autoload.php';
    18→
    19→use EmailIntelligence\MongoDatabase;
    20→use EmailIntelligence\QueryAdapter;
    21→
    22→session_start();
    23→
    24→// Get thread ID from URL
    25→$threadId = $_GET['thread_id'] ?? '';
    26→if (empty($threadId)) {
    27→    header('Location: index.php');
    28→    exit;
    29→}
    30→
    31→// Get data via QueryAdapter (which uses MongoDB)
    32→$adapter = QueryAdapter::getInstance();
    33→$mongo = MongoDatabase::getInstance();
    34→
    35→// Get thread details
    36→$threadData = $adapter->getThreadDetails($threadId);
    37→$emails = $threadData['emails'] ?? [];
    38→$analysis = $threadData['analysis'] ?? null;
    39→
    40→if (empty($emails)) {
    41→    header('Location: index.php?error=thread_not_found');
    42→    exit;
    43→}
    44→
    45→// Get the primary contact from this thread
    46→// Priority: 1) Most frequent external contact, 2) First inbound email sender, 3) Any contact
    47→$primaryContactId = null;
    48→$primaryContactEmail = null;
    49→$primaryContactName = null;
    50→$userEmail = defined('GMAIL_USER_EMAIL') ? strtolower(GMAIL_USER_EMAIL) : '';
    51→
    52→// Count contacts to find the most frequent one (excluding user)
    53→$contactCounts = [];
    54→$contactInfo = [];
    55→
    56→foreach ($emails as $email) {
    57→    if (!empty($email['contact_id'])) {
    58→        $contactId = $email['contact_id'];
    59→        $contactEmail = strtolower($email['contact_email'] ?? $email['from_email'] ?? '');
    60→
    61→        // Skip if this is the user's own email
    62→        if ($contactEmail === $userEmail) {
    63→            continue;
    64→        }
    65→
    66→        if (!isset($contactCounts[$contactId])) {
    67→            $contactCounts[$contactId] = 0;
    68→            $contactInfo[$contactId] = [
    69→                'email' => $email['contact_email'] ?? $email['from_email'],
    70→                'name' => $email['contact_name'] ?? ''
    71→            ];
    72→        }
    73→        $contactCounts[$contactId]++;
    74→    }
    75→}
    76→
    77→// Select the most frequent contact
    78→if (!empty($contactCounts)) {
    79→    arsort($contactCounts);
    80→    $primaryContactId = array_key_first($contactCounts);
    81→    $primaryContactEmail = $contactInfo[$primaryContactId]['email'];
    82→    $primaryContactName = $contactInfo[$primaryContactId]['name'];
    83→} else {
    84→    // Fallback: try to find any inbound email sender
    85→    foreach ($emails as $email) {
    86→        if (($email['direction'] ?? '') === 'inbound' && !empty($email['from_email'])) {
    87→            $senderEmail = strtolower($email['from_email']);
    88→            if ($senderEmail !== $userEmail) {
    89→                $primaryContactId = $email['contact_id'] ?? null;
    90→                $primaryContactEmail = $email['from_email'];
    91→                $primaryContactName = $email['from_name'] ?? $email['contact_name'] ?? '';
    92→                break;
    93→            }
    94→        }
    95→    }
    96→}
    97→
    98→// Get other threads from the same contact for selection
    99→$otherThreads = [];
   100→if ($primaryContactId) {
   101→    $contactThreads = $adapter->getThreads($primaryContactId, '', 50, 0);
   102→    foreach ($contactThreads['threads'] as $t) {
   103→        if ($t['thread_id'] !== $threadId) {
   104→            $otherThreads[] = $t;
   105→        }
   106→    }
   107→}
   108→
   109→// Get saved AI responses for this thread from MongoDB
   110→$savedResponsesLimit = 5; // Initial load limit
   111→$savedResponses = $mongo->findAll('ai_query_responses',
   112→    ['thread_ids' => $threadId],
   113→    ['sort' => ['created_at' => -1], 'limit' => $savedResponsesLimit]
   114→);
   115→
   116→// Get total count of saved responses for this thread
   117→$totalSavedResponses = $mongo->count('ai_query_responses', ['thread_ids' => $threadId]);
   118→
   119→// Get first email's subject for page title
   120→$threadSubject = $emails[0]['subject'] ?? '(No Subject)';
   121→
   122→// Build participant map for displaying real names
   123→$participantMap = [];
   124→// $userEmail already defined above
   125→
   126→foreach ($emails as $email) {
   127→    $fromEmail = strtolower($email['from_email'] ?? '');
   128→    if ($fromEmail && !isset($participantMap[$fromEmail])) {
   129→        $name = '';
   130→        if ($fromEmail === $userEmail) {
   131→            $name = 'You';
   132→        } elseif (!empty($email['from_name'])) {
   133→            $name = $email['from_name'];
   134→        } elseif (!empty($email['contact_name'])) {
   135→            $name = $email['contact_name'];
   136→        } else {
   137→            // Extract name from email
   138→            $parts = explode('@', $fromEmail);
   139→            $nameParts = explode('.', $parts[0]);
   140→            $name = ucfirst($nameParts[0]);
   141→        }
   142→        $participantMap[$fromEmail] = $name;
   143→    }
   144→}
   145→?>
   146→<!DOCTYPE html>
   147→<html lang="en">
   148→<head>
   149→    <meta charset="UTF-8">
   150→    <meta name="viewport" content="width=device-width, initial-scale=1.0">
   151→    <title>Thread: <?= htmlspecialchars($threadSubject) ?> - Email Intelligence</title>
   152→    <link rel="stylesheet" href="assets/style.css">
   153→    <style>
   154→        :root {
   155→            --bg-primary: #f5f7fa;
   156→            --bg-secondary: #ffffff;
   157→            --accent-primary: #667eea;
   158→            --accent-secondary: #764ba2;
   159→            --text-primary: #333;
   160→            --text-secondary: #666;
   161→            --border-color: #e0e0e0;
   162→            --success: #10b981;
   163→            --warning: #f59e0b;
   164→            --error: #ef4444;
   165→        }
   166→
   167→        body {
   168→            background: var(--bg-primary);
   169→            margin: 0;
   170→            padding: 0;
   171→        }
   172→
   173→        .page-container {
   174→            max-width: 1600px;
   175→            margin: 0 auto;
   176→            padding: 20px;
   177→        }
   178→
   179→        .page-header {
   180→            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
   181→            color: white;
   182→            padding: 20px 30px;
   183→            border-radius: 12px;
   184→            margin-bottom: 20px;
   185→            display: flex;
   186→            justify-content: space-between;
   187→            align-items: center;
   188→        }
   189→
   190→        .page-header h1 {
   191→            margin: 0 0 5px 0;
   192→            font-size: 1.5em;
   193→        }
   194→
   195→        .page-header .subtitle {
   196→            opacity: 0.9;
   197→            font-size: 0.9em;
   198→        }
   199→
   200→        .back-link {
   201→            color: white;
   202→            text-decoration: none;
   203→            padding: 10px 20px;
   204→            background: rgba(255,255,255,0.2);
   205→            border-radius: 8px;
   206→            transition: background 0.2s;
   207→        }
   208→
   209→        .back-link:hover {
   210→            background: rgba(255,255,255,0.3);
   211→        }
   212→
   213→        .main-grid {
   214→            display: grid;
   215→            grid-template-columns: 1fr 400px;
   216→            gap: 20px;
   217→        }
   218→
   219→        @media (max-width: 1200px) {
   220→            .main-grid {
   221→                grid-template-columns: 1fr;
   222→            }
   223→        }
   224→
   225→        .card {
   226→            background: var(--bg-secondary);
   227→            border-radius: 12px;
   228→            padding: 20px;
   229→            box-shadow: 0 2px 10px rgba(0,0,0,0.08);
   230→            margin-bottom: 20px;
   231→        }
   232→
   233→        .card-header {
   234→            display: flex;
   235→            justify-content: space-between;
   236→            align-items: center;
   237→            margin-bottom: 15px;
   238→            padding-bottom: 10px;
   239→            border-bottom: 1px solid var(--border-color);
   240→        }
   241→
   242→        .card-header h2 {
   243→            margin: 0;
   244→            font-size: 1.2em;
   245→            color: var(--text-primary);
   246→        }
   247→
   248→        /* Email Timeline */
   249→        .email-timeline {
   250→            max-height: 600px;
   251→            overflow-y: auto;
   252→        }
   253→
   254→        .email-item {
   255→            border-left: 4px solid #3b82f6;
   256→            padding: 15px;
   257→            margin-bottom: 15px;
   258→            background: #f9fafb;
   259→            border-radius: 0 8px 8px 0;
   260→        }
   261→
   262→        .email-item.inbound {
   263→            border-left-color: #10b981;
   264→        }
   265→
   266→        .email-item.outbound {
   267→            border-left-color: #3b82f6;
   268→        }
   269→
   270→        .email-meta {
   271→            display: flex;
   272→            justify-content: space-between;
   273→            align-items: center;
   274→            margin-bottom: 10px;
   275→        }
   276→
   277→        .sender-name {
   278→            font-weight: 600;
   279→            color: var(--text-primary);
   280→        }
   281→
   282→        .sender-email {
   283→            color: var(--text-secondary);
   284→            font-size: 0.85em;
   285→        }
   286→
   287→        .email-date {
   288→            color: var(--text-secondary);
   289→            font-size: 0.85em;
   290→        }
   291→
   292→        .email-body {
   293→            font-size: 0.95em;
   294→            line-height: 1.6;
   295→            color: var(--text-primary);
   296→            white-space: pre-wrap;
   297→            word-wrap: break-word;
   298→            max-height: 200px;
   299→            overflow-y: auto;
   300→            background: white;
   301→            padding: 10px;
   302→            border-radius: 6px;
   303→        }
   304→
   305→        /* Thread Selection */
   306→        .thread-selection {
   307→            max-height: 300px;
   308→            overflow-y: auto;
   309→        }
   310→
   311→        .thread-checkbox {
   312→            display: flex;
   313→            align-items: flex-start;
   314→            padding: 10px;
   315→            margin-bottom: 8px;
   316→            background: #f9fafb;
   317→            border-radius: 8px;
   318→            cursor: pointer;
   319→            transition: background 0.2s;
   320→        }
   321→
   322→        .thread-checkbox:hover {
   323→            background: #f0f0f5;
   324→        }
   325→
   326→        .thread-checkbox input {
   327→            margin-right: 12px;
   328→            margin-top: 3px;
   329→        }
   330→
   331→        .thread-checkbox-content {
   332→            flex: 1;
   333→        }
   334→
   335→        .thread-checkbox-subject {
   336→            font-weight: 500;
   337→            margin-bottom: 4px;
   338→        }
   339→
   340→        .thread-checkbox-meta {
   341→            font-size: 0.85em;
   342→            color: var(--text-secondary);
   343→        }
   344→
   345→        /* AI Query Form */
   346→        .ai-form-section {
   347→            margin-bottom: 20px;
   348→        }
   349→
   350→        .ai-form-section label {
   351→            display: block;
   352→            font-weight: 600;
   353→            margin-bottom: 8px;
   354→            color: var(--text-primary);
   355→        }
   356→
   357→        .ai-form-section textarea,
   358→        .ai-form-section input[type="text"],
   359→        .ai-form-section select {
   360→            width: 100%;
   361→            padding: 12px;
   362→            border: 1px solid var(--border-color);
   363→            border-radius: 8px;
   364→            font-family: inherit;
   365→            font-size: 0.95em;
   366→            box-sizing: border-box;
   367→        }
   368→
   369→        .ai-form-section textarea {
   370→            min-height: 100px;
   371→            resize: vertical;
   372→        }
   373→
   374→        .ai-form-section textarea:focus,
   375→        .ai-form-section input:focus,
   376→        .ai-form-section select:focus {
   377→            outline: none;
   378→            border-color: var(--accent-primary);
   379→        }
   380→
   381→        /* Provider Selection */
   382→        .provider-grid {
   383→            display: grid;
   384→            grid-template-columns: repeat(2, 1fr);
   385→            gap: 10px;
   386→        }
   387→
   388→        .provider-option {
   389→            display: flex;
   390→            align-items: center;
   391→            padding: 10px;
   392→            background: #f9fafb;
   393→            border: 1px solid var(--border-color);
   394→            border-radius: 8px;
   395→            cursor: pointer;
   396→            transition: all 0.2s;
   397→        }
   398→
   399→        .provider-option:hover {
   400→            border-color: var(--accent-primary);
   401→        }
   402→
   403→        .provider-option.selected {
   404→            background: rgba(102, 126, 234, 0.1);
   405→            border-color: var(--accent-primary);
   406→        }
   407→
   408→        .provider-option input {
   409→            margin-right: 8px;
   410→        }
   411→
   412→        .provider-option .provider-name {
   413→            font-weight: 500;
   414→            font-size: 0.9em;
   415→        }
   416→
   417→        .model-select {
   418→            margin-top: 8px;
   419→            padding: 6px 10px;
   420→            font-size: 0.85em;
   421→            background: white;
   422→        }
   423→
   424→        /* Buttons */
   425→        .btn {
   426→            padding: 12px 24px;
   427→            border: none;
   428→            border-radius: 8px;
   429→            font-size: 1em;
   430→            font-weight: 500;
   431→            cursor: pointer;
   432→            transition: all 0.2s;
   433→            display: inline-flex;
   434→            align-items: center;
   435→            gap: 8px;
   436→        }
   437→
   438→        .btn-primary {
   439→            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
   440→            color: white;
   441→        }
   442→
   443→        .btn-primary:hover {
   444→            transform: translateY(-2px);
   445→            box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
   446→        }
   447→
   448→        .btn-primary:disabled {
   449→            opacity: 0.6;
   450→            cursor: not-allowed;
   451→            transform: none;
   452→        }
   453→
   454→        .btn-secondary {
   455→            background: #e5e7eb;
   456→            color: var(--text-primary);
   457→        }
   458→
   459→        .btn-secondary:hover {
   460→            background: #d1d5db;
   461→        }
   462→
   463→        /* AI Response */
   464→        .ai-response-card {
   465→            background: #f0fdf4;
   466→            border: 2px solid #22c55e;
   467→            border-radius: 12px;
   468→            padding: 20px;
   469→            margin-bottom: 15px;
   470→        }
   471→
   472→        .ai-response-header {
   473→            display: flex;
   474→            justify-content: space-between;
   475→            align-items: center;
   476→            margin-bottom: 10px;
   477→        }
   478→
   479→        .ai-response-provider {
   480→            font-weight: 600;
   481→            color: #166534;
   482→        }
   483→
   484→        .ai-response-meta {
   485→            font-size: 0.85em;
   486→            color: #166534;
   487→        }
   488→
   489→        .ai-response-content {
   490→            white-space: pre-wrap;
   491→            line-height: 1.7;
   492→        }
   493→
   494→        /* Saved Responses */
   495→        .saved-response {
   496→            background: #f9fafb;
   497→            border: 2px solid var(--border-color);
   498→            border-radius: 8px;
   499→            padding: 15px;
   500→            margin-bottom: 10px;
   501→            transition: all 0.2s ease;
   502→            cursor: pointer;
   503→        }
   504→
   505→        .saved-response:hover {
   506→            border-color: var(--accent-primary);
   507→            background: #f0f4ff;
   508→        }
   509→
   510→        .saved-response.last-viewed {
   511→            border-color: var(--accent-primary);
   512→            background: linear-gradient(135deg, rgba(102, 126, 234, 0.08) 0%, rgba(118, 75, 162, 0.08) 100%);
   513→            box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.15);
   514→        }
   515→
   516→        .saved-response.last-viewed::before {
   517→            content: '← Last Viewed';
   518→            position: absolute;
   519→            right: 10px;
   520→            top: -10px;
   521→            background: var(--accent-primary);
   522→            color: white;
   523→            font-size: 0.7em;
   524→            padding: 2px 8px;
   525→            border-radius: 4px;
   526→        }
   527→
   528→        .saved-response {
   529→            position: relative;
   530→        }
   531→
   532→        .saved-response-header {
   533→            display: flex;
   534→            justify-content: space-between;
   535→            margin-bottom: 8px;
   536→        }
   537→
   538→        .saved-response-question {
   539→            font-weight: 500;
   540→            color: var(--text-primary);
   541→            flex: 1;
   542→            margin-right: 10px;
   543→        }
   544→
   545→        .saved-response-date {
   546→            font-size: 0.85em;
   547→            color: var(--text-secondary);
   548→            white-space: nowrap;
   549→        }
   550→
   551→        .saved-response-preview {
   552→            font-size: 0.85em;
   553→            color: var(--accent-primary);
   554→            font-weight: 600;
   555→            margin-bottom: 8px;
   556→        }
   557→
   558→        .saved-response-excerpt {
   559→            font-size: 0.85em;
   560→            color: var(--text-secondary);
   561→            background: rgba(255,255,255,0.7);
   562→            padding: 8px;
   563→            border-radius: 4px;
   564→            margin-bottom: 10px;
   565→            border-left: 3px solid #ddd;
   566→            font-style: italic;
   567→            line-height: 1.4;
   568→        }
   569→
   570→        .saved-response-actions {
   571→            display: flex;
   572→            gap: 8px;
   573→            margin-top: 10px;
   574→        }
   575→
   576→        .saved-response-actions .btn-view,
   577→        .saved-response-actions .btn-expand {
   578→            padding: 6px 12px;
   579→            border: none;
   580→            border-radius: 4px;
   581→            font-size: 0.8em;
   582→            cursor: pointer;
   583→            transition: all 0.2s;
   584→        }
   585→
   586→        .saved-response-actions .btn-view {
   587→            background: #e0e7ff;
   588→            color: #4338ca;
   589→        }
   590→
   591→        .saved-response-actions .btn-view:hover {
   592→            background: #c7d2fe;
   593→        }
   594→
   595→        .saved-response-actions .btn-expand {
   596→            background: #dbeafe;
   597→            color: #1d4ed8;
   598→        }
   599→
   600→        .saved-response-actions .btn-expand:hover {
   601→            background: #bfdbfe;
   602→        }
   603→
   604→        /* Quick View Modal */
   605→        .quick-view-overlay {
   606→            position: fixed;
   607→            top: 0;
   608→            left: 0;
   609→            right: 0;
   610→            bottom: 0;
   611→            background: rgba(0,0,0,0.7);
   612→            z-index: 2000;
   613→            display: flex;
   614→            justify-content: center;
   615→            align-items: flex-start;
   616→            padding: 40px 20px;
   617→            overflow-y: auto;
   618→        }
   619→
   620→        .quick-view-modal {
   621→            background: white;
   622→            border-radius: 12px;
   623→            max-width: 900px;
   624→            width: 100%;
   625→            max-height: calc(100vh - 80px);
   626→            overflow-y: auto;
   627→            box-shadow: 0 20px 60px rgba(0,0,0,0.3);
   628→        }
   629→
   630→        .quick-view-header {
   631→            display: flex;
   632→            justify-content: space-between;
   633→            align-items: center;
   634→            padding: 15px 20px;
   635→            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
   636→            color: white;
   637→            border-radius: 12px 12px 0 0;
   638→            position: sticky;
   639→            top: 0;
   640→            z-index: 10;
   641→        }
   642→
   643→        .quick-view-header h3 {
   644→            margin: 0;
   645→            font-size: 1.1em;
   646→        }
   647→
   648→        .quick-view-close {
   649→            background: rgba(255,255,255,0.2);
   650→            border: none;
   651→            color: white;
   652→            padding: 8px 16px;
   653→            border-radius: 6px;
   654→            cursor: pointer;
   655→            font-size: 0.9em;
   656→        }
   657→
   658→        .quick-view-close:hover {
   659→            background: rgba(255,255,255,0.3);
   660→        }
   661→
   662→        .quick-view-content {
   663→            padding: 20px;
   664→        }
   665→
   666→        .quick-view-meta {
   667→            display: flex;
   668→            gap: 20px;
   669→            margin-bottom: 15px;
   670→            padding-bottom: 15px;
   671→            border-bottom: 1px solid #e5e7eb;
   672→            flex-wrap: wrap;
   673→        }
   674→
   675→        .quick-view-meta-item {
   676→            font-size: 0.9em;
   677→        }
   678→
   679→        .quick-view-meta-item strong {
   680→            color: var(--accent-primary);
   681→        }
   682→
   683→        .quick-view-question {
   684→            background: #f0f9ff;
   685→            padding: 15px;
   686→            border-radius: 8px;
   687→            margin-bottom: 15px;
   688→            border-left: 4px solid #3b82f6;
   689→        }
   690→
   691→        .quick-view-response {
   692→            background: #f0fdf4;
   693→            padding: 15px;
   694→            border-radius: 8px;
   695→            border-left: 4px solid #22c55e;
   696→            white-space: pre-wrap;
   697→            line-height: 1.7;
   698→        }
   699→
   700→        /* Loading */
   701→        .loading-spinner {
   702→            display: inline-block;
   703→            width: 20px;
   704→            height: 20px;
   705→            border: 3px solid rgba(255,255,255,0.3);
   706→            border-radius: 50%;
   707→            border-top-color: white;
   708→            animation: spin 1s linear infinite;
   709→        }
   710→
   711→        @keyframes spin {
   712→            to { transform: rotate(360deg); }
   713→        }
   714→
   715→        .loading-overlay {
   716→            position: fixed;
   717→            top: 0;
   718→            left: 0;
   719→            right: 0;
   720→            bottom: 0;
   721→            background: rgba(0,0,0,0.5);
   722→            display: flex;
   723→            justify-content: center;
   724→            align-items: center;
   725→            z-index: 1000;
   726→            display: none;
   727→        }
   728→
   729→        .loading-overlay.active {
   730→            display: flex;
   731→        }
   732→
   733→        .loading-box {
   734→            background: white;
   735→            padding: 30px 50px;
   736→            border-radius: 12px;
   737→            text-align: center;
   738→        }
   739→
   740→        .loading-box .spinner {
   741→            width: 40px;
   742→            height: 40px;
   743→            border: 4px solid #e5e7eb;
   744→            border-top-color: var(--accent-primary);
   745→            border-radius: 50%;
   746→            animation: spin 1s linear infinite;
   747→            margin: 0 auto 15px;
   748→        }
   749→
   750→        /* Direction badge */
   751→        .badge-direction {
   752→            display: inline-block;
   753→            padding: 2px 8px;
   754→            border-radius: 4px;
   755→            font-size: 0.75em;
   756→            font-weight: 600;
   757→            text-transform: uppercase;
   758→        }
   759→
   760→        .badge-inbound {
   761→            background: #d1fae5;
   762→            color: #065f46;
   763→        }
   764→
   765→        .badge-outbound {
   766→            background: #dbeafe;
   767→            color: #1e40af;
   768→        }
   769→
   770→        /* Tabs for responses */
   771→        .response-tabs {
   772→            display: flex;
   773→            gap: 10px;
   774→            margin-bottom: 15px;
   775→            border-bottom: 2px solid var(--border-color);
   776→            padding-bottom: 10px;
   777→        }
   778→
   779→        .response-tab {
   780→            padding: 8px 16px;
   781→            background: none;
   782→            border: none;
   783→            cursor: pointer;
   784→            font-size: 0.9em;
   785→            color: var(--text-secondary);
   786→            border-bottom: 2px solid transparent;
   787→            margin-bottom: -12px;
   788→        }
   789→
   790→        .response-tab.active {
   791→            color: var(--accent-primary);
   792→            border-bottom-color: var(--accent-primary);
   793→            font-weight: 600;
   794→        }
   795→
   796→        .response-content {
   797→            display: none;
   798→        }
   799→
   800→        .response-content.active {
   801→            display: block;
   802→        }
   803→    </style>
   804→</head>
   805→<body>
   806→    <div class="page-container">
   807→        <!-- Header -->
   808→        <div class="page-header">
   809→            <div>
   810→                <h1><?= htmlspecialchars($threadSubject) ?></h1>
   811→                <div class="subtitle">
   812→                    <?= count($emails) ?> emails
   813→                    <?php if ($primaryContactName): ?>
   814→                        with <?= htmlspecialchars($primaryContactName) ?>
   815→                    <?php endif; ?>
   816→                    | Thread ID: <?= htmlspecialchars($threadId) ?>
   817→                </div>
   818→            </div>
   819→            <a href="index.php" class="back-link">Back to Dashboard</a>
   820→        </div>
   821→
   822→        <div class="main-grid">
   823→            <!-- Left Column: Email Thread -->
   824→            <div class="left-column">
   825→                <!-- Email Timeline -->
   826→                <div class="card">
   827→                    <div class="card-header">
   828→                        <h2>Email Conversation</h2>
   829→                        <span class="email-count"><?= count($emails) ?> emails</span>
   830→                    </div>
   831→                    <div class="email-timeline" id="email-timeline">
   832→                        <?php foreach ($emails as $index => $email):
   833→                            $senderEmail = strtolower($email['from_email'] ?? '');
   834→                            $senderName = $participantMap[$senderEmail] ?? 'Unknown';
   835→                            $isInbound = ($email['direction'] ?? '') === 'inbound';
   836→                            $body = $email['body_text'] ?? $email['body_html'] ?? '(No content)';
   837→                            // Truncate for display
   838→                            $displayBody = strlen($body) > 1500 ? substr($body, 0, 1500) . '...' : $body;
   839→                        ?>
   840→                        <div class="email-item <?= $isInbound ? 'inbound' : 'outbound' ?>">
   841→                            <div class="email-meta">
   842→                                <div>
   843→                                    <span class="sender-name"><?= htmlspecialchars($senderName) ?></span>
   844→                                    <span class="badge-direction <?= $isInbound ? 'badge-inbound' : 'badge-outbound' ?>">
   845→                                        <?= $isInbound ? 'Received' : 'Sent' ?>
   846→                                    </span>
   847→                                    <br>
   848→                                    <span class="sender-email"><?= htmlspecialchars($email['from_email'] ?? '') ?></span>
   849→                                </div>
   850→                                <span class="email-date"><?= date('M j, Y g:i A', strtotime($email['date'])) ?></span>
   851→                            </div>
   852→                            <div class="email-body"><?= htmlspecialchars($displayBody) ?></div>
   853→                        </div>
   854→                        <?php endforeach; ?>
   855→                    </div>
   856→                </div>
   857→
   858→                <!-- AI Response Display -->
   859→                <div class="card" id="ai-response-container" style="display: none;">
   860→                    <div class="card-header">
   861→                        <h2>AI Response</h2>
   862→                        <button class="btn btn-secondary" onclick="closeResponse()">Close</button>
   863→                    </div>
   864→                    <div class="response-tabs" id="response-tabs"></div>
   865→                    <div id="ai-responses-content"></div>
   866→                </div>
   867→
   868→                <!-- Saved Responses -->
   869→                <?php if (!empty($savedResponses)): ?>
   870→                <div class="card">
   871→                    <div class="card-header">
   872→                        <h2>Previous AI Analyses <span style="font-weight: normal; font-size: 0.85em; color: var(--text-secondary);">(<?= $totalSavedResponses ?> total)</span></h2>
   873→                    </div>
   874→                    <div id="saved-responses">
   875→                        <?php foreach ($savedResponses as $saved):
   876→                            // Determine what to display as the "question"
   877→                            $displayQuestion = $saved['question'] ?? 'General Analysis';
   878→                            $hasContext = !empty($saved['context']);
   879→                            $isDefaultQuestion = strpos($displayQuestion, 'Please analyze this email conversation') === 0;
   880→
   881→                            // If question is the default and user provided context, show context instead
   882→                            if ($isDefaultQuestion && $hasContext) {
   883→                                $displayQuestion = '[Context] ' . $saved['context'];
   884→                            } elseif ($hasContext && !$isDefaultQuestion) {
   885→                                // If both custom question and context exist, show question + indicator
   886→                                $displayQuestion = $displayQuestion . ' (+context)';
   887→                            }
   888→
   889→                            // Truncate to 200 chars instead of 100
   890→                            $displayQuestion = strlen($displayQuestion) > 200
   891→                                ? substr($displayQuestion, 0, 200) . '...'
   892→                                : $displayQuestion;
   893→
   894→                            // Get response excerpt for easier identification
   895→                            $responseText = $saved['response']['response'] ?? '';
   896→                            $responseExcerpt = strlen($responseText) > 120
   897→                                ? substr($responseText, 0, 120) . '...'
   898→                                : $responseText;
   899→                        ?>
   900→                        <div class="saved-response" id="saved-response-<?= $saved['_id'] ?>" data-id="<?= $saved['_id'] ?>">
   901→                            <div class="saved-response-header">
   902→                                <span class="saved-response-question">
   903→                                    <?= htmlspecialchars($displayQuestion) ?>
   904→                                </span>
   905→                                <span class="saved-response-date">
   906→                                    <?= date('M j, Y g:i A', strtotime($saved['created_at'] ?? 'now')) ?>
   907→                                </span>
   908→                            </div>
   909→                            <div class="saved-response-preview">
   910→                                <strong><?= htmlspecialchars($saved['provider'] ?? 'Unknown') ?></strong> /
   911→                                <?= htmlspecialchars($saved['model'] ?? 'Unknown') ?>
   912→                            </div>
   913→                            <?php if ($responseExcerpt): ?>
   914→                            <div class="saved-response-excerpt">
   915→                                <?= htmlspecialchars($responseExcerpt) ?>
   916→                            </div>
   917→                            <?php endif; ?>
   918→                            <div class="saved-response-actions">
   919→                                <button class="btn-view" onclick="event.stopPropagation(); quickViewResponse('<?= $saved['_id'] ?>')">
   920→                                    👁 Quick View
   921→                                </button>
   922→                                <button class="btn-expand" onclick="event.stopPropagation(); loadSavedResponse('<?= $saved['_id'] ?>')">
   923→                                    📄 Full View
   924→                                </button>
   925→                            </div>
   926→                        </div>
   927→                        <?php endforeach; ?>
   928→                    </div>
   929→                    <?php if ($totalSavedResponses > $savedResponsesLimit): ?>
   930→                    <div id="load-more-container" style="text-align: center; margin-top: 15px;">
   931→                        <button class="btn btn-secondary" id="load-more-btn" onclick="loadMoreResponses()"
   932→                                data-offset="<?= $savedResponsesLimit ?>"
   933→                                data-total="<?= $totalSavedResponses ?>">
   934→                            Load More (<?= $totalSavedResponses - $savedResponsesLimit ?> remaining)
   935→                        </button>
   936→                    </div>
   937→                    <?php endif; ?>
   938→                </div>
   939→                <?php endif; ?>
   940→            </div>
   941→
   942→            <!-- Right Column: AI Query Panel -->
   943→            <div class="right-column">
   944→                <!-- Additional Threads Selection -->
   945→                <?php if (!empty($otherThreads)): ?>
   946→                <div class="card">
   947→                    <div class="card-header">
   948→                        <h2>Include Other Threads</h2>
   949→                    </div>
   950→                    <p style="font-size: 0.9em; color: var(--text-secondary); margin-bottom: 15px;">
   951→                        Select additional threads from <?= htmlspecialchars($primaryContactName ?: 'this contact') ?> to include in the AI analysis:
   952→                    </p>
   953→                    <div class="thread-selection">
   954→                        <?php foreach (array_slice($otherThreads, 0, 10) as $thread): ?>
   955→                        <label class="thread-checkbox">
   956→                            <input type="checkbox" name="additional_threads[]" value="<?= htmlspecialchars($thread['thread_id']) ?>">
   957→                            <div class="thread-checkbox-content">
   958→                                <div class="thread-checkbox-subject"><?= htmlspecialchars($thread['subject'] ?? '(No Subject)') ?></div>
   959→                                <div class="thread-checkbox-meta">
   960→                                    <?= $thread['email_count'] ?? 0 ?> emails |
   961→                                    <?= date('M j, Y', strtotime($thread['last_date'] ?? 'now')) ?>
   962→                                </div>
   963→                            </div>
   964→                        </label>
   965→                        <?php endforeach; ?>
   966→                    </div>
   967→                </div>
   968→                <?php endif; ?>
   969→
   970→                <!-- AI Query Form -->
   971→                <div class="card">
   972→                    <div class="card-header">
   973→                        <h2>Ask AI</h2>
   974→                    </div>
   975→
   976→                    <!-- Provider Selection -->
   977→                    <div class="ai-form-section">
   978→                        <label>Select AI Provider</label>
   979→                        <div class="provider-grid" id="provider-grid">
   980→                            <!-- Loaded via JavaScript -->
   981→                            <p style="color: var(--text-secondary);">Loading providers...</p>
   982→                        </div>
   983→                    </div>
   984→
   985→                    <!-- Content Processing Mode -->
   986→                    <div class="ai-form-section">
   987→                        <label for="content-mode">Email Content Processing</label>
   988→                        <select id="content-mode" style="width: 100%;">
   989→                            <option value="full">Full Content (include all quoted replies)</option>
   990→                            <option value="stripped" selected>Stripped (remove quoted replies - saves tokens)</option>
   991→                            <option value="smart">Smart Deduplication (quotes only in last email)</option>
   992→                        </select>
   993→                        <p style="font-size: 0.8em; color: var(--text-secondary); margin-top: 5px;">
   994→                            <strong>Stripped:</strong> Removes ">" quoted lines and "On [date] wrote:" sections.<br>
   995→                            <strong>Smart:</strong> Keeps full context only in the last email to avoid redundancy.
   996→                        </p>
   997→                    </div>
   998→
   999→                    <!-- Question -->
  1000→                    <div class="ai-form-section">
  1001→                        <label for="ai-question">Your Question</label>
  1002→                        <textarea id="ai-question" placeholder="What would you like to know about this conversation?

Examples:
- What is the client's main concern?
- Summarize the key points
- Is there any deception detected?
- What should be my next steps?"></textarea>
  1003→                    </div>
  1004→
  1005→                    <!-- Additional Context -->
  1006→                    <div class="ai-form-section">
  1007→                        <label for="ai-context">Additional Context (Optional)</label>
  1008→                        <textarea id="ai-context" placeholder="Add any additional context the AI should know...

e.g., business background, relationship history, specific concerns..."></textarea>
  1009→                    </div>
  1010→
  1011→                    <!-- Submit Button -->
  1012→                    <button class="btn btn-primary" id="submit-ai-btn" onclick="submitToAI()" style="width: 100%;">
  1013→                        Send to AI
  1014→                    </button>
  1015→                </div>
  1016→            </div>
  1017→        </div>
  1018→    </div>
  1019→
  1020→    <!-- Loading Overlay -->
  1021→    <div class="loading-overlay" id="loading-overlay">
  1022→        <div class="loading-box">
  1023→            <div class="spinner"></div>
  1024→            <p id="loading-message">Analyzing with AI...</p>
  1025→        </div>
  1026→    </div>
  1027→
  1028→    <!-- Quick View Modal -->
  1029→    <div class="quick-view-overlay" id="quick-view-overlay" style="display: none;" onclick="closeQuickView(event)">
  1030→        <div class="quick-view-modal" onclick="event.stopPropagation()">
  1031→            <div class="quick-view-header">
  1032→                <h3 id="quick-view-title">AI Response</h3>
  1033→                <button class="quick-view-close" onclick="closeQuickView()">✕ Close (Esc)</button>
  1034→            </div>
  1035→            <div class="quick-view-content">
  1036→                <div class="quick-view-meta" id="quick-view-meta"></div>
  1037→                <div id="quick-view-question-section"></div>
  1038→                <div class="quick-view-response" id="quick-view-response"></div>
  1039→            </div>
  1040→        </div>
  1041→    </div>
  1042→
  1043→    <script>
  1044→        // Current thread data
  1045→        const currentThreadId = '<?= addslashes($threadId) ?>';
  1046→        const primaryContactId = <?= $primaryContactId ? $primaryContactId : 'null' ?>;
  1047→
  1048→        // Build email content for AI from PHP
  1049→        const emailContent = <?= json_encode(array_map(function($email) use ($participantMap) {
  1050→            $senderEmail = strtolower($email['from_email'] ?? '');
  1051→            $senderName = $participantMap[$senderEmail] ?? 'Unknown';
  1052→            return [
  1053→                'from' => $senderName,
  1054→                'from_email' => $email['from_email'] ?? '',
  1055→                'date' => $email['date'] ?? '',
  1056→                'direction' => $email['direction'] ?? '',
  1057→                'body' => $email['body_text'] ?? $email['body_html'] ?? ''
  1058→            ];
  1059→        }, $emails)) ?>;
  1060→
  1061→        // Provider data
  1062→        let providers = {};
  1063→        let selectedProvider = null;
  1064→        let selectedModel = null;
  1065→
  1066→        // ============================================
  1067→        // CONVERSATION MEMORY - ChatGPT-like history
  1068→        // ============================================
  1069→        // Conversation history - stores Q&A pairs for context
  1070→        let conversationHistory = [];
  1071→        const MAX_CONVERSATION_HISTORY = 20; // Maximum Q&A pairs to keep
  1072→
  1073→        // Load conversation history from sessionStorage (persists during page session)
  1074→        function loadConversationHistory() {
  1075→            const stored = sessionStorage.getItem(`conversation_${currentThreadId}`);
  1076→            if (stored) {
  1077→                try {
  1078→                    conversationHistory = JSON.parse(stored);
  1079→                    updateConversationDisplay();
  1080→                } catch (e) {
  1081→                    conversationHistory = [];
  1082→                }
  1083→            }
  1084→        }
  1085→
  1086→        // Save conversation history to sessionStorage
  1087→        function saveConversationHistory() {
  1088→            sessionStorage.setItem(`conversation_${currentThreadId}`, JSON.stringify(conversationHistory));
  1089→        }
  1090→
  1091→        // Add a Q&A pair to conversation history
  1092→        function addToConversation(question, answer, provider, model, context = '') {
  1093→            const entry = {
  1094→                timestamp: new Date().toISOString(),
  1095→                question: question,
  1096→                context: context,
  1097→                answer: answer,
  1098→                provider: provider,
  1099→                model: model
  1100→            };
  1101→
  1102→            conversationHistory.push(entry);
  1103→
  1104→            // Keep only the last MAX_CONVERSATION_HISTORY entries
  1105→            if (conversationHistory.length > MAX_CONVERSATION_HISTORY) {
  1106→                conversationHistory = conversationHistory.slice(-MAX_CONVERSATION_HISTORY);
  1107→            }
  1108→
  1109→            saveConversationHistory();
  1110→            updateConversationDisplay();
  1111→        }
  1112→
  1113→        // Clear conversation history
  1114→        function clearConversationHistory() {
  1115→            if (confirm('Clear all conversation history for this thread?')) {
  1116→                conversationHistory = [];
  1117→                saveConversationHistory();
  1118→                updateConversationDisplay();
  1119→            }
  1120→        }
  1121→
  1122→        // Build conversation context string for AI
  1123→        function buildConversationContext() {
  1124→            if (conversationHistory.length === 0) return '';
  1125→
  1126→            let context = '\n\n=== PREVIOUS CONVERSATION HISTORY ===\n';
  1127→            context += '(The user has asked previous questions about this email thread. Use this context for continuity.)\n\n';
  1128→
  1129→            conversationHistory.forEach((entry, index) => {
  1130→                context += `--- Exchange ${index + 1} (${new Date(entry.timestamp).toLocaleString()}) ---\n`;
  1131→                context += `USER QUESTION: ${entry.question}\n`;
  1132→                context += `AI RESPONSE (${entry.provider}/${entry.model}):\n${entry.answer}\n\n`;
  1133→            });
  1134→
  1135→            context += '=== END OF PREVIOUS CONVERSATION ===\n\n';
  1136→            context += 'Please consider the above conversation history when answering the new question. ';
  1137→            context += 'If the user refers to something discussed previously, use that context.\n\n';
  1138→
  1139→            return context;
  1140→        }
  1141→
  1142→        // Update the conversation history display in UI
  1143→        function updateConversationDisplay() {
  1144→            let historyContainer = document.getElementById('conversation-history');
  1145→
  1146→            if (conversationHistory.length === 0) {
  1147→                if (historyContainer) {
  1148→                    historyContainer.style.display = 'none';
  1149→                }
  1150→                return;
  1151→            }
  1152→
  1153→            if (!historyContainer) {
  1154→                // Create history container if it doesn't exist
  1155→                const aiFormCard = document.querySelector('.right-column .card:last-child');
  1156→                if (aiFormCard) {
  1157→                    historyContainer = document.createElement('div');
  1158→                    historyContainer.id = 'conversation-history';
  1159→                    historyContainer.className = 'card';
  1160→                    historyContainer.style.marginTop = '20px';
  1161→                    aiFormCard.after(historyContainer);
  1162→                }
  1163→            }
  1164→
  1165→            if (historyContainer) {
  1166→                historyContainer.style.display = 'block';
  1167→                historyContainer.innerHTML = `
  1168→                    <div class="card-header">
  1169→                        <h2>💬 Conversation History (${conversationHistory.length})</h2>
  1170→                        <button class="btn btn-secondary" onclick="clearConversationHistory()" style="padding: 6px 12px; font-size: 0.85em;">
  1171→                            Clear History
  1172→                        </button>
  1173→                    </div>
  1174→                    <p style="font-size: 0.85em; color: var(--text-secondary); margin-bottom: 10px;">
  1175→                        Previous Q&A pairs are included as context for new questions (like ChatGPT memory).
  1176→                    </p>
  1177→                    <div style="max-height: 300px; overflow-y: auto;">
  1178→                        ${conversationHistory.slice().reverse().map((entry, i) => {
  1179→                            // Determine display text - show context if question is default
  1180→                            const isDefaultQuestion = entry.question && entry.question.startsWith('Please analyze this email conversation');
  1181→                            const hasContext = entry.context && entry.context.length > 0;
  1182→                            let displayQ = entry.question || 'General Analysis';
  1183→
  1184→                            if (isDefaultQuestion && hasContext) {
  1185→                                displayQ = '[Context] ' + entry.context;
  1186→                            } else if (hasContext) {
  1187→                                displayQ = entry.question + ' (+context)';
  1188→                            }
  1189→
  1190→                            return `
  1191→                            <div style="background: ${i % 2 === 0 ? '#f9fafb' : '#fff'}; padding: 10px; border-radius: 6px; margin-bottom: 8px; border-left: 3px solid var(--accent-primary);">
  1192→                                <div style="font-size: 0.8em; color: var(--text-secondary); margin-bottom: 5px;">
  1193→                                    ${new Date(entry.timestamp).toLocaleString()} | ${entry.provider}/${entry.model}
  1194→                                </div>
  1195→                                <div style="font-weight: 600; color: var(--accent-primary); margin-bottom: 5px;">
  1196→                                    Q: ${escapeHtml(displayQ.substring(0, 200))}${displayQ.length > 200 ? '...' : ''}
  1197→                                </div>
  1198→                                <div style="font-size: 0.9em; color: var(--text-primary); max-height: 60px; overflow: hidden;">
  1199→                                    A: ${escapeHtml(entry.answer.substring(0, 150))}${entry.answer.length > 150 ? '...' : ''}
  1200→                                </div>
  1201→                            </div>`;
  1202→                        }).join('')}
  1203→                    </div>
  1204→                `;
  1205→            }
  1206→        }
  1207→
  1208→        // Load providers on page load
  1209→        document.addEventListener('DOMContentLoaded', function() {
  1210→            loadProviders();
  1211→            loadConversationHistory(); // Load conversation history on page load
  1212→        });
  1213→
  1214→        // Load AI providers from API
  1215→        async function loadProviders() {
  1216→            try {
  1217→                const response = await fetch('../aiapi/api_opus/api/query.php?action=providers');
  1218→                const data = await response.json();
  1219→
  1220→                if (data.success) {
  1221→                    providers = data.providers;
  1222→                    renderProviders();
  1223→                }
  1224→            } catch (error) {
  1225→                console.error('Failed to load providers:', error);
  1226→                document.getElementById('provider-grid').innerHTML =
  1227→                    '<p style="color: #ef4444;">Failed to load AI providers</p>';
  1228→            }
  1229→        }
  1230→
  1231→        // Render provider selection (multi-select with checkboxes)
  1232→        function renderProviders() {
  1233→            const container = document.getElementById('provider-grid');
  1234→            container.innerHTML = '';
  1235→
  1236→            // Add select all / deselect all buttons
  1237→            const buttonsDiv = document.createElement('div');
  1238→            buttonsDiv.style.cssText = 'grid-column: 1 / -1; display: flex; gap: 10px; margin-bottom: 10px;';
  1239→            buttonsDiv.innerHTML = `
  1240→                <button type="button" class="btn btn-small" onclick="selectAllProviders()">Select All</button>
  1241→                <button type="button" class="btn btn-small" onclick="deselectAllProviders()">Deselect All</button>
  1242→                <span style="margin-left: auto; color: var(--text-secondary); font-size: 0.85em;" id="selected-count">0 selected</span>
  1243→            `;
  1244→            container.appendChild(buttonsDiv);
  1245→
  1246→            for (const [key, provider] of Object.entries(providers)) {
  1247→                if (!provider.has_key) continue;
  1248→
  1249→                const div = document.createElement('div');
  1250→                div.className = 'provider-option';
  1251→                div.dataset.provider = key;
  1252→                div.onclick = (e) => {
  1253→                    if (e.target.tagName !== 'SELECT' && e.target.tagName !== 'OPTION') {
  1254→                        toggleProvider(key);
  1255→                    }
  1256→                };
  1257→
  1258→                let modelsHtml = '<select class="model-select" id="model_' + key + '" onclick="event.stopPropagation()">';
  1259→                for (const [modelKey, modelName] of Object.entries(provider.models)) {
  1260→                    const selected = modelKey === provider.default_model ? 'selected' : '';
  1261→                    modelsHtml += `<option value="${modelKey}" ${selected}>${modelName}</option>`;
  1262→                }
  1263→                modelsHtml += '</select>';
  1264→
  1265→                div.innerHTML = `
  1266→                    <input type="checkbox" name="providers[]" value="${key}" id="provider_${key}" onclick="event.stopPropagation(); toggleProvider('${key}', this.checked)">
  1267→                    <div style="flex: 1;">
  1268→                        <div class="provider-name">${provider.name}</div>
  1269→                        ${modelsHtml}
  1270→                    </div>
  1271→                `;
  1272→
  1273→                container.appendChild(div);
  1274→            }
  1275→
  1276→            // Select Claude by default if available
  1277→            if (providers['claude']?.has_key) {
  1278→                toggleProvider('claude', true);
  1279→            } else {
  1280→                // Select first available provider
  1281→                const firstProvider = Object.keys(providers).find(k => providers[k].has_key);
  1282→                if (firstProvider) {
  1283→                    toggleProvider(firstProvider, true);
  1284→                }
  1285→            }
  1286→        }
  1287→
  1288→        // Toggle a provider selection
  1289→        function toggleProvider(providerKey, forceState = null) {
  1290→            const checkbox = document.getElementById('provider_' + providerKey);
  1291→            const option = document.querySelector(`.provider-option[data-provider="${providerKey}"]`);
  1292→
  1293→            if (!checkbox || !option) return;
  1294→
  1295→            // Determine new state
  1296→            const newState = forceState !== null ? forceState : !checkbox.checked;
  1297→            checkbox.checked = newState;
  1298→            option.classList.toggle('selected', newState);
  1299→
  1300→            updateSelectedCount();
  1301→        }
  1302→
  1303→        // Select all providers
  1304→        function selectAllProviders() {
  1305→            for (const key of Object.keys(providers)) {
  1306→                if (providers[key].has_key) {
  1307→                    toggleProvider(key, true);
  1308→                }
  1309→            }
  1310→        }
  1311→
  1312→        // Deselect all providers
  1313→        function deselectAllProviders() {
  1314→            for (const key of Object.keys(providers)) {
  1315→                toggleProvider(key, false);
  1316→            }
  1317→        }
  1318→
  1319→        // Update selected count display
  1320→        function updateSelectedCount() {
  1321→            const count = document.querySelectorAll('input[name="providers[]"]:checked').length;
  1322→            const countEl = document.getElementById('selected-count');
  1323→            if (countEl) {
  1324→                countEl.textContent = count + ' selected';
  1325→                countEl.style.color = count === 0 ? '#ef4444' : 'var(--text-secondary)';
  1326→            }
  1327→        }
  1328→
  1329→        // Get selected providers
  1330→        function getSelectedProviders() {
  1331→            const checkboxes = document.querySelectorAll('input[name="providers[]"]:checked');
  1332→            return Array.from(checkboxes).map(cb => cb.value);
  1333→        }
  1334→
  1335→        // Get selected additional threads
  1336→        function getSelectedThreads() {
  1337→            const checkboxes = document.querySelectorAll('input[name="additional_threads[]"]:checked');
  1338→            return Array.from(checkboxes).map(cb => cb.value);
  1339→        }
  1340→
  1341→        /**
  1342→         * Strip quoted content from email body
  1343→         * Removes:
  1344→         * - Lines starting with ">" (quoted text)
  1345→         * - "On [date] [name] wrote:" patterns
  1346→         * - "From: ... Sent: ... To: ... Subject:" forwarded headers
  1347→         * - Lines starting with "-----Original Message-----"
  1348→         */
  1349→        function stripQuotedContent(body) {
  1350→            if (!body) return '';
  1351→
  1352→            let lines = body.split('\n');
  1353→            let result = [];
  1354→            let inQuoteBlock = false;
  1355→            let consecutiveEmptyLines = 0;
  1356→
  1357→            for (let i = 0; i < lines.length; i++) {
  1358→                let line = lines[i];
  1359→                let trimmedLine = line.trim();
  1360→
  1361→                // Detect start of quoted section
  1362→                if (/^On\s+.+wrote:\s*$/i.test(trimmedLine) ||
  1363→                    /^On\s+\d+.+at\s+\d+.+wrote:\s*$/i.test(trimmedLine) ||
  1364→                    /^-{3,}\s*Original Message\s*-{3,}/i.test(trimmedLine) ||
  1365→                    /^-{3,}\s*Forwarded message\s*-{3,}/i.test(trimmedLine) ||
  1366→                    /^From:\s*.+\s+Sent:\s*.+\s+To:/i.test(trimmedLine)) {
  1367→                    inQuoteBlock = true;
  1368→                    continue;
  1369→                }
  1370→
  1371→                // Skip quoted lines (starting with >)
  1372→                if (trimmedLine.startsWith('>')) {
  1373→                    inQuoteBlock = true;
  1374→                    continue;
  1375→                }
  1376→
  1377→                // If we were in a quote block and hit non-quoted content, exit quote mode
  1378→                if (inQuoteBlock && trimmedLine && !trimmedLine.startsWith('>')) {
  1379→                    // Check if this is still part of quote (continuation)
  1380→                    if (i + 1 < lines.length && lines[i + 1].trim().startsWith('>')) {
  1381→                        continue; // Skip this line too
  1382→                    }
  1383→                    inQuoteBlock = false;
  1384→                }
  1385→
  1386→                // Skip if still in quote block
  1387→                if (inQuoteBlock) continue;
  1388→
  1389→                // Handle consecutive empty lines (max 2)
  1390→                if (!trimmedLine) {
  1391→                    consecutiveEmptyLines++;
  1392→                    if (consecutiveEmptyLines <= 2) {
  1393→                        result.push('');
  1394→                    }
  1395→                    continue;
  1396→                }
  1397→
  1398→                consecutiveEmptyLines = 0;
  1399→                result.push(line);
  1400→            }
  1401→
  1402→            // Trim trailing empty lines
  1403→            while (result.length > 0 && !result[result.length - 1].trim()) {
  1404→                result.pop();
  1405→            }
  1406→
  1407→            return result.join('\n').trim();
  1408→        }
  1409→
  1410→        /**
  1411→         * Build email content string for AI
  1412→         * Supports different processing modes:
  1413→         * - full: Include all content as-is
  1414→         * - stripped: Remove quoted replies from all emails
  1415→         * - smart: Keep quotes only in the last email
  1416→         */
  1417→        function buildEmailContent() {
  1418→            const mode = document.getElementById('content-mode').value;
  1419→            let content = 'EMAIL THREAD CONVERSATION:\n';
  1420→            content += `(Content mode: ${mode})\n\n`;
  1421→
  1422→            const totalEmails = emailContent.length;
  1423→
  1424→            emailContent.forEach((email, index) => {
  1425→                content += `--- Email ${index + 1} of ${totalEmails} ---\n`;
  1426→                content += `From: ${email.from} <${email.from_email}>\n`;
  1427→                content += `Date: ${email.date}\n`;
  1428→                content += `Direction: ${email.direction}\n\n`;
  1429→
  1430→                let emailBody = email.body;
  1431→
  1432→                if (mode === 'stripped') {
  1433→                    // Strip quoted content from all emails
  1434→                    emailBody = stripQuotedContent(emailBody);
  1435→                    if (!emailBody.trim()) {
  1436→                        emailBody = '(Only quoted content - no new text in this email)';
  1437→                    }
  1438→                } else if (mode === 'smart') {
  1439→                    // Strip quotes from all emails except the last one
  1440→                    if (index < totalEmails - 1) {
  1441→                        emailBody = stripQuotedContent(emailBody);
  1442→                        if (!emailBody.trim()) {
  1443→                            emailBody = '(Only quoted content - no new text in this email)';
  1444→                        }
  1445→                    }
  1446→                    // Last email keeps full content for context
  1447→                }
  1448→                // mode === 'full' keeps everything as-is
  1449→
  1450→                content += emailBody + '\n\n';
  1451→            });
  1452→
  1453→            return content;
  1454→        }
  1455→
  1456→        /**
  1457→         * Process additional thread content with the selected mode
  1458→         */
  1459→        function processAdditionalThreadContent(emails, mode) {
  1460→            let content = '';
  1461→            const totalEmails = emails.length;
  1462→
  1463→            emails.forEach((email, idx) => {
  1464→                const senderName = email.from_name || email.from_email || 'Unknown';
  1465→                content += `Email ${idx + 1} from ${senderName}:\n`;
  1466→
  1467→                let emailBody = email.body_text || email.body_html || '';
  1468→
  1469→                if (mode === 'stripped') {
  1470→                    emailBody = stripQuotedContent(emailBody);
  1471→                    if (!emailBody.trim()) {
  1472→                        emailBody = '(Only quoted content)';
  1473→                    }
  1474→                } else if (mode === 'smart' && idx < totalEmails - 1) {
  1475→                    emailBody = stripQuotedContent(emailBody);
  1476→                    if (!emailBody.trim()) {
  1477→                        emailBody = '(Only quoted content)';
  1478→                    }
  1479→                }
  1480→
  1481→                content += emailBody + '\n\n';
  1482→            });
  1483→
  1484→            return content;
  1485→        }
  1486→
  1487→        // Submit to AI
  1488→        async function submitToAI() {
  1489→            const selectedProvidersList = getSelectedProviders();
  1490→
  1491→            if (selectedProvidersList.length === 0) {
  1492→                alert('Please select at least one AI provider');
  1493→                return;
  1494→            }
  1495→
  1496→            const question = document.getElementById('ai-question').value.trim();
  1497→            const context = document.getElementById('ai-context').value.trim();
  1498→            const contentMode = document.getElementById('content-mode').value;
  1499→            const additionalThreads = getSelectedThreads();
  1500→
  1501→            // Build models map for each selected provider
  1502→            const modelsMap = {};
  1503→            selectedProvidersList.forEach(provider => {
  1504→                const modelSelect = document.getElementById('model_' + provider);
  1505→                modelsMap[provider] = modelSelect ? modelSelect.value : '';
  1506→            });
  1507→
  1508→            // Show loading
  1509→            document.getElementById('loading-overlay').classList.add('active');
  1510→            document.getElementById('submit-ai-btn').disabled = true;
  1511→
  1512→            try {
  1513→                // Build the full content
  1514→                let fullContent = buildEmailContent();
  1515→
  1516→                // ADD CONVERSATION HISTORY FOR CONTEXT (ChatGPT-like memory)
  1517→                const conversationContext = buildConversationContext();
  1518→                if (conversationContext) {
  1519→                    fullContent += conversationContext;
  1520→                    console.log('Including conversation history:', conversationHistory.length, 'previous exchanges');
  1521→                }
  1522→
  1523→                // Add question if provided
  1524→                const actualQuestion = question || 'Please analyze this email conversation and provide insights on:\n1. Key points and summary\n2. Sentiment and tone analysis\n3. Any potential concerns or red flags\n4. Recommended next steps';
  1525→
  1526→                if (question) {
  1527→                    fullContent += '\n\nCURRENT USER QUESTION:\n' + question;
  1528→                } else {
  1529→                    fullContent += '\n\n' + actualQuestion;
  1530→                }
  1531→
  1532→                // Add context if provided
  1533→                if (context) {
  1534→                    fullContent += '\n\nADDITIONAL CONTEXT:\n' + context;
  1535→                }
  1536→
  1537→                // Fetch additional thread content if selected
  1538→                if (additionalThreads.length > 0) {
  1539→                    document.getElementById('loading-message').textContent = 'Loading additional threads...';
  1540→
  1541→                    for (const threadId of additionalThreads) {
  1542→                        const threadData = await fetch(`api.php?action=thread&thread_id=${threadId}`);
  1543→                        const thread = await threadData.json();
  1544→
  1545→                        if (thread.emails && thread.emails.length > 0) {
  1546→                            fullContent += '\n\n--- ADDITIONAL THREAD ---\n';
  1547→                            fullContent += 'Subject: ' + (thread.emails[0].subject || '(No Subject)') + '\n\n';
  1548→                            fullContent += processAdditionalThreadContent(thread.emails, contentMode);
  1549→                        }
  1550→                    }
  1551→                }
  1552→
  1553→                // Log what's being sent
  1554→                console.log('=== AI REQUEST LOG ===');
  1555→                console.log('Providers:', selectedProvidersList);
  1556→                console.log('Models:', modelsMap);
  1557→                console.log('Content Mode:', contentMode);
  1558→                console.log('Conversation History Entries:', conversationHistory.length);
  1559→                console.log('Content Length:', fullContent.length, 'characters');
  1560→                console.log('Estimated Tokens:', Math.ceil(fullContent.length / 4));
  1561→                console.log('Full Content Preview (first 500 chars):', fullContent.substring(0, 500));
  1562→                console.log('======================');
  1563→
  1564→                document.getElementById('loading-message').textContent = `Analyzing with ${selectedProvidersList.length} AI provider(s)...`;
  1565→
  1566→                // Build request body with all selected providers and their models
  1567→                const requestBody = {
  1568→                    user_content: fullContent,
  1569→                    providers: selectedProvidersList
  1570→                };
  1571→
  1572→                // Add model for each provider
  1573→                for (const [provider, model] of Object.entries(modelsMap)) {
  1574→                    requestBody['model_' + provider] = model;
  1575→                }
  1576→
  1577→                // Send to AI API
  1578→                const response = await fetch('../aiapi/api_opus/api/query.php', {
  1579→                    method: 'POST',
  1580→                    headers: { 'Content-Type': 'application/json' },
  1581→                    body: JSON.stringify(requestBody)
  1582→                });
  1583→
  1584→                const data = await response.json();
  1585→
  1586→                // Log response
  1587→                console.log('=== AI RESPONSE LOG ===');
  1588→                console.log('Success:', data.success);
  1589→                console.log('Query ID:', data.query_id);
  1590→                console.log('Total Cost:', data.total_cost);
  1591→                console.log('Response Keys:', Object.keys(data.responses || {}));
  1592→                console.log('=======================');
  1593→
  1594→                if (data.success) {
  1595→                    // Track if we've added to conversation history (only add once)
  1596→                    let addedToConversation = false;
  1597→                    let firstSuccessfulProvider = null;
  1598→                    let firstSuccessfulResponse = null;
  1599→
  1600→                    // Save to MongoDB for each provider
  1601→                    for (const provider of selectedProvidersList) {
  1602→                        const providerResponse = data.responses[provider + '_response'];
  1603→                        if (providerResponse && providerResponse.success) {
  1604→                            // Track first successful response for conversation history
  1605→                            if (!firstSuccessfulProvider) {
  1606→                                firstSuccessfulProvider = provider;
  1607→                                firstSuccessfulResponse = providerResponse;
  1608→                            }
  1609→
  1610→                            // Save to MongoDB via our API
  1611→                            await saveAIResponse({
  1612→                                thread_ids: [currentThreadId, ...additionalThreads],
  1613→                                contact_id: primaryContactId,
  1614→                                question: actualQuestion,
  1615→                                context: context,
  1616→                                content_mode: contentMode,
  1617→                                content_sent: fullContent, // Log what was sent
  1618→                                content_length: fullContent.length,
  1619→                                estimated_tokens: Math.ceil(fullContent.length / 4),
  1620→                                provider: provider,
  1621→                                model: modelsMap[provider],
  1622→                                query_id: data.query_id,
  1623→                                response: providerResponse,
  1624→                                total_cost: providerResponse.cost || 0,
  1625→                                all_providers: selectedProvidersList,
  1626→                                conversation_history_count: conversationHistory.length
  1627→                            });
  1628→                        }
  1629→                    }
  1630→
  1631→                    // ADD TO CONVERSATION HISTORY (first successful response)
  1632→                    // This creates the ChatGPT-like memory effect
  1633→                    if (firstSuccessfulProvider && firstSuccessfulResponse && firstSuccessfulResponse.response) {
  1634→                        addToConversation(
  1635→                            actualQuestion,
  1636→                            firstSuccessfulResponse.response,
  1637→                            firstSuccessfulProvider,
  1638→                            modelsMap[firstSuccessfulProvider],
  1639→                            context  // Pass context to conversation history
  1640→                        );
  1641→                        console.log('Added to conversation history:', firstSuccessfulProvider);
  1642→                    }
  1643→
  1644→                    // Clear the question field for next question
  1645→                    document.getElementById('ai-question').value = '';
  1646→
  1647→                    // Display response
  1648→                    displayAIResponse(data);
  1649→                } else {
  1650→                    alert('AI request failed: ' + (data.error || 'Unknown error'));
  1651→                }
  1652→            } catch (error) {
  1653→                console.error('AI request error:', error);
  1654→                alert('Error: ' + error.message);
  1655→            } finally {
  1656→                document.getElementById('loading-overlay').classList.remove('active');
  1657→                document.getElementById('submit-ai-btn').disabled = false;
  1658→            }
  1659→        }
  1660→
  1661→        // Save AI response to MongoDB
  1662→        async function saveAIResponse(responseData) {
  1663→            try {
  1664→                await fetch('api.php?action=save_ai_response', {
  1665→                    method: 'POST',
  1666→                    headers: { 'Content-Type': 'application/json' },
  1667→                    body: JSON.stringify(responseData)
  1668→                });
  1669→            } catch (error) {
  1670→                console.error('Failed to save response:', error);
  1671→            }
  1672→        }
  1673→
  1674→        // Display AI response
  1675→        function displayAIResponse(data) {
  1676→            const container = document.getElementById('ai-response-container');
  1677→            const tabsContainer = document.getElementById('response-tabs');
  1678→            const contentContainer = document.getElementById('ai-responses-content');
  1679→
  1680→            container.style.display = 'block';
  1681→            tabsContainer.innerHTML = '';
  1682→            contentContainer.innerHTML = '';
  1683→
  1684→            let tabIndex = 0;
  1685→            for (const [key, response] of Object.entries(data.responses)) {
  1686→                const providerName = key.replace('_response', '');
  1687→                const providerConfig = providers[providerName] || { name: providerName };
  1688→
  1689→                // Create tab
  1690→                const tab = document.createElement('button');
  1691→                tab.className = 'response-tab' + (tabIndex === 0 ? ' active' : '');
  1692→                tab.textContent = providerConfig.name;
  1693→                tab.onclick = () => switchResponseTab(tabIndex);
  1694→                tab.dataset.index = tabIndex;
  1695→                tabsContainer.appendChild(tab);
  1696→
  1697→                // Create content
  1698→                const content = document.createElement('div');
  1699→                content.className = 'response-content' + (tabIndex === 0 ? ' active' : '');
  1700→                content.id = 'response-tab-' + tabIndex;
  1701→
  1702→                if (response.success) {
  1703→                    content.innerHTML = `
  1704→                        <div class="ai-response-card">
  1705→                            <div class="ai-response-header">
  1706→                                <span class="ai-response-provider">${providerConfig.name}</span>
  1707→                                <span class="ai-response-meta">
  1708→                                    Model: ${response.model || 'Unknown'} |
  1709→                                    Time: ${response.request_time?.toFixed(2) || '?'}s |
  1710→                                    Cost: $${response.cost?.toFixed(6) || '0'}
  1711→                                </span>
  1712→                            </div>
  1713→                            <div class="ai-response-content">${escapeHtml(response.response)}</div>
  1714→                        </div>
  1715→                    `;
  1716→                } else {
  1717→                    content.innerHTML = `
  1718→                        <div style="background: #fef2f2; border: 1px solid #ef4444; padding: 15px; border-radius: 8px;">
  1719→                            <strong style="color: #dc2626;">Error:</strong>
  1720→                            <p style="margin: 5px 0 0; color: #991b1b;">${escapeHtml(response.error || 'Unknown error')}</p>
  1721→                        </div>
  1722→                    `;
  1723→                }
  1724→
  1725→                contentContainer.appendChild(content);
  1726→                tabIndex++;
  1727→            }
  1728→
  1729→            // Scroll to response
  1730→            container.scrollIntoView({ behavior: 'smooth' });
  1731→        }
  1732→
  1733→        // Switch response tabs - scoped to response container only
  1734→        function switchResponseTab(index) {
  1735→            const tabsContainer = document.getElementById('response-tabs');
  1736→            const contentContainer = document.getElementById('ai-responses-content');
  1737→
  1738→            if (!tabsContainer || !contentContainer) return;
  1739→
  1740→            // Only target tabs within our container
  1741→            tabsContainer.querySelectorAll('.response-tab').forEach(tab => {
  1742→                const tabIndex = parseInt(tab.dataset.index);
  1743→                tab.classList.remove('active');
  1744→                if (tabIndex === index) {
  1745→                    tab.classList.add('active');
  1746→                }
  1747→            });
  1748→
  1749→            // Only target content within our container
  1750→            contentContainer.querySelectorAll('.response-content').forEach((content, i) => {
  1751→                content.classList.remove('active');
  1752→                if (i === index) {
  1753→                    content.classList.add('active');
  1754→                }
  1755→            });
  1756→        }
  1757→
  1758→        // Close response
  1759→        function closeResponse() {
  1760→            document.getElementById('ai-response-container').style.display = 'none';
  1761→        }
  1762→
  1763→        // Mark a saved response row as last viewed
  1764→        function markAsLastViewed(responseId) {
  1765→            // Remove last-viewed from all rows
  1766→            document.querySelectorAll('.saved-response.last-viewed').forEach(el => {
  1767→                el.classList.remove('last-viewed');
  1768→            });
  1769→            // Add to the current row
  1770→            const row = document.getElementById('saved-response-' + responseId);
  1771→            if (row) {
  1772→                row.classList.add('last-viewed');
  1773→            }
  1774→        }
  1775→
  1776→        // Load saved response
  1777→        async function loadSavedResponse(responseId) {
  1778→            try {
  1779→                // Mark this row as last viewed
  1780→                markAsLastViewed(responseId);
  1781→
  1782→                document.getElementById('loading-overlay').classList.add('active');
  1783→                document.getElementById('loading-message').textContent = 'Loading saved response...';
  1784→
  1785→                const response = await fetch(`api.php?action=get_ai_response&id=${responseId}`);
  1786→                const data = await response.json();
  1787→
  1788→                if (data.success && data.response) {
  1789→                    const saved = data.response;
  1790→
  1791→                    // Display it
  1792→                    const container = document.getElementById('ai-response-container');
  1793→                    const tabsContainer = document.getElementById('response-tabs');
  1794→                    const contentContainer = document.getElementById('ai-responses-content');
  1795→
  1796→                    container.style.display = 'block';
  1797→                    tabsContainer.innerHTML = `<button class="response-tab active">${saved.provider}</button>`;
  1798→
  1799→                    const aiResponse = saved.response || {};
  1800→
  1801→                    // Determine how to display question/context
  1802→                    const isDefaultQuestion = saved.question && saved.question.startsWith('Please analyze this email conversation');
  1803→                    const hasContext = saved.context && saved.context.length > 0;
  1804→
  1805→                    let questionHtml = '';
  1806→                    if (isDefaultQuestion && hasContext) {
  1807→                        // Show context as the main input if question was default
  1808→                        questionHtml = `
  1809→                            <p><strong>User Input (Context):</strong></p>
  1810→                            <p style="background: #f5f5f5; padding: 10px; border-radius: 6px; white-space: pre-wrap;">${escapeHtml(saved.context)}</p>
  1811→                            <p style="font-size: 0.85em; color: #666;"><em>Default question was used for analysis</em></p>
  1812→                        `;
  1813→                    } else if (hasContext) {
  1814→                        // Show both question and context
  1815→                        questionHtml = `
  1816→                            <p><strong>Question:</strong> ${escapeHtml(saved.question)}</p>
  1817→                            <p><strong>Additional Context:</strong></p>
  1818→                            <p style="background: #f5f5f5; padding: 10px; border-radius: 6px; white-space: pre-wrap;">${escapeHtml(saved.context)}</p>
  1819→                        `;
  1820→                    } else {
  1821→                        // Just show question
  1822→                        questionHtml = `<p><strong>Question:</strong> ${escapeHtml(saved.question)}</p>`;
  1823→                    }
  1824→
  1825→                    contentContainer.innerHTML = `
  1826→                        <div class="response-content active">
  1827→                            <div class="ai-response-card">
  1828→                                <div class="ai-response-header">
  1829→                                    <span class="ai-response-provider">${saved.provider} - ${saved.model}</span>
  1830→                                    <span class="ai-response-meta">Saved: ${saved.created_at}</span>
  1831→                                </div>
  1832→                                ${questionHtml}
  1833→                                <hr style="margin: 15px 0; border: none; border-top: 1px solid #e0e0e0;">
  1834→                                <div class="ai-response-content">${escapeHtml(aiResponse.response || 'No response content')}</div>
  1835→                            </div>
  1836→                        </div>
  1837→                    `;
  1838→
  1839→                    container.scrollIntoView({ behavior: 'smooth' });
  1840→                }
  1841→            } catch (error) {
  1842→                console.error('Failed to load saved response:', error);
  1843→                alert('Failed to load saved response');
  1844→            } finally {
  1845→                document.getElementById('loading-overlay').classList.remove('active');
  1846→            }
  1847→        }
  1848→
  1849→        // Quick view response in modal (no page scroll)
  1850→        async function quickViewResponse(responseId) {
  1851→            try {
  1852→                // Mark this row as last viewed
  1853→                markAsLastViewed(responseId);
  1854→
  1855→                const overlay = document.getElementById('quick-view-overlay');
  1856→                overlay.style.display = 'flex';
  1857→                document.getElementById('quick-view-response').textContent = 'Loading...';
  1858→                document.getElementById('quick-view-meta').innerHTML = '';
  1859→                document.getElementById('quick-view-question-section').innerHTML = '';
  1860→
  1861→                const response = await fetch(`api.php?action=get_ai_response&id=${responseId}`);
  1862→                const data = await response.json();
  1863→
  1864→                if (data.success && data.response) {
  1865→                    const saved = data.response;
  1866→                    const aiResponse = saved.response || {};
  1867→
  1868→                    // Update title
  1869→                    document.getElementById('quick-view-title').textContent = `${saved.provider} / ${saved.model}`;
  1870→
  1871→                    // Update meta
  1872→                    document.getElementById('quick-view-meta').innerHTML = `
  1873→                        <div class="quick-view-meta-item"><strong>Provider:</strong> ${escapeHtml(saved.provider)}</div>
  1874→                        <div class="quick-view-meta-item"><strong>Model:</strong> ${escapeHtml(saved.model)}</div>
  1875→                        <div class="quick-view-meta-item"><strong>Date:</strong> ${escapeHtml(saved.created_at)}</div>
  1876→                        <div class="quick-view-meta-item"><strong>Cost:</strong> $${(saved.total_cost || 0).toFixed(6)}</div>
  1877→                    `;
  1878→
  1879→                    // Update question/context section
  1880→                    const isDefaultQuestion = saved.question && saved.question.startsWith('Please analyze this email conversation');
  1881→                    const hasContext = saved.context && saved.context.length > 0;
  1882→
  1883→                    let questionHtml = '';
  1884→                    if (isDefaultQuestion && hasContext) {
  1885→                        questionHtml = `
  1886→                            <div class="quick-view-question">
  1887→                                <strong>User Context:</strong><br>
  1888→                                ${escapeHtml(saved.context)}
  1889→                                <div style="font-size: 0.85em; color: #666; margin-top: 8px;"><em>Default analysis question was used</em></div>
  1890→                            </div>
  1891→                        `;
  1892→                    } else if (hasContext) {
  1893→                        questionHtml = `
  1894→                            <div class="quick-view-question">
  1895→                                <strong>Question:</strong> ${escapeHtml(saved.question)}<br><br>
  1896→                                <strong>Context:</strong> ${escapeHtml(saved.context)}
  1897→                            </div>
  1898→                        `;
  1899→                    } else {
  1900→                        questionHtml = `
  1901→                            <div class="quick-view-question">
  1902→                                <strong>Question:</strong> ${escapeHtml(saved.question)}
  1903→                            </div>
  1904→                        `;
  1905→                    }
  1906→                    document.getElementById('quick-view-question-section').innerHTML = questionHtml;
  1907→
  1908→                    // Update response
  1909→                    document.getElementById('quick-view-response').textContent = aiResponse.response || 'No response content';
  1910→                } else {
  1911→                    document.getElementById('quick-view-response').textContent = 'Error loading response';
  1912→                }
  1913→            } catch (error) {
  1914→                console.error('Failed to quick view response:', error);
  1915→                document.getElementById('quick-view-response').textContent = 'Error: ' + error.message;
  1916→            }
  1917→        }
  1918→
  1919→        // Close quick view modal
  1920→        function closeQuickView(event) {
  1921→            if (event && event.target !== event.currentTarget) return;
  1922→            document.getElementById('quick-view-overlay').style.display = 'none';
  1923→        }
  1924→
  1925→        // Close quick view on Escape key
  1926→        document.addEventListener('keydown', function(e) {
  1927→            if (e.key === 'Escape') {
  1928→                closeQuickView();
  1929→            }
  1930→        });
  1931→
  1932→        // Load more saved responses
  1933→        async function loadMoreResponses() {
  1934→            const btn = document.getElementById('load-more-btn');
  1935→            if (!btn) return;
  1936→
  1937→            const currentOffset = parseInt(btn.dataset.offset) || 0;
  1938→            const total = parseInt(btn.dataset.total) || 0;
  1939→            const limit = 5; // Load 5 more at a time
  1940→
  1941→            btn.disabled = true;
  1942→            btn.textContent = 'Loading...';
  1943→
  1944→            try {
  1945→                const response = await fetch(`api.php?action=list_ai_responses&thread_id=${currentThreadId}&limit=${limit}&offset=${currentOffset}`);
  1946→                const data = await response.json();
  1947→
  1948→                if (data.success && data.responses && data.responses.length > 0) {
  1949→                    const container = document.getElementById('saved-responses');
  1950→
  1951→                    // Append new responses
  1952→                    data.responses.forEach(saved => {
  1953→                        // Determine what to display as the "question"
  1954→                        let displayQuestion = saved.question || 'General Analysis';
  1955→                        const hasContext = saved.context && saved.context.length > 0;
  1956→                        const isDefaultQuestion = displayQuestion.startsWith('Please analyze this email conversation');
  1957→
  1958→                        if (isDefaultQuestion && hasContext) {
  1959→                            displayQuestion = '[Context] ' + saved.context;
  1960→                        } else if (hasContext) {
  1961→                            displayQuestion = displayQuestion + ' (+context)';
  1962→                        }
  1963→
  1964→                        // Truncate to 200 chars
  1965→                        if (displayQuestion.length > 200) {
  1966→                            displayQuestion = displayQuestion.substring(0, 200) + '...';
  1967→                        }
  1968→
  1969→                        // Get response excerpt
  1970→                        const responseText = saved.response?.response || '';
  1971→                        let responseExcerpt = responseText.length > 120
  1972→                            ? responseText.substring(0, 120) + '...'
  1973→                            : responseText;
  1974→
  1975→                        const responseEl = document.createElement('div');
  1976→                        responseEl.className = 'saved-response';
  1977→                        responseEl.id = 'saved-response-' + saved._id;
  1978→                        responseEl.dataset.id = saved._id;
  1979→                        responseEl.innerHTML = `
  1980→                            <div class="saved-response-header">
  1981→                                <span class="saved-response-question">${escapeHtml(displayQuestion)}</span>
  1982→                                <span class="saved-response-date">${saved.created_at || 'Unknown date'}</span>
  1983→                            </div>
  1984→                            <div class="saved-response-preview">
  1985→                                <strong>${escapeHtml(saved.provider || 'Unknown')}</strong> /
  1986→                                ${escapeHtml(saved.model || 'Unknown')}
  1987→                            </div>
  1988→                            ${responseExcerpt ? `<div class="saved-response-excerpt">${escapeHtml(responseExcerpt)}</div>` : ''}
  1989→                            <div class="saved-response-actions">
  1990→                                <button class="btn-view" onclick="event.stopPropagation(); quickViewResponse('${saved._id}')">
  1991→                                    👁 Quick View
  1992→                                </button>
  1993→                                <button class="btn-expand" onclick="event.stopPropagation(); loadSavedResponse('${saved._id}')">
  1994→                                    📄 Full View
  1995→                                </button>
  1996→                            </div>
  1997→                        `;
  1998→
  1999→                        container.appendChild(responseEl);
  2000→                    });
  2001→
  2002→                    // Update offset
  2003→                    const newOffset = currentOffset + data.responses.length;
  2004→                    btn.dataset.offset = newOffset;
  2005→
  2006→                    // Update button text or hide if no more
  2007→                    const remaining = total - newOffset;
  2008→                    if (remaining > 0) {
  2009→                        btn.textContent = `Load More (${remaining} remaining)`;
  2010→                        btn.disabled = false;
  2011→                    } else {
  2012→                        btn.parentElement.style.display = 'none';
  2013→                    }
  2014→                } else {
  2015→                    btn.parentElement.style.display = 'none';
  2016→                }
  2017→            } catch (error) {
  2018→                console.error('Failed to load more responses:', error);
  2019→                btn.textContent = 'Error - Try Again';
  2020→                btn.disabled = false;
  2021→            }
  2022→        }
  2023→
  2024→        // Escape HTML
  2025→        function escapeHtml(text) {
  2026→            if (!text) return '';
  2027→            const div = document.createElement('div');
  2028→            div.textContent = text;
  2029→            return div.innerHTML;
  2030→        }
  2031→    </script>
  2032→</body>
  2033→</html>
  2034→

<?php
/**
 * Thread View Page
 *
 * Dedicated page for viewing email threads and sending to AI API.
 * Features:
 * - View thread emails with actual sender names
 * - Select additional threads from the same contact
 * - Send to AI API with provider/model selection
 * - Add custom questions and context
 * - Save and load AI responses
 *
 * @package EmailIntelligence
 */

require_once dirname(__DIR__) . '/config/config.php';
require_once dirname(__DIR__) . '/vendor/autoload.php';

use EmailIntelligence\MongoDatabase;
use EmailIntelligence\QueryAdapter;

session_start();

// Get thread ID from URL
$threadId = $_GET['thread_id'] ?? '';
if (empty($threadId)) {
    header('Location: index.php');
    exit;
}

// Get data via QueryAdapter (which uses MongoDB)
$adapter = QueryAdapter::getInstance();
$mongo = MongoDatabase::getInstance();

// Get thread details
$threadData = $adapter->getThreadDetails($threadId);
$emails = $threadData['emails'] ?? [];
$analysis = $threadData['analysis'] ?? null;

if (empty($emails)) {
    header('Location: index.php?error=thread_not_found');
    exit;
}

// Get the primary contact from this thread
// Priority: 1) Most frequent external contact, 2) First inbound email sender, 3) Any contact
$primaryContactId = null;
$primaryContactEmail = null;
$primaryContactName = null;
$userEmail = defined('GMAIL_USER_EMAIL') ? strtolower(GMAIL_USER_EMAIL) : '';

// Count contacts to find the most frequent one (excluding user)
$contactCounts = [];
$contactInfo = [];

foreach ($emails as $email) {
    if (!empty($email['contact_id'])) {
        $contactId = $email['contact_id'];
        $contactEmail = strtolower($email['contact_email'] ?? $email['from_email'] ?? '');

        // Skip if this is the user's own email
        if ($contactEmail === $userEmail) {
            continue;
        }

        if (!isset($contactCounts[$contactId])) {
            $contactCounts[$contactId] = 0;
            $contactInfo[$contactId] = [
                'email' => $email['contact_email'] ?? $email['from_email'],
                'name' => $email['contact_name'] ?? ''
            ];
        }
        $contactCounts[$contactId]++;
    }
}

// Select the most frequent contact
if (!empty($contactCounts)) {
    arsort($contactCounts);
    $primaryContactId = array_key_first($contactCounts);
    $primaryContactEmail = $contactInfo[$primaryContactId]['email'];
    $primaryContactName = $contactInfo[$primaryContactId]['name'];
} else {
    // Fallback: try to find any inbound email sender
    foreach ($emails as $email) {
        if (($email['direction'] ?? '') === 'inbound' && !empty($email['from_email'])) {
            $senderEmail = strtolower($email['from_email']);
            if ($senderEmail !== $userEmail) {
                $primaryContactId = $email['contact_id'] ?? null;
                $primaryContactEmail = $email['from_email'];
                $primaryContactName = $email['from_name'] ?? $email['contact_name'] ?? '';
                break;
            }
        }
    }
}

// Get other threads from the same contact for selection
$otherThreads = [];
if ($primaryContactId) {
    $contactThreads = $adapter->getThreads($primaryContactId, '', 50, 0);
    foreach ($contactThreads['threads'] as $t) {
        if ($t['thread_id'] !== $threadId) {
            $otherThreads[] = $t;
        }
    }
}

// Get saved AI responses for this thread from MongoDB
$savedResponsesLimit = 5; // Initial load limit
$savedResponses = $mongo->findAll('ai_query_responses',
    ['thread_ids' => $threadId],
    ['sort' => ['created_at' => -1], 'limit' => $savedResponsesLimit]
);

// Get total count of saved responses for this thread
$totalSavedResponses = $mongo->count('ai_query_responses', ['thread_ids' => $threadId]);

// Get first email's subject for page title
$threadSubject = $emails[0]['subject'] ?? '(No Subject)';

// Build participant map for displaying real names
$participantMap = [];
// $userEmail already defined above

foreach ($emails as $email) {
    $fromEmail = strtolower($email['from_email'] ?? '');
    if ($fromEmail && !isset($participantMap[$fromEmail])) {
        $name = '';
        if ($fromEmail === $userEmail) {
            $name = 'You';
        } elseif (!empty($email['from_name'])) {
            $name = $email['from_name'];
        } elseif (!empty($email['contact_name'])) {
            $name = $email['contact_name'];
        } else {
            // Extract name from email
            $parts = explode('@', $fromEmail);
            $nameParts = explode('.', $parts[0]);
            $name = ucfirst($nameParts[0]);
        }
        $participantMap[$fromEmail] = $name;
    }
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Thread: <?= htmlspecialchars($threadSubject) ?> - Email Intelligence</title>
    <link rel="stylesheet" href="assets/style.css">
    <style>
        :root {
            --bg-primary: #f5f7fa;
            --bg-secondary: #ffffff;
            --accent-primary: #667eea;
            --accent-secondary: #764ba2;
            --text-primary: #333;
            --text-secondary: #666;
            --border-color: #e0e0e0;
            --success: #10b981;
            --warning: #f59e0b;
            --error: #ef4444;
        }

        body {
            background: var(--bg-primary);
            margin: 0;
            padding: 0;
        }

        .page-container {
            max-width: 1600px;
            margin: 0 auto;
            padding: 20px;
        }

        .page-header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 20px 30px;
            border-radius: 12px;
            margin-bottom: 20px;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .page-header h1 {
            margin: 0 0 5px 0;
            font-size: 1.5em;
        }

        .page-header .subtitle {
            opacity: 0.9;
            font-size: 0.9em;
        }

        .back-link {
            color: white;
            text-decoration: none;
            padding: 10px 20px;
            background: rgba(255,255,255,0.2);
            border-radius: 8px;
            transition: background 0.2s;
        }

        .back-link:hover {
            background: rgba(255,255,255,0.3);
        }

        .main-grid {
            display: grid;
            grid-template-columns: 1fr 400px;
            gap: 20px;
        }

        @media (max-width: 1200px) {
            .main-grid {
                grid-template-columns: 1fr;
            }
        }

        .card {
            background: var(--bg-secondary);
            border-radius: 12px;
            padding: 20px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.08);
            margin-bottom: 20px;
        }

        .card-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
            padding-bottom: 10px;
            border-bottom: 1px solid var(--border-color);
        }

        .card-header h2 {
            margin: 0;
            font-size: 1.2em;
            color: var(--text-primary);
        }

        /* Email Timeline */
        .email-timeline {
            max-height: 600px;
            overflow-y: auto;
        }

        .email-item {
            border-left: 4px solid #3b82f6;
            padding: 15px;
            margin-bottom: 15px;
            background: #f9fafb;
            border-radius: 0 8px 8px 0;
        }

        .email-item.inbound {
            border-left-color: #10b981;
        }

        .email-item.outbound {
            border-left-color: #3b82f6;
        }

        .email-meta {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 10px;
        }

        .sender-name {
            font-weight: 600;
            color: var(--text-primary);
        }

        .sender-email {
            color: var(--text-secondary);
            font-size: 0.85em;
        }

        .email-date {
            color: var(--text-secondary);
            font-size: 0.85em;
        }

        .email-body {
            font-size: 0.95em;
            line-height: 1.6;
            color: var(--text-primary);
            white-space: pre-wrap;
            word-wrap: break-word;
            max-height: 200px;
            overflow-y: auto;
            background: white;
            padding: 10px;
            border-radius: 6px;
        }

        /* Thread Selection */
        .thread-selection {
            max-height: 300px;
            overflow-y: auto;
        }

        .thread-checkbox {
            display: flex;
            align-items: flex-start;
            padding: 10px;
            margin-bottom: 8px;
            background: #f9fafb;
            border-radius: 8px;
            cursor: pointer;
            transition: background 0.2s;
        }

        .thread-checkbox:hover {
            background: #f0f0f5;
        }

        .thread-checkbox input {
            margin-right: 12px;
            margin-top: 3px;
        }

        .thread-checkbox-content {
            flex: 1;
        }

        .thread-checkbox-subject {
            font-weight: 500;
            margin-bottom: 4px;
        }

        .thread-checkbox-meta {
            font-size: 0.85em;
            color: var(--text-secondary);
        }

        /* AI Query Form */
        .ai-form-section {
            margin-bottom: 20px;
        }

        .ai-form-section label {
            display: block;
            font-weight: 600;
            margin-bottom: 8px;
            color: var(--text-primary);
        }

        .ai-form-section textarea,
        .ai-form-section input[type="text"],
        .ai-form-section select {
            width: 100%;
            padding: 12px;
            border: 1px solid var(--border-color);
            border-radius: 8px;
            font-family: inherit;
            font-size: 0.95em;
            box-sizing: border-box;
        }

        .ai-form-section textarea {
            min-height: 100px;
            resize: vertical;
        }

        .ai-form-section textarea:focus,
        .ai-form-section input:focus,
        .ai-form-section select:focus {
            outline: none;
            border-color: var(--accent-primary);
        }

        /* Provider Selection */
        .provider-grid {
            display: grid;
            grid-template-columns: repeat(2, 1fr);
            gap: 10px;
        }

        .provider-option {
            display: flex;
            align-items: center;
            padding: 10px;
            background: #f9fafb;
            border: 1px solid var(--border-color);
            border-radius: 8px;
            cursor: pointer;
            transition: all 0.2s;
        }

        .provider-option:hover {
            border-color: var(--accent-primary);
        }

        .provider-option.selected {
            background: rgba(102, 126, 234, 0.1);
            border-color: var(--accent-primary);
        }

        .provider-option input {
            margin-right: 8px;
        }

        .provider-option .provider-name {
            font-weight: 500;
            font-size: 0.9em;
        }

        .model-select {
            margin-top: 8px;
            padding: 6px 10px;
            font-size: 0.85em;
            background: white;
        }

        /* Buttons */
        .btn {
            padding: 12px 24px;
            border: none;
            border-radius: 8px;
            font-size: 1em;
            font-weight: 500;
            cursor: pointer;
            transition: all 0.2s;
            display: inline-flex;
            align-items: center;
            gap: 8px;
        }

        .btn-primary {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
        }

        .btn-primary:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
        }

        .btn-primary:disabled {
            opacity: 0.6;
            cursor: not-allowed;
            transform: none;
        }

        .btn-secondary {
            background: #e5e7eb;
            color: var(--text-primary);
        }

        .btn-secondary:hover {
            background: #d1d5db;
        }

        /* AI Response */
        .ai-response-card {
            background: #f0fdf4;
            border: 2px solid #22c55e;
            border-radius: 12px;
            padding: 20px;
            margin-bottom: 15px;
        }

        .ai-response-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 10px;
        }

        .ai-response-provider {
            font-weight: 600;
            color: #166534;
        }

        .ai-response-meta {
            font-size: 0.85em;
            color: #166534;
        }

        .ai-response-content {
            white-space: pre-wrap;
            line-height: 1.7;
        }

        /* Saved Responses */
        .saved-response {
            background: #f9fafb;
            border: 2px solid var(--border-color);
            border-radius: 8px;
            padding: 15px;
            margin-bottom: 10px;
            transition: all 0.2s ease;
            cursor: pointer;
        }

        .saved-response:hover {
            border-color: var(--accent-primary);
            background: #f0f4ff;
        }

        .saved-response.last-viewed {
            border-color: var(--accent-primary);
            background: linear-gradient(135deg, rgba(102, 126, 234, 0.08) 0%, rgba(118, 75, 162, 0.08) 100%);
            box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.15);
        }

        .saved-response.last-viewed::before {
            content: '← Last Viewed';
            position: absolute;
            right: 10px;
            top: -10px;
            background: var(--accent-primary);
            color: white;
            font-size: 0.7em;
            padding: 2px 8px;
            border-radius: 4px;
        }

        .saved-response {
            position: relative;
        }

        .saved-response-header {
            display: flex;
            justify-content: space-between;
            margin-bottom: 8px;
        }

        .saved-response-question {
            font-weight: 500;
            color: var(--text-primary);
            flex: 1;
            margin-right: 10px;
        }

        .saved-response-date {
            font-size: 0.85em;
            color: var(--text-secondary);
            white-space: nowrap;
        }

        .saved-response-preview {
            font-size: 0.85em;
            color: var(--accent-primary);
            font-weight: 600;
            margin-bottom: 8px;
        }

        .saved-response-excerpt {
            font-size: 0.85em;
            color: var(--text-secondary);
            background: rgba(255,255,255,0.7);
            padding: 8px;
            border-radius: 4px;
            margin-bottom: 10px;
            border-left: 3px solid #ddd;
            font-style: italic;
            line-height: 1.4;
        }

        .saved-response-actions {
            display: flex;
            gap: 8px;
            margin-top: 10px;
        }

        .saved-response-actions .btn-view,
        .saved-response-actions .btn-expand {
            padding: 6px 12px;
            border: none;
            border-radius: 4px;
            font-size: 0.8em;
            cursor: pointer;
            transition: all 0.2s;
        }

        .saved-response-actions .btn-view {
            background: #e0e7ff;
            color: #4338ca;
        }

        .saved-response-actions .btn-view:hover {
            background: #c7d2fe;
        }

        .saved-response-actions .btn-expand {
            background: #dbeafe;
            color: #1d4ed8;
        }

        .saved-response-actions .btn-expand:hover {
            background: #bfdbfe;
        }

        /* Quick View Modal */
        .quick-view-overlay {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0,0,0,0.7);
            z-index: 2000;
            display: flex;
            justify-content: center;
            align-items: flex-start;
            padding: 40px 20px;
            overflow-y: auto;
        }

        .quick-view-modal {
            background: white;
            border-radius: 12px;
            max-width: 900px;
            width: 100%;
            max-height: calc(100vh - 80px);
            overflow-y: auto;
            box-shadow: 0 20px 60px rgba(0,0,0,0.3);
        }

        .quick-view-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 15px 20px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border-radius: 12px 12px 0 0;
            position: sticky;
            top: 0;
            z-index: 10;
        }

        .quick-view-header h3 {
            margin: 0;
            font-size: 1.1em;
        }

        .quick-view-close {
            background: rgba(255,255,255,0.2);
            border: none;
            color: white;
            padding: 8px 16px;
            border-radius: 6px;
            cursor: pointer;
            font-size: 0.9em;
        }

        .quick-view-close:hover {
            background: rgba(255,255,255,0.3);
        }

        .quick-view-content {
            padding: 20px;
        }

        .quick-view-meta {
            display: flex;
            gap: 20px;
            margin-bottom: 15px;
            padding-bottom: 15px;
            border-bottom: 1px solid #e5e7eb;
            flex-wrap: wrap;
        }

        .quick-view-meta-item {
            font-size: 0.9em;
        }

        .quick-view-meta-item strong {
            color: var(--accent-primary);
        }

        .quick-view-question {
            background: #f0f9ff;
            padding: 15px;
            border-radius: 8px;
            margin-bottom: 15px;
            border-left: 4px solid #3b82f6;
        }

        .quick-view-response {
            background: #f0fdf4;
            padding: 15px;
            border-radius: 8px;
            border-left: 4px solid #22c55e;
            white-space: pre-wrap;
            line-height: 1.7;
        }

        /* Loading */
        .loading-spinner {
            display: inline-block;
            width: 20px;
            height: 20px;
            border: 3px solid rgba(255,255,255,0.3);
            border-radius: 50%;
            border-top-color: white;
            animation: spin 1s linear infinite;
        }

        @keyframes spin {
            to { transform: rotate(360deg); }
        }

        .loading-overlay {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0,0,0,0.5);
            display: flex;
            justify-content: center;
            align-items: center;
            z-index: 1000;
            display: none;
        }

        .loading-overlay.active {
            display: flex;
        }

        .loading-box {
            background: white;
            padding: 30px 50px;
            border-radius: 12px;
            text-align: center;
        }

        .loading-box .spinner {
            width: 40px;
            height: 40px;
            border: 4px solid #e5e7eb;
            border-top-color: var(--accent-primary);
            border-radius: 50%;
            animation: spin 1s linear infinite;
            margin: 0 auto 15px;
        }

        /* Direction badge */
        .badge-direction {
            display: inline-block;
            padding: 2px 8px;
            border-radius: 4px;
            font-size: 0.75em;
            font-weight: 600;
            text-transform: uppercase;
        }

        .badge-inbound {
            background: #d1fae5;
            color: #065f46;
        }

        .badge-outbound {
            background: #dbeafe;
            color: #1e40af;
        }

        /* Tabs for responses */
        .response-tabs {
            display: flex;
            gap: 10px;
            margin-bottom: 15px;
            border-bottom: 2px solid var(--border-color);
            padding-bottom: 10px;
        }

        .response-tab {
            padding: 8px 16px;
            background: none;
            border: none;
            cursor: pointer;
            font-size: 0.9em;
            color: var(--text-secondary);
            border-bottom: 2px solid transparent;
            margin-bottom: -12px;
        }

        .response-tab.active {
            color: var(--accent-primary);
            border-bottom-color: var(--accent-primary);
            font-weight: 600;
        }

        .response-content {
            display: none;
        }

        .response-content.active {
            display: block;
        }
    </style>
</head>
<body>
    <div class="page-container">
        <!-- Header -->
        <div class="page-header">
            <div>
                <h1><?= htmlspecialchars($threadSubject) ?></h1>
                <div class="subtitle">
                    <?= count($emails) ?> emails
                    <?php if ($primaryContactName): ?>
                        with <?= htmlspecialchars($primaryContactName) ?>
                    <?php endif; ?>
                    | Thread ID: <?= htmlspecialchars($threadId) ?>
                </div>
            </div>
            <a href="index.php" class="back-link">Back to Dashboard</a>
        </div>

        <div class="main-grid">
            <!-- Left Column: Email Thread -->
            <div class="left-column">
                <!-- Email Timeline -->
                <div class="card">
                    <div class="card-header">
                        <h2>Email Conversation</h2>
                        <span class="email-count"><?= count($emails) ?> emails</span>
                    </div>
                    <div class="email-timeline" id="email-timeline">
                        <?php foreach ($emails as $index => $email):
                            $senderEmail = strtolower($email['from_email'] ?? '');
                            $senderName = $participantMap[$senderEmail] ?? 'Unknown';
                            $isInbound = ($email['direction'] ?? '') === 'inbound';
                            $body = $email['body_text'] ?? $email['body_html'] ?? '(No content)';
                            // Truncate for display
                            $displayBody = strlen($body) > 1500 ? substr($body, 0, 1500) . '...' : $body;
                        ?>
                        <div class="email-item <?= $isInbound ? 'inbound' : 'outbound' ?>">
                            <div class="email-meta">
                                <div>
                                    <span class="sender-name"><?= htmlspecialchars($senderName) ?></span>
                                    <span class="badge-direction <?= $isInbound ? 'badge-inbound' : 'badge-outbound' ?>">
                                        <?= $isInbound ? 'Received' : 'Sent' ?>
                                    </span>
                                    <br>
                                    <span class="sender-email"><?= htmlspecialchars($email['from_email'] ?? '') ?></span>
                                </div>
                                <span class="email-date"><?= date('M j, Y g:i A', strtotime($email['date'])) ?></span>
                            </div>
                            <div class="email-body"><?= htmlspecialchars($displayBody) ?></div>
                        </div>
                        <?php endforeach; ?>
                    </div>
                </div>

                <!-- AI Response Display -->
                <div class="card" id="ai-response-container" style="display: none;">
                    <div class="card-header">
                        <h2>AI Response</h2>
                        <button class="btn btn-secondary" onclick="closeResponse()">Close</button>
                    </div>
                    <div class="response-tabs" id="response-tabs"></div>
                    <div id="ai-responses-content"></div>
                </div>

                <!-- Saved Responses -->
                <?php if (!empty($savedResponses)): ?>
                <div class="card">
                    <div class="card-header">
                        <h2>Previous AI Analyses <span style="font-weight: normal; font-size: 0.85em; color: var(--text-secondary);">(<?= $totalSavedResponses ?> total)</span></h2>
                    </div>
                    <div id="saved-responses">
                        <?php foreach ($savedResponses as $saved):
                            // Determine what to display as the "question"
                            $displayQuestion = $saved['question'] ?? 'General Analysis';
                            $hasContext = !empty($saved['context']);
                            $isDefaultQuestion = strpos($displayQuestion, 'Please analyze this email conversation') === 0;

                            // If question is the default and user provided context, show context instead
                            if ($isDefaultQuestion && $hasContext) {
                                $displayQuestion = '[Context] ' . $saved['context'];
                            } elseif ($hasContext && !$isDefaultQuestion) {
                                // If both custom question and context exist, show question + indicator
                                $displayQuestion = $displayQuestion . ' (+context)';
                            }

                            // Truncate to 200 chars instead of 100
                            $displayQuestion = strlen($displayQuestion) > 200
                                ? substr($displayQuestion, 0, 200) . '...'
                                : $displayQuestion;

                            // Get response excerpt for easier identification
                            $responseText = $saved['response']['response'] ?? '';
                            $responseExcerpt = strlen($responseText) > 120
                                ? substr($responseText, 0, 120) . '...'
                                : $responseText;
                        ?>
                        <div class="saved-response" id="saved-response-<?= $saved['_id'] ?>" data-id="<?= $saved['_id'] ?>">
                            <div class="saved-response-header">
                                <span class="saved-response-question">
                                    <?= htmlspecialchars($displayQuestion) ?>
                                </span>
                                <span class="saved-response-date">
                                    <?= date('M j, Y g:i A', strtotime($saved['created_at'] ?? 'now')) ?>
                                </span>
                            </div>
                            <div class="saved-response-preview">
                                <strong><?= htmlspecialchars($saved['provider'] ?? 'Unknown') ?></strong> /
                                <?= htmlspecialchars($saved['model'] ?? 'Unknown') ?>
                            </div>
                            <?php if ($responseExcerpt): ?>
                            <div class="saved-response-excerpt">
                                <?= htmlspecialchars($responseExcerpt) ?>
                            </div>
                            <?php endif; ?>
                            <div class="saved-response-actions">
                                <button class="btn-view" onclick="event.stopPropagation(); quickViewResponse('<?= $saved['_id'] ?>')">
                                    👁 Quick View
                                </button>
                                <button class="btn-expand" onclick="event.stopPropagation(); loadSavedResponse('<?= $saved['_id'] ?>')">
                                    📄 Full View
                                </button>
                            </div>
                        </div>
                        <?php endforeach; ?>
                    </div>
                    <?php if ($totalSavedResponses > $savedResponsesLimit): ?>
                    <div id="load-more-container" style="text-align: center; margin-top: 15px;">
                        <button class="btn btn-secondary" id="load-more-btn" onclick="loadMoreResponses()"
                                data-offset="<?= $savedResponsesLimit ?>"
                                data-total="<?= $totalSavedResponses ?>">
                            Load More (<?= $totalSavedResponses - $savedResponsesLimit ?> remaining)
                        </button>
                    </div>
                    <?php endif; ?>
                </div>
                <?php endif; ?>
            </div>

            <!-- Right Column: AI Query Panel -->
            <div class="right-column">
                <!-- Additional Threads Selection -->
                <?php if (!empty($otherThreads)): ?>
                <div class="card">
                    <div class="card-header">
                        <h2>Include Other Threads</h2>
                    </div>
                    <p style="font-size: 0.9em; color: var(--text-secondary); margin-bottom: 15px;">
                        Select additional threads from <?= htmlspecialchars($primaryContactName ?: 'this contact') ?> to include in the AI analysis:
                    </p>
                    <div class="thread-selection">
                        <?php foreach (array_slice($otherThreads, 0, 10) as $thread): ?>
                        <label class="thread-checkbox">
                            <input type="checkbox" name="additional_threads[]" value="<?= htmlspecialchars($thread['thread_id']) ?>">
                            <div class="thread-checkbox-content">
                                <div class="thread-checkbox-subject"><?= htmlspecialchars($thread['subject'] ?? '(No Subject)') ?></div>
                                <div class="thread-checkbox-meta">
                                    <?= $thread['email_count'] ?? 0 ?> emails |
                                    <?= date('M j, Y', strtotime($thread['last_date'] ?? 'now')) ?>
                                </div>
                            </div>
                        </label>
                        <?php endforeach; ?>
                    </div>
                </div>
                <?php endif; ?>

                <!-- AI Query Form -->
                <div class="card">
                    <div class="card-header">
                        <h2>Ask AI</h2>
                    </div>

                    <!-- Provider Selection -->
                    <div class="ai-form-section">
                        <label>Select AI Provider</label>
                        <div class="provider-grid" id="provider-grid">
                            <!-- Loaded via JavaScript -->
                            <p style="color: var(--text-secondary);">Loading providers...</p>
                        </div>
                    </div>

                    <!-- Content Processing Mode -->
                    <div class="ai-form-section">
                        <label for="content-mode">Email Content Processing</label>
                        <select id="content-mode" style="width: 100%;">
                            <option value="full">Full Content (include all quoted replies)</option>
                            <option value="stripped" selected>Stripped (remove quoted replies - saves tokens)</option>
                            <option value="smart">Smart Deduplication (quotes only in last email)</option>
                        </select>
                        <p style="font-size: 0.8em; color: var(--text-secondary); margin-top: 5px;">
                            <strong>Stripped:</strong> Removes ">" quoted lines and "On [date] wrote:" sections.<br>
                            <strong>Smart:</strong> Keeps full context only in the last email to avoid redundancy.
                        </p>
                    </div>

                    <!-- Question -->
                    <div class="ai-form-section">
                        <label for="ai-question">Your Question</label>
                        <textarea id="ai-question" placeholder="What would you like to know about this conversation?

Examples:
- What is the client's main concern?
- Summarize the key points
- Is there any deception detected?
- What should be my next steps?"></textarea>
                    </div>

                    <!-- Additional Context -->
                    <div class="ai-form-section">
                        <label for="ai-context">Additional Context (Optional)</label>
                        <textarea id="ai-context" placeholder="Add any additional context the AI should know...

e.g., business background, relationship history, specific concerns..."></textarea>
                    </div>

                    <!-- Submit Button -->
                    <button class="btn btn-primary" id="submit-ai-btn" onclick="submitToAI()" style="width: 100%;">
                        Send to AI
                    </button>
                </div>
            </div>
        </div>
    </div>

    <!-- Loading Overlay -->
    <div class="loading-overlay" id="loading-overlay">
        <div class="loading-box">
            <div class="spinner"></div>
            <p id="loading-message">Analyzing with AI...</p>
        </div>
    </div>

    <!-- Quick View Modal -->
    <div class="quick-view-overlay" id="quick-view-overlay" style="display: none;" onclick="closeQuickView(event)">
        <div class="quick-view-modal" onclick="event.stopPropagation()">
            <div class="quick-view-header">
                <h3 id="quick-view-title">AI Response</h3>
                <button class="quick-view-close" onclick="closeQuickView()">✕ Close (Esc)</button>
            </div>
            <div class="quick-view-content">
                <div class="quick-view-meta" id="quick-view-meta"></div>
                <div id="quick-view-question-section"></div>
                <div class="quick-view-response" id="quick-view-response"></div>
            </div>
        </div>
    </div>

    <script>
        // Current thread data
        const currentThreadId = '<?= addslashes($threadId) ?>';
        const primaryContactId = <?= $primaryContactId ? $primaryContactId : 'null' ?>;

        // Build email content for AI from PHP
        const emailContent = <?= json_encode(array_map(function($email) use ($participantMap) {
            $senderEmail = strtolower($email['from_email'] ?? '');
            $senderName = $participantMap[$senderEmail] ?? 'Unknown';
            return [
                'from' => $senderName,
                'from_email' => $email['from_email'] ?? '',
                'date' => $email['date'] ?? '',
                'direction' => $email['direction'] ?? '',
                'body' => $email['body_text'] ?? $email['body_html'] ?? ''
            ];
        }, $emails)) ?>;

        // Provider data
        let providers = {};
        let selectedProvider = null;
        let selectedModel = null;

        // ============================================
        // CONVERSATION MEMORY - ChatGPT-like history
        // ============================================
        // Conversation history - stores Q&A pairs for context
        let conversationHistory = [];
        const MAX_CONVERSATION_HISTORY = 20; // Maximum Q&A pairs to keep

        // Load conversation history from sessionStorage (persists during page session)
        function loadConversationHistory() {
            const stored = sessionStorage.getItem(`conversation_${currentThreadId}`);
            if (stored) {
                try {
                    conversationHistory = JSON.parse(stored);
                    updateConversationDisplay();
                } catch (e) {
                    conversationHistory = [];
                }
            }
        }

        // Save conversation history to sessionStorage
        function saveConversationHistory() {
            sessionStorage.setItem(`conversation_${currentThreadId}`, JSON.stringify(conversationHistory));
        }

        // Add a Q&A pair to conversation history
        function addToConversation(question, answer, provider, model, context = '') {
            const entry = {
                timestamp: new Date().toISOString(),
                question: question,
                context: context,
                answer: answer,
                provider: provider,
                model: model
            };

            conversationHistory.push(entry);

            // Keep only the last MAX_CONVERSATION_HISTORY entries
            if (conversationHistory.length > MAX_CONVERSATION_HISTORY) {
                conversationHistory = conversationHistory.slice(-MAX_CONVERSATION_HISTORY);
            }

            saveConversationHistory();
            updateConversationDisplay();
        }

        // Clear conversation history
        function clearConversationHistory() {
            if (confirm('Clear all conversation history for this thread?')) {
                conversationHistory = [];
                saveConversationHistory();
                updateConversationDisplay();
            }
        }

        // Build conversation context string for AI
        function buildConversationContext() {
            if (conversationHistory.length === 0) return '';

            let context = '\n\n=== PREVIOUS CONVERSATION HISTORY ===\n';
            context += '(The user has asked previous questions about this email thread. Use this context for continuity.)\n\n';

            conversationHistory.forEach((entry, index) => {
                context += `--- Exchange ${index + 1} (${new Date(entry.timestamp).toLocaleString()}) ---\n`;
                context += `USER QUESTION: ${entry.question}\n`;
                context += `AI RESPONSE (${entry.provider}/${entry.model}):\n${entry.answer}\n\n`;
            });

            context += '=== END OF PREVIOUS CONVERSATION ===\n\n';
            context += 'Please consider the above conversation history when answering the new question. ';
            context += 'If the user refers to something discussed previously, use that context.\n\n';

            return context;
        }

        // Update the conversation history display in UI
        function updateConversationDisplay() {
            let historyContainer = document.getElementById('conversation-history');

            if (conversationHistory.length === 0) {
                if (historyContainer) {
                    historyContainer.style.display = 'none';
                }
                return;
            }

            if (!historyContainer) {
                // Create history container if it doesn't exist
                const aiFormCard = document.querySelector('.right-column .card:last-child');
                if (aiFormCard) {
                    historyContainer = document.createElement('div');
                    historyContainer.id = 'conversation-history';
                    historyContainer.className = 'card';
                    historyContainer.style.marginTop = '20px';
                    aiFormCard.after(historyContainer);
                }
            }

            if (historyContainer) {
                historyContainer.style.display = 'block';
                historyContainer.innerHTML = `
                    <div class="card-header">
                        <h2>💬 Conversation History (${conversationHistory.length})</h2>
                        <button class="btn btn-secondary" onclick="clearConversationHistory()" style="padding: 6px 12px; font-size: 0.85em;">
                            Clear History
                        </button>
                    </div>
                    <p style="font-size: 0.85em; color: var(--text-secondary); margin-bottom: 10px;">
                        Previous Q&A pairs are included as context for new questions (like ChatGPT memory).
                    </p>
                    <div style="max-height: 300px; overflow-y: auto;">
                        ${conversationHistory.slice().reverse().map((entry, i) => {
                            // Determine display text - show context if question is default
                            const isDefaultQuestion = entry.question && entry.question.startsWith('Please analyze this email conversation');
                            const hasContext = entry.context && entry.context.length > 0;
                            let displayQ = entry.question || 'General Analysis';

                            if (isDefaultQuestion && hasContext) {
                                displayQ = '[Context] ' + entry.context;
                            } else if (hasContext) {
                                displayQ = entry.question + ' (+context)';
                            }

                            return `
                            <div style="background: ${i % 2 === 0 ? '#f9fafb' : '#fff'}; padding: 10px; border-radius: 6px; margin-bottom: 8px; border-left: 3px solid var(--accent-primary);">
                                <div style="font-size: 0.8em; color: var(--text-secondary); margin-bottom: 5px;">
                                    ${new Date(entry.timestamp).toLocaleString()} | ${entry.provider}/${entry.model}
                                </div>
                                <div style="font-weight: 600; color: var(--accent-primary); margin-bottom: 5px;">
                                    Q: ${escapeHtml(displayQ.substring(0, 200))}${displayQ.length > 200 ? '...' : ''}
                                </div>
                                <div style="font-size: 0.9em; color: var(--text-primary); max-height: 60px; overflow: hidden;">
                                    A: ${escapeHtml(entry.answer.substring(0, 150))}${entry.answer.length > 150 ? '...' : ''}
                                </div>
                            </div>`;
                        }).join('')}
                    </div>
                `;
            }
        }

        // Load providers on page load
        document.addEventListener('DOMContentLoaded', function() {
            loadProviders();
            loadConversationHistory(); // Load conversation history on page load
        });

        // Load AI providers from API
        async function loadProviders() {
            try {
                const response = await fetch('../aiapi/api_opus/api/query.php?action=providers');
                const data = await response.json();

                if (data.success) {
                    providers = data.providers;
                    renderProviders();
                }
            } catch (error) {
                console.error('Failed to load providers:', error);
                document.getElementById('provider-grid').innerHTML =
                    '<p style="color: #ef4444;">Failed to load AI providers</p>';
            }
        }

        // Render provider selection (multi-select with checkboxes)
        function renderProviders() {
            const container = document.getElementById('provider-grid');
            container.innerHTML = '';

            // Add select all / deselect all buttons
            const buttonsDiv = document.createElement('div');
            buttonsDiv.style.cssText = 'grid-column: 1 / -1; display: flex; gap: 10px; margin-bottom: 10px;';
            buttonsDiv.innerHTML = `
                <button type="button" class="btn btn-small" onclick="selectAllProviders()">Select All</button>
                <button type="button" class="btn btn-small" onclick="deselectAllProviders()">Deselect All</button>
                <span style="margin-left: auto; color: var(--text-secondary); font-size: 0.85em;" id="selected-count">0 selected</span>
            `;
            container.appendChild(buttonsDiv);

            for (const [key, provider] of Object.entries(providers)) {
                if (!provider.has_key) continue;

                const div = document.createElement('div');
                div.className = 'provider-option';
                div.dataset.provider = key;
                div.onclick = (e) => {
                    if (e.target.tagName !== 'SELECT' && e.target.tagName !== 'OPTION') {
                        toggleProvider(key);
                    }
                };

                let modelsHtml = '<select class="model-select" id="model_' + key + '" onclick="event.stopPropagation()">';
                for (const [modelKey, modelName] of Object.entries(provider.models)) {
                    const selected = modelKey === provider.default_model ? 'selected' : '';
                    modelsHtml += `<option value="${modelKey}" ${selected}>${modelName}</option>`;
                }
                modelsHtml += '</select>';

                div.innerHTML = `
                    <input type="checkbox" name="providers[]" value="${key}" id="provider_${key}" onclick="event.stopPropagation(); toggleProvider('${key}', this.checked)">
                    <div style="flex: 1;">
                        <div class="provider-name">${provider.name}</div>
                        ${modelsHtml}
                    </div>
                `;

                container.appendChild(div);
            }

            // Select Claude by default if available
            if (providers['claude']?.has_key) {
                toggleProvider('claude', true);
            } else {
                // Select first available provider
                const firstProvider = Object.keys(providers).find(k => providers[k].has_key);
                if (firstProvider) {
                    toggleProvider(firstProvider, true);
                }
            }
        }

        // Toggle a provider selection
        function toggleProvider(providerKey, forceState = null) {
            const checkbox = document.getElementById('provider_' + providerKey);
            const option = document.querySelector(`.provider-option[data-provider="${providerKey}"]`);

            if (!checkbox || !option) return;

            // Determine new state
            const newState = forceState !== null ? forceState : !checkbox.checked;
            checkbox.checked = newState;
            option.classList.toggle('selected', newState);

            updateSelectedCount();
        }

        // Select all providers
        function selectAllProviders() {
            for (const key of Object.keys(providers)) {
                if (providers[key].has_key) {
                    toggleProvider(key, true);
                }
            }
        }

        // Deselect all providers
        function deselectAllProviders() {
            for (const key of Object.keys(providers)) {
                toggleProvider(key, false);
            }
        }

        // Update selected count display
        function updateSelectedCount() {
            const count = document.querySelectorAll('input[name="providers[]"]:checked').length;
            const countEl = document.getElementById('selected-count');
            if (countEl) {
                countEl.textContent = count + ' selected';
                countEl.style.color = count === 0 ? '#ef4444' : 'var(--text-secondary)';
            }
        }

        // Get selected providers
        function getSelectedProviders() {
            const checkboxes = document.querySelectorAll('input[name="providers[]"]:checked');
            return Array.from(checkboxes).map(cb => cb.value);
        }

        // Get selected additional threads
        function getSelectedThreads() {
            const checkboxes = document.querySelectorAll('input[name="additional_threads[]"]:checked');
            return Array.from(checkboxes).map(cb => cb.value);
        }

        /**
         * Strip quoted content from email body
         * Removes:
         * - Lines starting with ">" (quoted text)
         * - "On [date] [name] wrote:" patterns
         * - "From: ... Sent: ... To: ... Subject:" forwarded headers
         * - Lines starting with "-----Original Message-----"
         */
        function stripQuotedContent(body) {
            if (!body) return '';

            let lines = body.split('\n');
            let result = [];
            let inQuoteBlock = false;
            let consecutiveEmptyLines = 0;

            for (let i = 0; i < lines.length; i++) {
                let line = lines[i];
                let trimmedLine = line.trim();

                // Detect start of quoted section
                if (/^On\s+.+wrote:\s*$/i.test(trimmedLine) ||
                    /^On\s+\d+.+at\s+\d+.+wrote:\s*$/i.test(trimmedLine) ||
                    /^-{3,}\s*Original Message\s*-{3,}/i.test(trimmedLine) ||
                    /^-{3,}\s*Forwarded message\s*-{3,}/i.test(trimmedLine) ||
                    /^From:\s*.+\s+Sent:\s*.+\s+To:/i.test(trimmedLine)) {
                    inQuoteBlock = true;
                    continue;
                }

                // Skip quoted lines (starting with >)
                if (trimmedLine.startsWith('>')) {
                    inQuoteBlock = true;
                    continue;
                }

                // If we were in a quote block and hit non-quoted content, exit quote mode
                if (inQuoteBlock && trimmedLine && !trimmedLine.startsWith('>')) {
                    // Check if this is still part of quote (continuation)
                    if (i + 1 < lines.length && lines[i + 1].trim().startsWith('>')) {
                        continue; // Skip this line too
                    }
                    inQuoteBlock = false;
                }

                // Skip if still in quote block
                if (inQuoteBlock) continue;

                // Handle consecutive empty lines (max 2)
                if (!trimmedLine) {
                    consecutiveEmptyLines++;
                    if (consecutiveEmptyLines <= 2) {
                        result.push('');
                    }
                    continue;
                }

                consecutiveEmptyLines = 0;
                result.push(line);
            }

            // Trim trailing empty lines
            while (result.length > 0 && !result[result.length - 1].trim()) {
                result.pop();
            }

            return result.join('\n').trim();
        }

        /**
         * Build email content string for AI
         * Supports different processing modes:
         * - full: Include all content as-is
         * - stripped: Remove quoted replies from all emails
         * - smart: Keep quotes only in the last email
         */
        function buildEmailContent() {
            const mode = document.getElementById('content-mode').value;
            let content = 'EMAIL THREAD CONVERSATION:\n';
            content += `(Content mode: ${mode})\n\n`;

            const totalEmails = emailContent.length;

            emailContent.forEach((email, index) => {
                content += `--- Email ${index + 1} of ${totalEmails} ---\n`;
                content += `From: ${email.from} <${email.from_email}>\n`;
                content += `Date: ${email.date}\n`;
                content += `Direction: ${email.direction}\n\n`;

                let emailBody = email.body;

                if (mode === 'stripped') {
                    // Strip quoted content from all emails
                    emailBody = stripQuotedContent(emailBody);
                    if (!emailBody.trim()) {
                        emailBody = '(Only quoted content - no new text in this email)';
                    }
                } else if (mode === 'smart') {
                    // Strip quotes from all emails except the last one
                    if (index < totalEmails - 1) {
                        emailBody = stripQuotedContent(emailBody);
                        if (!emailBody.trim()) {
                            emailBody = '(Only quoted content - no new text in this email)';
                        }
                    }
                    // Last email keeps full content for context
                }
                // mode === 'full' keeps everything as-is

                content += emailBody + '\n\n';
            });

            return content;
        }

        /**
         * Process additional thread content with the selected mode
         */
        function processAdditionalThreadContent(emails, mode) {
            let content = '';
            const totalEmails = emails.length;

            emails.forEach((email, idx) => {
                const senderName = email.from_name || email.from_email || 'Unknown';
                content += `Email ${idx + 1} from ${senderName}:\n`;

                let emailBody = email.body_text || email.body_html || '';

                if (mode === 'stripped') {
                    emailBody = stripQuotedContent(emailBody);
                    if (!emailBody.trim()) {
                        emailBody = '(Only quoted content)';
                    }
                } else if (mode === 'smart' && idx < totalEmails - 1) {
                    emailBody = stripQuotedContent(emailBody);
                    if (!emailBody.trim()) {
                        emailBody = '(Only quoted content)';
                    }
                }

                content += emailBody + '\n\n';
            });

            return content;
        }

        // Submit to AI
        async function submitToAI() {
            const selectedProvidersList = getSelectedProviders();

            if (selectedProvidersList.length === 0) {
                alert('Please select at least one AI provider');
                return;
            }

            const question = document.getElementById('ai-question').value.trim();
            const context = document.getElementById('ai-context').value.trim();
            const contentMode = document.getElementById('content-mode').value;
            const additionalThreads = getSelectedThreads();

            // Build models map for each selected provider
            const modelsMap = {};
            selectedProvidersList.forEach(provider => {
                const modelSelect = document.getElementById('model_' + provider);
                modelsMap[provider] = modelSelect ? modelSelect.value : '';
            });

            // Show loading
            document.getElementById('loading-overlay').classList.add('active');
            document.getElementById('submit-ai-btn').disabled = true;

            try {
                // Build the full content
                let fullContent = buildEmailContent();

                // ADD CONVERSATION HISTORY FOR CONTEXT (ChatGPT-like memory)
                const conversationContext = buildConversationContext();
                if (conversationContext) {
                    fullContent += conversationContext;
                    console.log('Including conversation history:', conversationHistory.length, 'previous exchanges');
                }

                // Add question if provided
                const actualQuestion = question || 'Please analyze this email conversation and provide insights on:\n1. Key points and summary\n2. Sentiment and tone analysis\n3. Any potential concerns or red flags\n4. Recommended next steps';

                if (question) {
                    fullContent += '\n\nCURRENT USER QUESTION:\n' + question;
                } else {
                    fullContent += '\n\n' + actualQuestion;
                }

                // Add context if provided
                if (context) {
                    fullContent += '\n\nADDITIONAL CONTEXT:\n' + context;
                }

                // Fetch additional thread content if selected
                if (additionalThreads.length > 0) {
                    document.getElementById('loading-message').textContent = 'Loading additional threads...';

                    for (const threadId of additionalThreads) {
                        const threadData = await fetch(`api.php?action=thread&thread_id=${threadId}`);
                        const thread = await threadData.json();

                        if (thread.emails && thread.emails.length > 0) {
                            fullContent += '\n\n--- ADDITIONAL THREAD ---\n';
                            fullContent += 'Subject: ' + (thread.emails[0].subject || '(No Subject)') + '\n\n';
                            fullContent += processAdditionalThreadContent(thread.emails, contentMode);
                        }
                    }
                }

                // Log what's being sent
                console.log('=== AI REQUEST LOG ===');
                console.log('Providers:', selectedProvidersList);
                console.log('Models:', modelsMap);
                console.log('Content Mode:', contentMode);
                console.log('Conversation History Entries:', conversationHistory.length);
                console.log('Content Length:', fullContent.length, 'characters');
                console.log('Estimated Tokens:', Math.ceil(fullContent.length / 4));
                console.log('Full Content Preview (first 500 chars):', fullContent.substring(0, 500));
                console.log('======================');

                document.getElementById('loading-message').textContent = `Analyzing with ${selectedProvidersList.length} AI provider(s)...`;

                // Build request body with all selected providers and their models
                const requestBody = {
                    user_content: fullContent,
                    providers: selectedProvidersList
                };

                // Add model for each provider
                for (const [provider, model] of Object.entries(modelsMap)) {
                    requestBody['model_' + provider] = model;
                }

                // Send to AI API
                const response = await fetch('../aiapi/api_opus/api/query.php', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify(requestBody)
                });

                const data = await response.json();

                // Log response
                console.log('=== AI RESPONSE LOG ===');
                console.log('Success:', data.success);
                console.log('Query ID:', data.query_id);
                console.log('Total Cost:', data.total_cost);
                console.log('Response Keys:', Object.keys(data.responses || {}));
                console.log('=======================');

                if (data.success) {
                    // Track if we've added to conversation history (only add once)
                    let addedToConversation = false;
                    let firstSuccessfulProvider = null;
                    let firstSuccessfulResponse = null;

                    // Save to MongoDB for each provider
                    for (const provider of selectedProvidersList) {
                        const providerResponse = data.responses[provider + '_response'];
                        if (providerResponse && providerResponse.success) {
                            // Track first successful response for conversation history
                            if (!firstSuccessfulProvider) {
                                firstSuccessfulProvider = provider;
                                firstSuccessfulResponse = providerResponse;
                            }

                            // Save to MongoDB via our API
                            await saveAIResponse({
                                thread_ids: [currentThreadId, ...additionalThreads],
                                contact_id: primaryContactId,
                                question: actualQuestion,
                                context: context,
                                content_mode: contentMode,
                                content_sent: fullContent, // Log what was sent
                                content_length: fullContent.length,
                                estimated_tokens: Math.ceil(fullContent.length / 4),
                                provider: provider,
                                model: modelsMap[provider],
                                query_id: data.query_id,
                                response: providerResponse,
                                total_cost: providerResponse.cost || 0,
                                all_providers: selectedProvidersList,
                                conversation_history_count: conversationHistory.length
                            });
                        }
                    }

                    // ADD TO CONVERSATION HISTORY (first successful response)
                    // This creates the ChatGPT-like memory effect
                    if (firstSuccessfulProvider && firstSuccessfulResponse && firstSuccessfulResponse.response) {
                        addToConversation(
                            actualQuestion,
                            firstSuccessfulResponse.response,
                            firstSuccessfulProvider,
                            modelsMap[firstSuccessfulProvider],
                            context  // Pass context to conversation history
                        );
                        console.log('Added to conversation history:', firstSuccessfulProvider);
                    }

                    // Clear the question field for next question
                    document.getElementById('ai-question').value = '';

                    // Display response
                    displayAIResponse(data);
                } else {
                    alert('AI request failed: ' + (data.error || 'Unknown error'));
                }
            } catch (error) {
                console.error('AI request error:', error);
                alert('Error: ' + error.message);
            } finally {
                document.getElementById('loading-overlay').classList.remove('active');
                document.getElementById('submit-ai-btn').disabled = false;
            }
        }

        // Save AI response to MongoDB
        async function saveAIResponse(responseData) {
            try {
                await fetch('api.php?action=save_ai_response', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify(responseData)
                });
            } catch (error) {
                console.error('Failed to save response:', error);
            }
        }

        // Display AI response
        function displayAIResponse(data) {
            const container = document.getElementById('ai-response-container');
            const tabsContainer = document.getElementById('response-tabs');
            const contentContainer = document.getElementById('ai-responses-content');

            container.style.display = 'block';
            tabsContainer.innerHTML = '';
            contentContainer.innerHTML = '';

            let tabIndex = 0;
            for (const [key, response] of Object.entries(data.responses)) {
                const providerName = key.replace('_response', '');
                const providerConfig = providers[providerName] || { name: providerName };

                // Create tab
                const tab = document.createElement('button');
                tab.className = 'response-tab' + (tabIndex === 0 ? ' active' : '');
                tab.textContent = providerConfig.name;
                tab.onclick = () => switchResponseTab(tabIndex);
                tab.dataset.index = tabIndex;
                tabsContainer.appendChild(tab);

                // Create content
                const content = document.createElement('div');
                content.className = 'response-content' + (tabIndex === 0 ? ' active' : '');
                content.id = 'response-tab-' + tabIndex;

                if (response.success) {
                    content.innerHTML = `
                        <div class="ai-response-card">
                            <div class="ai-response-header">
                                <span class="ai-response-provider">${providerConfig.name}</span>
                                <span class="ai-response-meta">
                                    Model: ${response.model || 'Unknown'} |
                                    Time: ${response.request_time?.toFixed(2) || '?'}s |
                                    Cost: $${response.cost?.toFixed(6) || '0'}
                                </span>
                            </div>
                            <div class="ai-response-content">${escapeHtml(response.response)}</div>
                        </div>
                    `;
                } else {
                    content.innerHTML = `
                        <div style="background: #fef2f2; border: 1px solid #ef4444; padding: 15px; border-radius: 8px;">
                            <strong style="color: #dc2626;">Error:</strong>
                            <p style="margin: 5px 0 0; color: #991b1b;">${escapeHtml(response.error || 'Unknown error')}</p>
                        </div>
                    `;
                }

                contentContainer.appendChild(content);
                tabIndex++;
            }

            // Scroll to response
            container.scrollIntoView({ behavior: 'smooth' });
        }

        // Switch response tabs - scoped to response container only
        function switchResponseTab(index) {
            const tabsContainer = document.getElementById('response-tabs');
            const contentContainer = document.getElementById('ai-responses-content');

            if (!tabsContainer || !contentContainer) return;

            // Only target tabs within our container
            tabsContainer.querySelectorAll('.response-tab').forEach(tab => {
                const tabIndex = parseInt(tab.dataset.index);
                tab.classList.remove('active');
                if (tabIndex === index) {
                    tab.classList.add('active');
                }
            });

            // Only target content within our container
            contentContainer.querySelectorAll('.response-content').forEach((content, i) => {
                content.classList.remove('active');
                if (i === index) {
                    content.classList.add('active');
                }
            });
        }

        // Close response
        function closeResponse() {
            document.getElementById('ai-response-container').style.display = 'none';
        }

        // Mark a saved response row as last viewed
        function markAsLastViewed(responseId) {
            // Remove last-viewed from all rows
            document.querySelectorAll('.saved-response.last-viewed').forEach(el => {
                el.classList.remove('last-viewed');
            });
            // Add to the current row
            const row = document.getElementById('saved-response-' + responseId);
            if (row) {
                row.classList.add('last-viewed');
            }
        }

        // Load saved response
        async function loadSavedResponse(responseId) {
            try {
                // Mark this row as last viewed
                markAsLastViewed(responseId);

                document.getElementById('loading-overlay').classList.add('active');
                document.getElementById('loading-message').textContent = 'Loading saved response...';

                const response = await fetch(`api.php?action=get_ai_response&id=${responseId}`);
                const data = await response.json();

                if (data.success && data.response) {
                    const saved = data.response;

                    // Display it
                    const container = document.getElementById('ai-response-container');
                    const tabsContainer = document.getElementById('response-tabs');
                    const contentContainer = document.getElementById('ai-responses-content');

                    container.style.display = 'block';
                    tabsContainer.innerHTML = `<button class="response-tab active">${saved.provider}</button>`;

                    const aiResponse = saved.response || {};

                    // Determine how to display question/context
                    const isDefaultQuestion = saved.question && saved.question.startsWith('Please analyze this email conversation');
                    const hasContext = saved.context && saved.context.length > 0;

                    let questionHtml = '';
                    if (isDefaultQuestion && hasContext) {
                        // Show context as the main input if question was default
                        questionHtml = `
                            <p><strong>User Input (Context):</strong></p>
                            <p style="background: #f5f5f5; padding: 10px; border-radius: 6px; white-space: pre-wrap;">${escapeHtml(saved.context)}</p>
                            <p style="font-size: 0.85em; color: #666;"><em>Default question was used for analysis</em></p>
                        `;
                    } else if (hasContext) {
                        // Show both question and context
                        questionHtml = `
                            <p><strong>Question:</strong> ${escapeHtml(saved.question)}</p>
                            <p><strong>Additional Context:</strong></p>
                            <p style="background: #f5f5f5; padding: 10px; border-radius: 6px; white-space: pre-wrap;">${escapeHtml(saved.context)}</p>
                        `;
                    } else {
                        // Just show question
                        questionHtml = `<p><strong>Question:</strong> ${escapeHtml(saved.question)}</p>`;
                    }

                    contentContainer.innerHTML = `
                        <div class="response-content active">
                            <div class="ai-response-card">
                                <div class="ai-response-header">
                                    <span class="ai-response-provider">${saved.provider} - ${saved.model}</span>
                                    <span class="ai-response-meta">Saved: ${saved.created_at}</span>
                                </div>
                                ${questionHtml}
                                <hr style="margin: 15px 0; border: none; border-top: 1px solid #e0e0e0;">
                                <div class="ai-response-content">${escapeHtml(aiResponse.response || 'No response content')}</div>
                            </div>
                        </div>
                    `;

                    container.scrollIntoView({ behavior: 'smooth' });
                }
            } catch (error) {
                console.error('Failed to load saved response:', error);
                alert('Failed to load saved response');
            } finally {
                document.getElementById('loading-overlay').classList.remove('active');
            }
        }

        // Quick view response in modal (no page scroll)
        async function quickViewResponse(responseId) {
            try {
                // Mark this row as last viewed
                markAsLastViewed(responseId);

                const overlay = document.getElementById('quick-view-overlay');
                overlay.style.display = 'flex';
                document.getElementById('quick-view-response').textContent = 'Loading...';
                document.getElementById('quick-view-meta').innerHTML = '';
                document.getElementById('quick-view-question-section').innerHTML = '';

                const response = await fetch(`api.php?action=get_ai_response&id=${responseId}`);
                const data = await response.json();

                if (data.success && data.response) {
                    const saved = data.response;
                    const aiResponse = saved.response || {};

                    // Update title
                    document.getElementById('quick-view-title').textContent = `${saved.provider} / ${saved.model}`;

                    // Update meta
                    document.getElementById('quick-view-meta').innerHTML = `
                        <div class="quick-view-meta-item"><strong>Provider:</strong> ${escapeHtml(saved.provider)}</div>
                        <div class="quick-view-meta-item"><strong>Model:</strong> ${escapeHtml(saved.model)}</div>
                        <div class="quick-view-meta-item"><strong>Date:</strong> ${escapeHtml(saved.created_at)}</div>
                        <div class="quick-view-meta-item"><strong>Cost:</strong> $${(saved.total_cost || 0).toFixed(6)}</div>
                    `;

                    // Update question/context section
                    const isDefaultQuestion = saved.question && saved.question.startsWith('Please analyze this email conversation');
                    const hasContext = saved.context && saved.context.length > 0;

                    let questionHtml = '';
                    if (isDefaultQuestion && hasContext) {
                        questionHtml = `
                            <div class="quick-view-question">
                                <strong>User Context:</strong><br>
                                ${escapeHtml(saved.context)}
                                <div style="font-size: 0.85em; color: #666; margin-top: 8px;"><em>Default analysis question was used</em></div>
                            </div>
                        `;
                    } else if (hasContext) {
                        questionHtml = `
                            <div class="quick-view-question">
                                <strong>Question:</strong> ${escapeHtml(saved.question)}<br><br>
                                <strong>Context:</strong> ${escapeHtml(saved.context)}
                            </div>
                        `;
                    } else {
                        questionHtml = `
                            <div class="quick-view-question">
                                <strong>Question:</strong> ${escapeHtml(saved.question)}
                            </div>
                        `;
                    }
                    document.getElementById('quick-view-question-section').innerHTML = questionHtml;

                    // Update response
                    document.getElementById('quick-view-response').textContent = aiResponse.response || 'No response content';
                } else {
                    document.getElementById('quick-view-response').textContent = 'Error loading response';
                }
            } catch (error) {
                console.error('Failed to quick view response:', error);
                document.getElementById('quick-view-response').textContent = 'Error: ' + error.message;
            }
        }

        // Close quick view modal
        function closeQuickView(event) {
            if (event && event.target !== event.currentTarget) return;
            document.getElementById('quick-view-overlay').style.display = 'none';
        }

        // Close quick view on Escape key
        document.addEventListener('keydown', function(e) {
            if (e.key === 'Escape') {
                closeQuickView();
            }
        });

        // Load more saved responses
        async function loadMoreResponses() {
            const btn = document.getElementById('load-more-btn');
            if (!btn) return;

            const currentOffset = parseInt(btn.dataset.offset) || 0;
            const total = parseInt(btn.dataset.total) || 0;
            const limit = 5; // Load 5 more at a time

            btn.disabled = true;
            btn.textContent = 'Loading...';

            try {
                const response = await fetch(`api.php?action=list_ai_responses&thread_id=${currentThreadId}&limit=${limit}&offset=${currentOffset}`);
                const data = await response.json();

                if (data.success && data.responses && data.responses.length > 0) {
                    const container = document.getElementById('saved-responses');

                    // Append new responses
                    data.responses.forEach(saved => {
                        // Determine what to display as the "question"
                        let displayQuestion = saved.question || 'General Analysis';
                        const hasContext = saved.context && saved.context.length > 0;
                        const isDefaultQuestion = displayQuestion.startsWith('Please analyze this email conversation');

                        if (isDefaultQuestion && hasContext) {
                            displayQuestion = '[Context] ' + saved.context;
                        } else if (hasContext) {
                            displayQuestion = displayQuestion + ' (+context)';
                        }

                        // Truncate to 200 chars
                        if (displayQuestion.length > 200) {
                            displayQuestion = displayQuestion.substring(0, 200) + '...';
                        }

                        // Get response excerpt
                        const responseText = saved.response?.response || '';
                        let responseExcerpt = responseText.length > 120
                            ? responseText.substring(0, 120) + '...'
                            : responseText;

                        const responseEl = document.createElement('div');
                        responseEl.className = 'saved-response';
                        responseEl.id = 'saved-response-' + saved._id;
                        responseEl.dataset.id = saved._id;
                        responseEl.innerHTML = `
                            <div class="saved-response-header">
                                <span class="saved-response-question">${escapeHtml(displayQuestion)}</span>
                                <span class="saved-response-date">${saved.created_at || 'Unknown date'}</span>
                            </div>
                            <div class="saved-response-preview">
                                <strong>${escapeHtml(saved.provider || 'Unknown')}</strong> /
                                ${escapeHtml(saved.model || 'Unknown')}
                            </div>
                            ${responseExcerpt ? `<div class="saved-response-excerpt">${escapeHtml(responseExcerpt)}</div>` : ''}
                            <div class="saved-response-actions">
                                <button class="btn-view" onclick="event.stopPropagation(); quickViewResponse('${saved._id}')">
                                    👁 Quick View
                                </button>
                                <button class="btn-expand" onclick="event.stopPropagation(); loadSavedResponse('${saved._id}')">
                                    📄 Full View
                                </button>
                            </div>
                        `;

                        container.appendChild(responseEl);
                    });

                    // Update offset
                    const newOffset = currentOffset + data.responses.length;
                    btn.dataset.offset = newOffset;

                    // Update button text or hide if no more
                    const remaining = total - newOffset;
                    if (remaining > 0) {
                        btn.textContent = `Load More (${remaining} remaining)`;
                        btn.disabled = false;
                    } else {
                        btn.parentElement.style.display = 'none';
                    }
                } else {
                    btn.parentElement.style.display = 'none';
                }
            } catch (error) {
                console.error('Failed to load more responses:', error);
                btn.textContent = 'Error - Try Again';
                btn.disabled = false;
            }
        }

        // Escape HTML
        function escapeHtml(text) {
            if (!text) return '';
            const div = document.createElement('div');
            div.textContent = text;
            return div.innerHTML;
        }
    </script>
</body>
</html>