<?php

namespace App\Controllers;

use App\Core\Controller;
use App\Config\Database;
use PDO;

class AnonController extends Controller {
    private $db;

    public function __construct() {
        $this->db = Database::getInstance()->getConnection();
    }

    public function start() {
        $input = $this->input();
        $this->validate($input, [
            'owner_slug' => 'required',
            'visitor_hash' => 'required'
        ]);

        $ownerSlug = $input['owner_slug'];
        $visitorHash = $input['visitor_hash'];

        // 1. Find Owner
        $stmt = $this->db->prepare("SELECT id FROM users WHERE link_slug = ?");
        $stmt->execute([$ownerSlug]);
        $owner = $stmt->fetch();

        if (!$owner) {
            $this->json(['error' => 'User not found'], 404);
        }

        $ownerId = $owner['id'];

        // 2. Check if session exists
        $stmt = $this->db->prepare("SELECT * FROM anonymous_sessions WHERE owner_user_id = ? AND visitor_hash = ?");
        $stmt->execute([$ownerId, $visitorHash]);
        $session = $stmt->fetch();

        $conversationId = null;
        $anonLabel = null;
        $visitorUserId = null;

        $stableUserId = null;
        if (preg_match('/^user_stable_(\d+)$/', $visitorHash, $m)) {
            $stableUserId = (int)$m[1];
            $stmt = $this->db->prepare("SELECT id FROM users WHERE id = ? LIMIT 1");
            $stmt->execute([$stableUserId]);
            if (!$stmt->fetch(PDO::FETCH_ASSOC)) {
                $stableUserId = null;
            }
        }

        if ($stableUserId !== null) {
            $visitorUserId = $stableUserId;
            $anonLabel = $session && isset($session['anon_label']) ? $session['anon_label'] : null;
            if (!$anonLabel) {
                $anonLabel = 'Anon' . rand(100, 999);
                if ($session) {
                    $stmt = $this->db->prepare("UPDATE anonymous_sessions SET anon_label = ? WHERE id = ?");
                    $stmt->execute([$anonLabel, $session['id']]);
                } else {
                    $stmt = $this->db->prepare("INSERT INTO anonymous_sessions (owner_user_id, visitor_hash, anon_label) VALUES (?, ?, ?)");
                    $stmt->execute([$ownerId, $visitorHash, $anonLabel]);
                }
            }

            $userA = min($ownerId, $visitorUserId);
            $userB = max($ownerId, $visitorUserId);
            $stmt = $this->db->prepare("SELECT id FROM conversations WHERE user_a_id = ? AND user_b_id = ? AND is_anonymous = 1");
            $stmt->execute([$userA, $userB]);
            $conv = $stmt->fetch(PDO::FETCH_ASSOC);
            if ($conv) {
                $conversationId = $conv['id'];
            }
        } elseif ($session) {
            // Existing session
            $anonLabel = $session['anon_label'];
            
            // Reconstruct shadow username
            $uniqueString = $ownerId . "_" . $visitorHash;
            $shadowUsername = "anon_" . md5($uniqueString);
            
            $stmt = $this->db->prepare("SELECT id FROM users WHERE username = ?");
            $stmt->execute([$shadowUsername]);
            $shadowUser = $stmt->fetch();
            
            if ($shadowUser) {
                $visitorUserId = $shadowUser['id'];
                
                // Find conversation
                $stmt = $this->db->prepare("SELECT id FROM conversations WHERE (user_a_id = ? AND user_b_id = ?) OR (user_a_id = ? AND user_b_id = ?)");
                $stmt->execute([$ownerId, $visitorUserId, $visitorUserId, $ownerId]);
                $conv = $stmt->fetch();
                if ($conv) {
                    $conversationId = $conv['id'];
                }
            } else {
                // Inconsistent state: Session exists but User is missing.
                // Treat as new session (Force guest mode)
                $session = null;
            }
        }
        
        if (!$session) {
            // NEW SESSION or Fallback
            // ...
            // Just generate a provisional Guest Token.
            // The Shadow User & Session will be created when they send the first message.
            
            $anonLabel = 'Anon' . rand(100, 999);
            
            // We set visitorUserId to a special string "guest:OWNERID:HASH:LABEL"
            // This will be parsed by MessageController
            $visitorUserId = "guest:{$ownerId}:{$visitorHash}:{$anonLabel}";
        }
        
        // Generate Token
        $payload = [
            'iss' => 'anon-chat',
            'sub' => $visitorUserId, // Can be ID or "guest:..." string
            'iat' => time(),
            'exp' => time() + (60 * 60 * 24), // 1 day
            'scope' => 'anonymous',
            'alias' => $anonLabel
        ];
        $token = \App\Utils\JWT::encode($payload, \App\Utils\Env::get('JWT_SECRET'));

        $this->json([
            'conversation_id' => $conversationId,
            'anon_label' => $anonLabel,
            'token' => $token, 
            'visitor_id' => $visitorUserId,
            'owner_id' => $ownerId
        ]);
    }
}
