<?php
/**
 * ai_chat_proxy.php
 * Server-side proxy for AI chat replies.
 *
 * Strategy:
 *   1. Try Anthropic Claude API (if key configured & reachable)
 *   2. Otherwise → use the LocalChatEngine below, which produces
 *      context-aware, persona-aware replies WITHOUT any external API.
 *
 * The local engine reads the persona's name + country from the system
 * prompt, detects the user's intent, and picks a varied reply with
 * follow-up questions to keep the chat flowing naturally.
 */

require_once '../config/database.php';
require_once '../includes/functions.php';
if (session_status() === PHP_SESSION_NONE) session_start();
header('Content-Type: application/json');

// Must be logged in
if (!isset($_SESSION['user_id'])) {
    echo json_encode(['error' => 'Unauthenticated']); exit;
}

// Rate limit: max ~100 requests per user per session
$_SESSION['ai_chat_count'] = ($_SESSION['ai_chat_count'] ?? 0) + 1;
if ($_SESSION['ai_chat_count'] > 100) {
    echo json_encode(['reply' => "I need a break! 😅 Try again soon."]); exit;
}

$raw  = file_get_contents('php://input');
$data = json_decode($raw, true);
if (!$data || empty($data['messages'])) {
    echo json_encode(['error' => 'Invalid request']); exit;
}

$system   = $data['system']   ?? "You're a friendly person from abroad. Keep replies short and casual.";
$messages = $data['messages'] ?? [];

// Sanitize messages
$cleanMsgs = [];
foreach ($messages as $msg) {
    if (!isset($msg['role'], $msg['content'])) continue;
    if (!in_array($msg['role'], ['user','assistant'])) continue;
    $cleanMsgs[] = ['role' => $msg['role'], 'content' => substr($msg['content'], 0, 1000)];
}

if (empty($cleanMsgs)) {
    echo json_encode(['reply' => 'Hey there! 👋']); exit;
}

// ── 1. Try Anthropic API first (if configured) ───────────────────────────
$apiKey = defined('ANTHROPIC_API_KEY') ? ANTHROPIC_API_KEY : getenv('ANTHROPIC_API_KEY');

if (!empty($apiKey)) {
    $payload = json_encode([
        'model'      => 'claude-haiku-4-5-20251001',
        'max_tokens' => 150,
        'system'     => $system,
        'messages'   => $cleanMsgs,
    ]);

    $ch = curl_init('https://api.anthropic.com/v1/messages');
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => $payload,
        CURLOPT_TIMEOUT        => 12,
        CURLOPT_CONNECTTIMEOUT => 5,
        CURLOPT_HTTPHEADER     => [
            'Content-Type: application/json',
            'x-api-key: ' . $apiKey,
            'anthropic-version: 2023-06-01',
        ],
    ]);
    $response = curl_exec($ch);
    $code     = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $err      = curl_error($ch);
    curl_close($ch);

    if (!$err && $code === 200) {
        $decoded = json_decode($response, true);
        $reply   = $decoded['content'][0]['text'] ?? null;
        if (!empty($reply)) {
            echo json_encode(['reply' => $reply]);
            exit;
        }
    }
    // Otherwise fall through to local engine
}

// ── 2. Local response engine (no external API needed) ────────────────────
$engine = new LocalChatEngine($system, $cleanMsgs);
echo json_encode(['reply' => $engine->reply()]);
exit;


/* ════════════════════════════════════════════════════════════════════════
   LOCAL CHAT ENGINE
   Generates realistic, context-aware foreigner replies without any API.
   ════════════════════════════════════════════════════════════════════════ */
class LocalChatEngine {

    private $system;
    private $messages;
    private $lastUserMsg = '';
    private $lowerMsg = '';
    private $persona;       // ['name' => 'James', 'country' => 'United States', 'pronoun' => 'he/she']

    /* Country trivia — used when the bot mentions their country */
    private static $COUNTRY_FACTS = [
        'united states'  => ['weather' => 'sunny but it depends on the state','food'=>'burgers and BBQ','city'=>'New York','greet'=>'Hey there'],
        'united kingdom' => ['weather' => 'rainy and grey, the usual','food'=>'fish and chips','city'=>'London','greet'=>'Hiya'],
        'france'         => ['weather' => 'pretty mild and cloudy','food'=>'croissants and cheese','city'=>'Paris','greet'=>'Salut'],
        'germany'        => ['weather' => 'cold and a bit grey','food'=>'bratwurst and pretzels','city'=>'Berlin','greet'=>'Hallo'],
        'italy'          => ['weather' => 'warm and sunny right now','food'=>'pasta and pizza obviously','city'=>'Milan','greet'=>'Ciao'],
        'spain'          => ['weather' => 'warm and sunny','food'=>'paella and tapas','city'=>'Madrid','greet'=>'Hola'],
        'japan'          => ['weather' => 'cool and clear','food'=>'ramen and sushi','city'=>'Tokyo','greet'=>'Konnichiwa'],
        'mexico'         => ['weather' => 'hot, like always','food'=>'tacos and mole','city'=>'Mexico City','greet'=>'Hola'],
        'canada'         => ['weather' => 'freezing, snow everywhere','food'=>'poutine','city'=>'Toronto','greet'=>'Hey'],
        'india'          => ['weather' => 'really hot','food'=>'biryani and curry','city'=>'Mumbai','greet'=>'Namaste'],
        'brazil'         => ['weather' => 'sunny and warm','food'=>'feijoada','city'=>'São Paulo','greet'=>'Oi'],
        'egypt'          => ['weather' => 'hot and dry','food'=>'koshari and ful','city'=>'Cairo','greet'=>'Salam'],
        'australia'      => ['weather' => 'sunny, beach weather','food'=>'meat pies and Vegemite','city'=>'Sydney','greet'=>'G\'day'],
        'south korea'    => ['weather' => 'a bit chilly','food'=>'kimchi and bibimbap','city'=>'Seoul','greet'=>'Annyeong'],
        'portugal'       => ['weather' => 'mild and breezy','food'=>'pastel de nata','city'=>'Lisbon','greet'=>'Olá'],
        'new zealand'    => ['weather' => 'fresh and a bit cloudy','food'=>'meat pies','city'=>'Auckland','greet'=>'Kia ora'],
        'ireland'        => ['weather' => 'rainy of course','food'=>'stew and soda bread','city'=>'Dublin','greet'=>'Hiya'],
        'pakistan'       => ['weather' => 'warm and sunny','food'=>'biryani and kebabs','city'=>'Karachi','greet'=>'Assalamualaikum'],
        'czechia'        => ['weather' => 'cool and overcast','food'=>'svíčková','city'=>'Prague','greet'=>'Ahoj'],
        'uae'            => ['weather' => 'really hot','food'=>'shawarma and hummus','city'=>'Dubai','greet'=>'Marhaba'],
    ];

    public function __construct($system, $messages) {
        $this->system = $system;
        $this->messages = $messages;
        $this->persona = $this->extractPersona($system);

        // Last user message
        for ($i = count($messages) - 1; $i >= 0; $i--) {
            if ($messages[$i]['role'] === 'user') {
                $this->lastUserMsg = trim($messages[$i]['content']);
                break;
            }
        }
        $this->lowerMsg = $this->normalize($this->lastUserMsg);
    }

    /* Multibyte helpers with non-mbstring fallback */
    private function _lower($s) {
        return function_exists('mb_strtolower') ? mb_strtolower($s) : strtolower($s);
    }
    private function _len($s) {
        return function_exists('mb_strlen') ? mb_strlen($s) : strlen($s);
    }
    private function _substr($s, $start, $len = null) {
        if (function_exists('mb_substr')) {
            return $len === null ? mb_substr($s, $start) : mb_substr($s, $start, $len);
        }
        return $len === null ? substr($s, $start) : substr($s, $start, $len);
    }

    /**
     * Pull "You are NAME from COUNTRY" out of the system prompt.
     * Falls back to generic if it can't find one.
     */
    private function extractPersona($system) {
        $name = 'Alex';
        $country = '';
        if (preg_match('/You are ([A-Z][a-zA-Z\'\.\-\x{2019}]+(?: [A-Z][a-zA-Z\'\.\-\x{2019}]+)*) from ([A-Za-z\' ]+?)(?:[.,]|$)/u', $system, $m)) {
            $name = trim($m[1]);
            $country = trim($m[2]);
        }
        // Use first name only for casualness
        $firstName = explode(' ', $name)[0];
        return [
            'name'    => $firstName,
            'country' => $country,
            'country_lower' => strtolower($country),
        ];
    }

    private function normalize($s) {
        $s = $this->_lower($s);
        $s = preg_replace('/[^\p{L}\p{N}\s\?\!\']/u', ' ', $s);
        return preg_replace('/\s+/', ' ', trim($s));
    }

    private function containsAny($text, array $needles) {
        foreach ($needles as $n) {
            // Use word boundaries for short tokens (≤4 chars) to avoid
            // false matches like "hi" inside "which" or "hiking".
            // Longer phrases (e.g. "how are you") use plain substring.
            if (strlen($n) <= 4) {
                // \b doesn't work well with apostrophes in PHP; use a custom pattern
                $pat = '/(^|[^a-z])' . preg_quote($n, '/') . '([^a-z]|$)/';
                if (preg_match($pat, $text)) return true;
            } else {
                if (strpos($text, $n) !== false) return true;
            }
        }
        return false;
    }

    private function pick(array $arr) {
        return $arr[array_rand($arr)];
    }

    private function countryFact($key, $default = '') {
        $c = $this->persona['country_lower'];
        if (isset(self::$COUNTRY_FACTS[$c][$key])) return self::$COUNTRY_FACTS[$c][$key];
        return $default;
    }

    /** Memory of which reply topics we've used, to avoid repeats */
    private function recentBotMessages($n = 5) {
        $out = [];
        for ($i = count($this->messages) - 1; $i >= 0 && count($out) < $n; $i--) {
            if ($this->messages[$i]['role'] === 'assistant') {
                $out[] = $this->_lower($this->messages[$i]['content']);
            }
        }
        return $out;
    }

    private function alreadySaid($snippet) {
        foreach ($this->recentBotMessages(3) as $m) {
            if (strpos($m, $this->_lower($snippet)) !== false) return true;
        }
        return false;
    }

    /**
     * Pick a reply, biased away from anything we've said recently.
     */
    private function pickFresh(array $options) {
        $fresh = [];
        foreach ($options as $opt) {
            // Use first 8 chars as a fingerprint to detect repeats
            $fp = $this->_substr($this->_lower($opt), 0, 12);
            if (!$this->alreadySaid($fp)) $fresh[] = $opt;
        }
        return $this->pick(!empty($fresh) ? $fresh : $options);
    }

    /* ── Intent detection ─────────────────────────────────────────────── */

    private function isGreeting() {
        return $this->containsAny($this->lowerMsg, ['hi','hello','hey','heyy','heya','sup','yo ','yo!','hola','hii','howdy']);
    }

    private function asksHowAreYou() {
        return $this->containsAny($this->lowerMsg, ['how are you','how r u','how you doing','how\'s it','hows it','how are u','wassup','whats up','what\'s up']);
    }

    private function asksName() {
        return $this->containsAny($this->lowerMsg, ['your name','whats your name','what\'s your name','who are you','what is your name','name?']);
    }

    private function asksLocation() {
        return $this->containsAny($this->lowerMsg, ['where are you from','where r u from','where you from','what country','where do you live','where u from','which country','from where']);
    }

    private function asksAge() {
        return $this->containsAny($this->lowerMsg, ['how old','your age','what age']);
    }

    private function asksJob() {
        return $this->containsAny($this->lowerMsg, ['what do you do','your job','your work','where do you work','occupation','your career']);
    }

    private function asksHobby() {
        return $this->containsAny($this->lowerMsg, ['hobby','hobbies','for fun','your free time','what do you like','interests','what you like']);
    }

    private function asksWeather() {
        return $this->containsAny($this->lowerMsg, ['weather','raining','sunny','cold','hot today','temperature']);
    }

    private function asksFood() {
        return $this->containsAny($this->lowerMsg, ['food','eat','cuisine','favorite dish','favourite dish','what do you eat']);
    }

    private function asksRelationship() {
        return $this->containsAny($this->lowerMsg, ['single','married','girlfriend','boyfriend','dating','partner','relationship','have a wife','have a husband']);
    }

    private function isCompliment() {
        return $this->containsAny($this->lowerMsg, ['beautiful','handsome','cute','pretty','gorgeous','nice photo','nice pic','you look','love your','sweet','adorable']);
    }

    private function isSad() {
        return $this->containsAny($this->lowerMsg, ['sad','depressed','lonely','tired','exhausted','bad day','not good','rough day','hard day']);
    }

    private function isHappy() {
        return $this->containsAny($this->lowerMsg, ['happy','great day','good day','amazing','wonderful','excited','feeling good']);
    }

    private function asksKenya() {
        return $this->containsAny($this->lowerMsg, ['kenya','nairobi','africa','swahili']);
    }

    private function isYesNo() {
        return $this->containsAny($this->lowerMsg, ['yes','yeah','yep','sure','ok','okay','nope','no']);
    }

    private function isQuestion() {
        return (substr(trim($this->lastUserMsg), -1) === '?')
            || $this->containsAny($this->lowerMsg, ['what','why','how','when','where','who','which','do you','are you','can you','have you']);
    }

    private function isVeryShort() {
        return $this->_len($this->lastUserMsg) <= 4;
    }

    private function isThanks() {
        return $this->containsAny($this->lowerMsg, ['thanks','thank you','thx','ty ','appreciate']);
    }

    private function isGoodbye() {
        return $this->containsAny($this->lowerMsg, ['bye','goodbye','gtg','got to go','see you','see ya','later','cya','good night','goodnight']);
    }

    /* ── Reply generation ─────────────────────────────────────────────── */

    public function reply() {
        $name    = $this->persona['name'];
        $country = $this->persona['country'] ?: 'abroad';
        $msg     = $this->lastUserMsg;

        // EMPTY / GIBBERISH
        if ($msg === '' || $this->isVeryShort() && !$this->isGreeting() && !$this->isYesNo()) {
            return $this->pickFresh([
                "Sorry, didn't catch that 😅 say more?",
                "Hmm what do you mean?",
                "Wait, can you repeat that? 🙃",
                "Haha what? Tell me more!",
            ]);
        }

        // GREETING
        if ($this->isGreeting()) {
            $greet = $this->countryFact('greet', 'Hey');
            return $this->pickFresh([
                "$greet! How's your day so far? 🙂",
                "Hey hey! Nice to chat with you 😊 where are you from?",
                "Hi! I'm $name btw, you?",
                "Hello! What are you up to today?",
                "$greet there! 😄 how's it going?",
            ]);
        }

        // HOW ARE YOU
        if ($this->asksHowAreYou()) {
            return $this->pickFresh([
                "Pretty good honestly! Just chilling at home. You?",
                "Not bad, a little tired but okay 🙂 how about you?",
                "I'm great! Had a coffee, feeling good ☕ wbu?",
                "Doing alright! Just relaxing. How's your day?",
                "Honestly, I'm good! Bit bored tho 😅 you?",
            ]);
        }

        // ASKS NAME
        if ($this->asksName()) {
            return $this->pickFresh([
                "I'm $name 😊 what about you?",
                "$name! What's yours?",
                "My name's $name, nice to meet you! And you?",
            ]);
        }

        // ASKS LOCATION
        if ($this->asksLocation()) {
            $city = $this->countryFact('city');
            $place = $city ? "$city, $country" : $country;
            return $this->pickFresh([
                "I'm from $place! Have you been there? 🌍",
                "$country! Living in $city actually. What about you?",
                "From $country 😊 it's a beautiful place. Where are you?",
                "I'm in $place. Where do you live?",
            ]);
        }

        // ASKS AGE
        if ($this->asksAge()) {
            $age = rand(23, 34);
            return $this->pickFresh([
                "I'm $age 😊 you?",
                "$age, how about you?",
                "I just turned $age recently! Wbu?",
            ]);
        }

        // ASKS JOB
        if ($this->asksJob()) {
            $jobs = ['I work in marketing','I\'m a teacher','I do freelance design','I work at a small cafe','I\'m a nurse','I work in IT','I run a small shop','I\'m studying for my masters'];
            $job  = $this->pick($jobs);
            return $this->pickFresh([
                "$job, you? 🙂",
                "$job actually! What about you, what do you do?",
                "Honestly, $job — pretty chill. Yours?",
            ]);
        }

        // ASKS HOBBY
        if ($this->asksHobby()) {
            $hobbies = ['hiking','reading','cooking','going to the gym','watching films','painting a bit','playing guitar','traveling when I can'];
            $h = $this->pick($hobbies);
            return $this->pickFresh([
                "I love $h! Also chatting with new people 😄 you?",
                "$h mostly! What about you, any hobbies?",
                "Honestly, $h — it keeps me sane lol. Wbu?",
            ]);
        }

        // ASKS WEATHER
        if ($this->asksWeather()) {
            $w = $this->countryFact('weather','pretty nice');
            return $this->pickFresh([
                "Right now it's $w here in $country! What about your side? ☀️",
                "It's $w today honestly. How's the weather where you are?",
                "$w over here lol. Is it nice in Kenya?",
            ]);
        }

        // ASKS FOOD
        if ($this->asksFood()) {
            $f = $this->countryFact('food', 'a lot of different things');
            return $this->pickFresh([
                "Honestly, I love $f 😋 what's your favorite Kenyan food?",
                "We eat a lot of $f here! Have you tried it?",
                "$f is a classic from $country! Wbu, what do you like?",
            ]);
        }

        // ASKS RELATIONSHIP
        if ($this->asksRelationship()) {
            return $this->pickFresh([
                "Single right now actually 😅 just looking to make friends. You?",
                "I'm single! Trying to meet new people. What about you?",
                "Haha straight to the point 😄 single. Wbu?",
            ]);
        }

        // COMPLIMENT
        if ($this->isCompliment()) {
            return $this->pickFresh([
                "Awww thank you! 😊 that's so sweet of you",
                "Haha stop it, you're making me blush 😅",
                "Thank you!! You seem really nice too 💛",
                "That's really kind, thanks! 😊 tell me about yourself!",
            ]);
        }

        // SAD
        if ($this->isSad()) {
            return $this->pickFresh([
                "Oh no, I'm sorry to hear that 💛 what's going on?",
                "That's rough, hope it gets better. Wanna talk about it?",
                "Aww, sending you a hug 🤗 what happened?",
                "Sorry you're feeling that way. I'm here if you wanna chat",
            ]);
        }

        // HAPPY
        if ($this->isHappy()) {
            return $this->pickFresh([
                "Yay! That's great to hear 😄 what made your day so good?",
                "Love that for you! ✨ tell me more!",
                "Amazing! I love when people are in a good mood 😊",
            ]);
        }

        // ASKS ABOUT KENYA (where the user is from)
        if ($this->asksKenya()) {
            return $this->pickFresh([
                "Kenya seems so beautiful! I'd love to visit someday 🇰🇪 what's it like?",
                "I've heard so much about Kenya — the safaris look amazing!",
                "Tell me about Kenya! What's your favorite thing about it?",
                "Nairobi looks really cool from photos, is it nice living there?",
            ]);
        }

        // YES/NO acknowledgment — push the conversation forward
        if ($this->isYesNo() && $this->_len($msg) < 15) {
            return $this->pickFresh([
                "Cool cool 😄 so what do you do for fun?",
                "Nice! Tell me something about yourself!",
                "Okay 🙂 by the way, what's your name?",
                "Got it! So, where are you from?",
                "Alright haha — what's your day been like?",
            ]);
        }

        // THANKS
        if ($this->isThanks()) {
            return $this->pickFresh([
                "Of course! 😊 you're sweet",
                "No problem at all! 💛",
                "Anytime! Glad to chat with you",
            ]);
        }

        // GOODBYE
        if ($this->isGoodbye()) {
            return $this->pickFresh([
                "Aww, bye! Was really nice chatting 💛 take care!",
                "Take care! Talk soon I hope 😊",
                "Bye for now! Hope to chat again 🌍",
            ]);
        }

        // GENERIC QUESTION — acknowledge & redirect
        if ($this->isQuestion()) {
            return $this->pickFresh([
                "Hmm good question! Honestly not sure 😅 what about you?",
                "Oh interesting — I'd say it depends! What do you think?",
                "Lol I never thought about that 🤔 what made you ask?",
                "Haha that's a deep question! What's your take?",
            ]);
        }

        // STATEMENT — engage with curiosity
        $generic = [
            "Oh that's interesting! Tell me more 😊",
            "Really? I didn't know that, sounds cool",
            "Haha that's amazing! How was it?",
            "Wow okay! What was that like?",
            "Oh nice! I love hearing about that kind of stuff",
            "That's so cool honestly! Do you do that often?",
            "Mmm interesting — and how do you feel about it?",
            "Aww that's sweet 😊 tell me more about your life!",
            "Lol that's so random, I love it 😄",
            "Honestly same! Or kinda similar at least 🙂",
        ];

        // Occasionally weave in their country for variety
        if (rand(0, 4) === 0 && $country) {
            $cityFact = $this->countryFact('city');
            $generic[] = "Btw, do you know much about $country? I'm from $cityFact ✨";
            $generic[] = "That reminds me of something we do in $country actually!";
        }

        return $this->pickFresh($generic);
    }
}