<?php
$datetime = date("Y-m-d H:i:s");
$txt  = "\n$datetime - ".$_SERVER['PHP_SELF']."\n";
$txt .= print_r($user, true);
$txt .= print_r($_POST, true);
$txt .= print_r($_FILES, true);

if ( !$user['superAdmin'] ) {
    $txt .= "403 not superAdmin\n";
    $txt .= "done\n\n\n\n";
    $file = fopen(PATH_LOGS.'/btb.send-ai-message.log', "a");
    fwrite($file, $txt);
    fclose($file);

    http_response_code(403);
    echo json_encode('You do not have permission to use AI tools');
    exit;
}

if ( !isset($_POST['prompt']) ) {
    $txt .= "400 invalid prompt\n";
    $txt .= "done\n\n\n\n";
    $file = fopen(PATH_LOGS.'/btb.send-ai-message.log', "a");
    fwrite($file, $txt);
    fclose($file);

    http_response_code(400);
    echo json_encode('You must provide a valid prompt');
    exit;
} else {
    $prompt = $_POST['prompt'];
}

$systemPrompt = ( isset($_POST['systemPrompt']) )
    ? $_POST['systemPrompt']
    : NULL
;

$model = ( isset($_POST['model']) )
    ? $_POST['model']
    // : 'claude-3-5-sonnet-20241022'
    // : 'claude-3-5-sonnet-latest'
    : 'claude-sonnet-4-20250514'
;

$whitelist = [
    'jpg' => 'image',
    'jpeg' => 'image',
    'png' => 'image',
    'webp' => 'image',
    'pdf' => 'document',
    'JPG' => 'image',
    'JPEG' => 'image',
    'PNG' => 'image',
    'WEBP' => 'image',
    'PDF' => 'document',
];

$payload = [
    'model' => $model,
    'messages' => [],
    'max_tokens' => 4096,
    'tools' => [
        [
            'type' => 'web_search_20250305',
            'name' => 'web_search',
            'max_uses' => 5
        ],
    ]
];

if ( isset($_POST['conversationId']) && !empty($_POST['conversationId']) ) {
    if ( $conversation = $db->row("SELECT * FROM ai_conversation WHERE id = ?", $_POST['conversationId']) ) {
        $messages = $db->run("SELECT * FROM ai_message WHERE conversationId = ? ORDER BY createdAt ASC", $conversation['id']);
        foreach ( $messages as $message ) {
            $payload['messages'][] = [
                'role' => $message['role'],
                'content' => [
                    [
                        'type' => 'text',
                        'text' => $message['text']
                    ]
                ]
            ];

            $message['attachments'] = $db->run("SELECT * FROM ai_attachment WHERE messageId = ?", $message['id']);
            foreach ( $message['attachments'] as $attachment ) {
                $payload['messages'][count($payload['messages']) - 1]['content'][] = [
                    'type' => $whitelist[pathinfo(PATH_AI_ATTACHMENTS.'/'.$attachment['filename'], PATHINFO_EXTENSION)],
                    'source' => [
                        'type' => 'base64',
                        'media_type' => mime_content_type(PATH_AI_ATTACHMENTS.'/'.$attachment['filename']),
                        'data' => base64_encode(file_get_contents(PATH_AI_ATTACHMENTS.'/'.$attachment['filename']))
                    ],
                    'cache_control' => [
                        'type' => 'ephemeral'
                    ]
                ];
            }
        }
        $payload['messages'][] = [
            'role' => 'user',
            'content' => [
                [
                    'type' => 'text',
                    'text' => $prompt
                ]
            ]
        ];
        if ( $conversation['systemPrompt'] ) {
            $payload['system'] = $conversation['systemPrompt'];
        }
    }
} else {
    $txt .= "new conversation\n";
    $payload['messages'] = [
        [
            'role' => 'user',
            'content' => [
                [
                    'type' => 'text',
                    'text' => $prompt
                ]
            ]
        ]
    ];
    if ( $systemPrompt ) {
        $payload['system'] = $systemPrompt;
    }
}

if ( !empty($_FILES['files']['name'][0]) ) {
    $txt .= "looping over uploaded files\n";
    $numFiles = count($_FILES['files']['name']);
    if ( $numFiles > 10 ) {
        $txt .= "400 too many files\n";
        $txt .= "done\n\n\n\n";
        $file = fopen(PATH_LOGS.'/btb.send-ai-message.log', "a");
        fwrite($file, $txt);
        fclose($file);
        
        http_response_code(400);
        echo json_encode('You uploaded too many files. Max 10');
        exit;
    }

    $files = [];
    for ( $i = 0; $i < $numFiles; $i++ ) {
        $ext = pathinfo($_FILES['files']['name'][$i], PATHINFO_EXTENSION);

        if ( !in_array($ext, array_keys($whitelist)) ) {
            $txt .= "400 invalid file type: $ext\n";
            $txt .= "done\n\n\n\n";
            $file = fopen(PATH_LOGS.'/btb.send-ai-message.log', "a");
            fwrite($file, $txt);
            fclose($file);
            
            http_response_code(400);
            echo json_encode("You uploaded an unsupported file type of $ext");
        }

        $filename = strtotime($datetime).'-'.$_FILES['files']['name'][$i];
        if ( !move_uploaded_file($_FILES['files']['tmp_name'][$i], PATH_AI_ATTACHMENTS.'/'.$filename) ) {
            $txt .= "500 file move failed\n";
            $txt .= "done\n\n\n\n";
            $file = fopen(PATH_LOGS.'/btb.send-ai-message.log', "a");
            fwrite($file, $txt);
            fclose($file);
            
            http_response_code(500);
            echo json_encode('There was a problem moving your file upload(s)');
        }

        $files[$i]['messageId'] = NULL;
        $files[$i]['filename'] = $filename;
        $files[$i]['createdBy'] = $user['id'];
        $files[$i]['createdAt'] = $datetime;
        $db->insert('ai_attachment', $files[$i]);
        $txt .= "attachment inserted\n";

        $payload['messages'][count($payload['messages']) - 1]['content'][] = [
            'type' => $whitelist[$ext],
            'source' => [
                'type' => 'base64',
                'media_type' => mime_content_type(PATH_AI_ATTACHMENTS.'/'.$filename),
                'data' => base64_encode(file_get_contents(PATH_AI_ATTACHMENTS.'/'.$filename))
            ],
            'cache_control' => [
                'type' => 'ephemeral'
            ]
        ];
    }
}

$txt .= "payload set:\n";
$txt .= print_r($payload, true);

$start = date('Y-m-d H:i:s');

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.anthropic.com/v1/messages");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json', 'x-api-key: '.CLAUDE_API_TOKEN, 'Anthropic-Version: 2023-06-01', 'anthropic-beta: pdfs-2024-09-25,prompt-caching-2024-07-31']);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));

$response = json_decode(curl_exec($ch));
$responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$txt .= "curl sent\n";
$txt .= print_r($response, true);

$stop = date('Y-m-d H:i:s');

if ( $responseCode !== 200 ) {
    $txt .= "non-200 response from api: \n";
    $txt .=  print_r($response, true)."\n";
    $txt .= "done\n\n\n\n";
    $file = fopen(PATH_LOGS.'/btb.send-ai-message.log', "a");
    fwrite($file, $txt);
    fclose($file);

    http_response_code(400);
    echo json_encode("There was an error: ".print_r($response, true));
    exit;
}

// $text = $response->content[0]->text;
$text = '';
foreach ( $response->content as $content ) {
    switch ( $content->type ) {
        case 'text' :
            $text .= $content->text;
            break;
        case 'server_tool_use' :
            if ( $content->name === 'web_search' ) {
                $text .= '[websearch]I searched the web for [searchquery]"'.$content->input->query.'".[/searchquery] Results:[/websearch]';
            }
            break;
        case 'web_search_tool_result' :
            if ( isset($content->content) ) {
                foreach ( $content->content as $result ) {
                    $text .= '[searchresult][resulturl]'.$result->url.'[/resulturl][resulttitle]'.$result->title.'[/resulttitle][/searchresult]';
                }
            }
            break;
    }
}

$tokensOut = $response->usage->output_tokens;
$tokensIn = $response->usage->input_tokens;
$tokensIn += $response->usage->cache_creation_input_tokens;
$tokensIn += $response->usage->cache_read_input_tokens;

if ( $conversation ) {
    $db->update('ai_conversation', ['model' => $model, 'updatedAt' => $stop], ['id' => $conversation['id']]);
    $txt .= "conversation updated\n";
} else {
    $db->insert('ai_conversation', ['createdBy' => $user['id'], 'model' => $model, 'systemPrompt' => $systemPrompt, 'createdAt' => $start]);
    $conversation = $db->row("SELECT * FROM ai_conversation WHERE model = ? AND createdBy = ? AND createdAt = ?", $model, $user['id'], $start);
    $txt .= "conversation inserted\n";
}

$db->insert('ai_message', [
    'anthropicId' => $response->id, 
    'conversationId' => $conversation['id'],
    'role' => 'assistant', 
    'text' => $text, 
    'tokens' => $tokensOut,
    'createdAt' => $stop
]);
$txt .= "ai response inserted\n";

$parentId = $db->cell("SELECT id FROM ai_message WHERE anthropicId = ?", $response->id);

$db->insert('ai_message', [
    'parentId' => $parentId,
    'conversationId' => $conversation['id'],
    'role' => 'user', 
    'text' => $prompt, 
    'tokens' => $tokensIn,
    'createdAt' => $start
]);
$txt .= "prompt inserted\n";

$childId = $db->cell("SELECT id FROM ai_message WHERE parentId = ?", $parentId);

foreach ( $files as $file ) {
    $db->update('ai_attachment', ['messageId' => $childId], ['filename' => $file['filename'], 'createdBy' => $user['id'], 'createdAt' => $datetime]);
}
$txt .= "attachment messageIds updated\n";

$conversationTokens = $db->cell("SELECT SUM(tokens) FROM ai_message WHERE conversationId = ?", $conversation['id']);

ob_start();
include '../template/ai-response.php';
$html = ob_get_clean();
$txt .= "template rendered\n";

$txt .= "done\n\n\n\n";
$file = fopen(PATH_LOGS.'/btb.send-ai-message.log', "a");
fwrite($file, $txt);
fclose($file);

http_response_code(200);
echo json_encode(['conversationId' => $conversation['id'], 'html' => $html, 'raw' => $response, 'optionText' => $conversation['createdAt'].' - '.substr($prompt, 0, 30).'...', 'conversationTokens' => $conversationTokens]);