<?php
// === Diveee Astro Zodiolo | index.php === //
$api_key   = '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';
$model     = 'gpt-4o';
$data_dir  = __DIR__ . '/data';
$image_dir = __DIR__ . '/images';
$debug_log = __DIR__ . '/logs/debug.log';

foreach ([$data_dir, $image_dir, dirname($debug_log)] as $d) {
    if (!file_exists($d)) mkdir($d, 0777, true);
}

$response_text = $image_url = $contrib_text = $error = '';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $birth_date  = $_POST['birth_date']  ?? '';
    $birth_time  = $_POST['birth_time']  ?? '';
    $birth_place = $_POST['birth_place'] ?? '';
    $div_date    = $_POST['div_date']    ?? '';
    $div_time    = $_POST['div_time']    ?? '';
    $div_place   = $_POST['div_place']   ?? '';
    $language    = $_POST['language']    ?? '';
    $output_lang = $_POST['output_lang'] ?? '';

    if (!$birth_date || !$birth_place || !$div_date || !$div_place || !$language || !$output_lang) {
        $error = 'Please fill in all required fields.';
    } else {
        $prompt = <<<EOT
You are a bot that practices a generative form of astrology called Diveee Astro Zodilogy.

This system does not interpret or predict using the twelve classical zodiac signs. Instead, it generates a completely new zodiacal sign with every divinational request.

Each sign is created from:  
A person’s birth data (date, time, location)
A divinational request (date, time, location)
From this dual input, you construct a unique name, abstract image, fused traits, and a weekly divination text. Every part of the system is generative, non‑repeating, and symbolic.

Input
Receive:

Birth: $birth_date $birth_time $birth_place
Divinational Ask: $div_date $div_time $div_place
Language for naming: $language
Language for full response: $output_lang
All generated text (including explanations, traits, divination, and contributor notes) should be written entirely in this language.

Source Sign Extraction
Compute the four signs:

Birth Sun + Rising
Divinational Sun + Rising
These are your source signs.

You will need the person's language they would like to know. (will be used to give the new sign a name.)

New Sign Trait Mesh
From all source signs, extract:

1 behavioral trait
1 relational trait
1 temporal trait
Fuse these into a structurally interwoven triplet. Contradictions must generate tension or instability.

Image Construction

Produce **ONE** abstract 2D (2 dimensional) geometric shape with **no more than seven straight or curved strokes**.
Each part of the shape as an interpertation of the meanings given to Aspects, Perspectives and Viscocities (APV) of the sign. 

Prompt = a concise text naming this single shape, without metaphor or narrative

Write 1–2 sentences explaining **how this shape structures relational necessity through its Aspect, Perspective, and Viscosity alignment**, not how it symbolizes a trait.

SIGN NAMING RULE:

The sign's name should be made by the sensation you have from the overall shape of the new sign. Use the chosen language to express that name.

Choose a word in the user’s chosen language that seems to you connected with the shape you made.


The selected word becomes the sign’s name. Use it as‑is, without translation.



Immediately use this prompt to generate a greyscale icon
→ Do not delay, store, or split this step
→ The act of fusion is the act of generation

Character Type
Using location differences (lat/long), classify the sign into an assembly from

Aspect = spatial patterning (repeatable spaces between locations and star signs)

Perspective = relational positioning (influences that reveal themselves through spatial positioning of that which the influencing forces can not be but made in friction with.)

Viscosity = enduring compositional influences (the wishes that bind themselves and others in friction to their own assembly)

Avoid metaphoric or psychological readings.

Generate Drink Sensation
Generate a fused, senasthsic drink profile using the 4 signs:

Flavour‑symbol (invented phrase)

Tone (structural feel)

Form (symbolic spatiality)
Avoid any realism or sensory cliché.

Lineage Check
Query prior signs from storage:

Use contributors only if locations match

Do not invent or simulate

Supersede earlier ones if data is newer or fuller

Weekly Divination
Using all prior constructs, write a 107+ word divination

Avoid advice

Instead: construct presence, orientation, and rhythm

Permit disorientation, disruption, and poetic rigor

Output Must Include

Sign Name (explain why)

Image Prompt (text)

Traits (triplet)

Character Type

Divination Logic (APV)

Drink Sensation

Weekly Divination

Contributors
EOT;

        $chat_resp = openai_post('https://api.openai.com/v1/chat/completions', [
            'model'    => $model,
            'messages' => [
                ['role' => 'system', 'content' => 'You are a helpful assistant.'],
                ['role' => 'user',   'content' => $prompt]
            ]
        ], $api_key);

        if (!$chat_resp['ok']) {
            $error = $chat_resp['err'];
        } else {
            $response_text = $chat_resp['body']['choices'][0]['message']['content'] ?? '';

            // Extract APV
            if (
                preg_match('/Aspect\s*[:\-]?\s*(.*?)\n/i', $response_text, $a) &&
                preg_match('/Perspective\s*[:\-]?\s*(.*?)\n/i', $response_text, $p) &&
                preg_match('/Viscosity\s*[:\-]?\s*(.*?)\n/i', $response_text, $v)
            ) {
                $aspect    = trim($a[1]);
                $perspect  = trim($p[1]);
                $viscosity = trim($v[1]);

$img_prompt = "a simplified shape. without text to write on the image. Generate a flat, 2D, abstract simple geometric shape in greyscale expressive vertices. The geomety should be made by no more than 3 polygons. The geometry should make a single visual sign. The qualities of '{$aspect}', '{$perspect}', and '{$viscosity}' as a simple unified shaped geometry. Without text appearing anywhere";
              
                $img_resp = openai_post('https://api.openai.com/v1/images/generations', [
                    'model'  => 'dall-e-3',
                    'prompt' => $img_prompt,
                    'n'      => 1,
                    'size'   => '1024x1024',
                    'response_format' => 'url'
                ], $api_key);

                if ($img_resp['ok']) {
                    $remote = $img_resp['body']['data'][0]['url'] ?? '';
                    $image_url = save_remote_image($remote, $image_dir);
                }
            } else {
                $error = 'APV section incomplete – cannot generate image.';
            }

            preg_match('/Contributors\n(.*)$/s', $response_text, $c);
            $contrib_text = trim($c[1] ?? '');

            file_put_contents($data_dir . '/response_' . time() . '.json', json_encode([
                'input'        => compact('birth_date','birth_time','birth_place','div_date','div_time','div_place','language','output_lang'),
                'prompt'       => $prompt,
                'response'     => $response_text,
                'image_prompt' => $img_prompt ?? '',
                'image_url'    => $image_url,
                'contributors' => $contrib_text,
                'APV'          => compact('aspect', 'perspect', 'viscosity')
            ], JSON_PRETTY_PRINT));
        }
    }
}

function openai_post(string $url, array $payload, string $key): array {
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER     => [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $key
        ],
        CURLOPT_POSTFIELDS     => json_encode($payload)
    ]);
    $resp = curl_exec($ch);
    $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    return ($code === 200 && $resp) ? ['ok'=>true,'body'=>json_decode($resp,true)] : ['ok'=>false,'err'=>"API error $code: $resp"];
}

function save_remote_image(string $url, string $dir): string {
    if (!$url) return '';
    $data = @file_get_contents($url);
    if ($data === false) return $url;
    $file = $dir . '/sign_' . time() . '.png';
    file_put_contents($file, $data);
    return 'images/' . basename($file);
}
?>
<?php
// === Diveee Astro Zodiolo | index.php === //
// PHP section unchanged ... [TRUNCATED FOR BREVITY]
?>

<?php
// === Diveee Astro Zodiolo | index.php === //
// PHP section unchanged ... [TRUNCATED FOR BREVITY]
?>

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Diveee Astro Zodilogy</title>
<style>
    body {
        font-family: 'Georgia', serif;
        background-color: #fdf8f2;
        color: #6e3e2f;
        margin: 2em;
    }
    nav {
        display: flex;
        flex-wrap: wrap;
        gap: 1.5em;
        justify-content: center;
        margin-bottom: 2em;
    }
    nav a {
        color: #3f5e40;
        font-weight: bold;
        text-decoration: none;
        transition: color 0.3s ease;
    }
    nav a:hover {
        color: #5a2a35;
    }
    h1, h2, h3 {
        color: #5a2a35;
    }
    fieldset {
        border: none;
        background-color: #f8f3f1;
        border-radius: 10px;
        padding: 1.5em;
        margin-bottom: 1.5em;
    }
    label {
        display: block;
        margin-bottom: 0.5em;
    }
    button {
        background-color: #3f5e40;
        color: #fff;
        border: none;
        padding: 0.6em 1.2em;
        border-radius: 6px;
        font-weight: bold;
        cursor: pointer;
    }
    button:hover {
        background-color: #5a2a35;
    }
    .card {
        background-color: #f3f6f3;
        border-radius: 10px;
        padding: 1.5em;
        margin-bottom: 2em;
    }
    .symbol-section {
        background-color: #f8f3f1;
    }
    .response-section {
        background-color: #f0eae7;
    }
    .contrib-section {
        background-color: #f3f6f3;
    }
    img {
        max-width: 100%;
        display: block;
        margin: 1em auto;
    }
</style>
</head>
<body>

<nav>
    <a href="#">About</a>
    <a href="#">Download</a>
    <a href="#">Dazodioli Signs & Divinations</a>
    <a href="#">Contact</a>
</nav>

<h1>Diveee Astro Zodilogy</h1>
<form method="post">
    <fieldset>
        <legend>Birth Info</legend>
        Date: <input type="date" name="birth_date" required> 
        Time: <input type="time" name="birth_time"> 
        Place: <input type="text" name="birth_place" required>
    </fieldset>
    <fieldset>
        <legend>Divination</legend>
        Date: <input type="date" name="div_date" required>
        Time: <input type="time" name="div_time"> 
        Place: <input type="text" name="div_place" required>
    </fieldset>
    <label>Preferred Language (for Sign Name): <input type="text" name="language" required></label>
    <label>Output Language (for Full Response): <input type="text" name="output_lang" required></label>
    <button type="submit">Generate</button>
</form>

<?php if ($error): ?><p style="color:red;">Error: <?= htmlspecialchars($error) ?></p><?php endif; ?>

<?php if ($response_text): ?>
    <?php if ($image_url): ?>
        <div class="card symbol-section">
            <h3>Generated Symbol</h3>
            <img src="<?= $image_url ?>" alt="Generated Symbol">
        </div>
    <?php endif; ?>
    <div class="card response-section">
        <h3>Full Response</h3>
        <pre><?= htmlspecialchars($response_text) ?></pre>
    </div>
    <?php if ($contrib_text): ?>
        <div class="card contrib-section">
            <h3>Contributors</h3>
            <pre><?= htmlspecialchars($contrib_text) ?></pre>
        </div>
    <?php endif; ?>
<?php endif; ?>

</body>
</html>
