<?php
// classes/Search.php
require_once __DIR__ . '/TelegramBot.php';

class Search {
    private $pdo;
    private $user;
    private $telegram;

    public function __construct($db, $user) {
        $this->pdo = method_exists($db, 'getConnection') ? $db->getConnection() : $db;
        $this->user = $user;

        // AUTO-INIT TELEGRAM BOT
        $this->telegram = new TelegramBot(TELEGRAM_BOT_TOKEN, TELEGRAM_ADMIN_CHAT_ID);
    }

    /* ============================================================
        SEND TELEGRAM API DOWN ALERT (with spam control)
    ============================================================ */
    private function sendApiDownAlert($type, $errorMessage, $query = '') {
        // Prevent spamming → store last alert time in file
        $cacheFile = __DIR__ . "/api_down_cache_$type.txt";

        if (file_exists($cacheFile)) {
            $last = intval(file_get_contents($cacheFile));
            if (time() - $last < 300) { // 5 minute throttle
                return;
            }
        }

        file_put_contents($cacheFile, time());

        $msg  = "🚨 *API DOWN ALERT*\n\n";
        $msg .= "🔍 *Type:* " . strtoupper($type) . "\n";
        if ($query) $msg .= "🔢 *Query:* `$query`\n";
      $msg .= "⚠️ *Error:* API DOWN\n";

        $msg .= "⏰ *Time:* " . date('d-M-Y H:i:s') . "\n";

        $this->telegram->sendAdminMessage($msg);
    }

    /* ============================================================
        MOBILE SEARCH
    ============================================================ */
    public function mobileSearch($userId, $mobileNumber) {
        if (!$this->validateMobileNumber($mobileNumber)) {
            return ['success' => false, 'message' => 'Invalid mobile number'];
        }

        $cost = $this->getSearchCost('mobile');
        $balance = $this->user->getWalletBalance($userId);

        if ($balance < $cost) {
            return ['success' => false, 'message' => 'Insufficient wallet balance'];
        }

        // Deduct wallet first
        $this->user->updateWalletBalance($userId, -$cost);

        // Load last cached data
        $cached = $this->pdo->prepare(
            "SELECT response_json FROM search_logs 
             WHERE type='mobile' AND query=? AND status='success'
             ORDER BY id DESC LIMIT 1"
        );
        $cached->execute([$mobileNumber]);
        $cachedRow = $cached->fetch(PDO::FETCH_ASSOC);
        $cachedData = $cachedRow ? json_decode($cachedRow['response_json'], true) : null;

        // API CALL
        $apiResponse = $this->callMobileAPI($mobileNumber);

        $invalid = (
            !$apiResponse ||
            (is_array($apiResponse) && empty($apiResponse)) ||
            isset($apiResponse['error'])
        );

        // If API DOWN → send Telegram alert
        if ($invalid) {
            $this->sendApiDownAlert("mobile", $apiResponse['message'] ?? "No Response", $mobileNumber);
        }

        // FALLBACK TO DB
        if ($invalid && $cachedData) {
            $masked = $this->applyMobileVisibility($cachedData);

            $this->logSearch($userId, 'mobile', $mobileNumber, $cachedData, $cost, 'fallback');

            return [
                'success' => true,
                'data' => $masked,
                'fallback' => true,
                'message' => 'API down — showing last saved result.'
            ];
        }

        // NO API + NO CACHE → refund
        if ($invalid && !$cachedData) {
            $this->user->updateWalletBalance($userId, $cost);
            return ['success' => false, 'message' => 'API error & no backup found'];
        }

        // VALID API RESPONSE
        $masked = $this->applyMobileVisibility($apiResponse);

        // LOG API RESULT
        $this->logSearch($userId, 'mobile', $mobileNumber, $apiResponse, $cost, 'success');

        return ['success' => true, 'data' => $masked, 'fallback' => false];
    }

    /* ============================================================
        AADHAAR SEARCH
    ============================================================ */
    public function aadhaarSearch($userId, $aadhaarNumber) {
        if (!$this->validateAadhaarNumber($aadhaarNumber)) {
            return ['success' => false, 'message' => 'Invalid Aadhaar number'];
        }

        $cost = $this->getSearchCost('aadhaar');
        $balance = $this->user->getWalletBalance($userId);

        if ($balance < $cost) {
            return ['success' => false, 'message' => 'Insufficient wallet balance'];
        }

        // Deduct wallet
        $this->user->updateWalletBalance($userId, -$cost);

        // LOAD cached
        $cached = $this->pdo->prepare(
            "SELECT response_json FROM search_logs 
             WHERE type='aadhaar' AND query=? AND status='success'
             ORDER BY id DESC LIMIT 1"
        );
        $cached->execute([$aadhaarNumber]);
        $cachedRow = $cached->fetch(PDO::FETCH_ASSOC);
        $cachedData = $cachedRow ? json_decode($cachedRow['response_json'], true) : null;

        // API CALL
        $apiResponse = $this->callAadhaarAPI($aadhaarNumber);

        $invalid = (
            !$apiResponse ||
            (is_array($apiResponse) && empty($apiResponse)) ||
            isset($apiResponse['error'])
        );

        // API DOWN alert
        if ($invalid) {
            $this->sendApiDownAlert("aadhaar", $apiResponse['message'] ?? "No Response", $aadhaarNumber);
        }

        // FALLBACK TO DB
        if ($invalid && $cachedData) {
            $masked = $this->applyAadhaarVisibility($cachedData);

            $this->logSearch($userId, 'aadhaar', $aadhaarNumber, $cachedData, $cost, 'fallback');

            return [
                'success' => true,
                'data' => $masked,
                'fallback' => true,
                'message' => 'API down — showing last saved result.'
            ];
        }

        // No cache & API failed → refund
        if ($invalid && !$cachedData) {
            $this->user->updateWalletBalance($userId, $cost);
            return ['success' => false, 'message' => 'API error & no backup found'];
        }

        // SUCCESS
        $masked = $this->applyAadhaarVisibility($apiResponse);

        $this->logSearch($userId, 'aadhaar', $aadhaarNumber, $apiResponse, $cost);

        return ['success' => true, 'data' => $masked, 'fallback' => false];
    }

    /* ============================================================
        API CALLERS (MOBILE)
    ============================================================ */
    private function callMobileAPI($mobileNumber) {
        $settings = $this->getAdminSettings();
        $baseUrl = $settings['mobile_api_url'] ?? '';

        if ($baseUrl === '') {
            return ['error' => true, 'message' => 'Mobile API URL not set'];
        }

        // Placeholder support
        if (strpos($baseUrl, '{mobile}') !== false) {
            $url = str_replace('{mobile}', urlencode($mobileNumber), $baseUrl);
        } else {
            $url = $baseUrl . urlencode($mobileNumber);
        }

        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => 20,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_USERAGENT => 'Mozilla/5.0'
        ]);

        $response = curl_exec($ch);
        $error = curl_error($ch);
        curl_close($ch);

        if ($error) return ['error' => true, 'message' => "API Error: $error"];

        $decoded = json_decode($response, true);
        if (!$decoded) return ['error' => true, 'message' => 'Invalid API response'];

        return isset($decoded['data']) ? $decoded['data'] : $decoded;
    }

    /* ============================================================
        API CALLERS (AADHAAR)
    ============================================================ */
    private function callAadhaarAPI($aadhaarNumber) {
        $settings = $this->getAdminSettings();
        $baseUrl = $settings['aadhaar_api_url'] ?? '';

        if ($baseUrl === '') {
            return ['error' => true, 'message' => 'Aadhaar API URL not set'];
        }

        if (strpos($baseUrl, '{aadhaar}') !== false) {
            $url = str_replace('{aadhaar}', urlencode($aadhaarNumber), $baseUrl);
        } else {
            $url = $baseUrl . urlencode($aadhaarNumber);
        }

        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => 25,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_USERAGENT => 'Mozilla/5.0'
        ]);

        $response = curl_exec($ch);
        $error = curl_error($ch);
        curl_close($ch);

        if ($error) return ['error' => true, 'message' => "API Error: $error"];

        $decoded = json_decode($response, true);
        if (!$decoded) return ['error' => true, 'message' => 'Invalid API response'];

        return $decoded;
    }

    /* ============================================================
        HELPERS / LOGGING
    ============================================================ */
    private function validateMobileNumber($num) {
        return preg_match('/^[6-9]\d{9}$/', $num);
    }

    private function validateAadhaarNumber($num) {
        return preg_match('/^\d{12}$/', $num);
    }

    private function getSearchCost($type) {
        $stmt = $this->pdo->prepare("SELECT setting_value FROM admin_settings WHERE setting_key=:key");
        $stmt->execute([':key' => $type . '_search_cost']);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        return $row ? (float)$row['setting_value'] : 1.0;
    }

    private function logSearch($userId, $type, $query, $response, $cost, $status='success') {
        $stmt = $this->pdo->prepare(
            "INSERT INTO search_logs (user_id, type, query, response_json, cost, status, created_at)
             VALUES (:uid, :type, :query, :resp, :cost, :status, NOW())"
        );
        $stmt->execute([
            ':uid' => $userId,
            ':type' => $type,
            ':query' => $query,
            ':resp' => json_encode($response),
            ':cost' => $cost,
            ':status' => $status
        ]);
    }

    public function getAdminSettings() {
        $stmt = $this->pdo->query("SELECT setting_key, setting_value FROM admin_settings");
        $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
        $res = [];
        foreach ($rows as $r) $res[$r['setting_key']] = $r['setting_value'];
        return $res;
    }

    /* ============================================================
        MASKING FUNCTIONS (unchanged)
    ============================================================ */
    private function maskMobileNumber($num) {
        $digits = preg_replace('/\D/', '', $num);
        if (strlen($digits) < 6) return $num;
        return substr($digits, 0, 2) . str_repeat('x', strlen($digits)-4) . substr($digits, -2);
    }

    private function applyMobileVisibility($apiData) {
        $settings = $this->getAdminSettings();

        if (is_array($apiData) && array_values($apiData) === $apiData) {
            $out = [];
            foreach ($apiData as $i) $out[] = $this->maskMobileRecord($i, $settings);
            return $out;
        }

        if (is_array($apiData)) return $this->maskMobileRecord($apiData, $settings);

        return $apiData;
    }

    private function maskMobileRecord($r, $settings) {
        if (($settings['show_name_field'] ?? '1') !== '1') $r['name'] = 'Hidden';
        if (($settings['show_mobile_field'] ?? '1') !== '1') $r['mobile'] = $this->maskMobileNumber($r['mobile'] ?? '');
        if (($settings['show_fname_field'] ?? '1') !== '1') $r['fname'] = 'Hidden';
        if (($settings['show_circle_field'] ?? '1') !== '1') $r['circle'] = 'Hidden';
        if (($settings['show_id_field'] ?? '1') !== '1') $r['id'] = 'Hidden';
        if (($settings['show_credit_field'] ?? '1') !== '1') $r['credit'] = 'Hidden';
        if (($settings['show_developer_field'] ?? '1') !== '1') $r['developer'] = 'Hidden';
        if (($settings['show_address_field'] ?? '1') !== '1') $r['address'] = 'Hidden';
        return $r;
    }

    private function applyAadhaarVisibility($apiData) {
        $settings = $this->getAdminSettings();
        $d = $apiData;

        if (isset($d['data'])) $d = $d['data'];

        if (is_array($d)) {
            if (($settings['show_address_aadhaar'] ?? '1') !== '1') $d['address'] = 'Hidden';
            if (($settings['show_homeDistName'] ?? '1') !== '1') $d['homeDistName'] = $d['homeDistrict'] = 'Hidden';
            if (($settings['show_homeStateName'] ?? '1') !== '1') $d['homeStateName'] = 'Hidden';
            if (($settings['show_allowed_onorc'] ?? '1') !== '1') $d['allowed_onorc'] = 'Hidden';
            if (($settings['show_districtCode'] ?? '1') !== '1') $d['districtCode'] = 'Hidden';
            if (($settings['show_dup_uid_status'] ?? '1') !== '1') $d['dup_uid_status'] = 'Hidden';
            if (($settings['show_fpsId'] ?? '1') !== '1') $d['fpsId'] = 'Hidden';
            if (($settings['show_schemeId'] ?? '1') !== '1') $d['schemeId'] = 'Hidden';
            if (($settings['show_schemeName'] ?? '1') !== '1') $d['schemeName'] = 'Hidden';
            if (($settings['show_memberDetailsList'] ?? '1') !== '1') $d['memberDetailsList'] = [];
        }

        if (isset($apiData['data'])) {
            $apiData['data'] = $d;
            return $apiData;
        }

        return $d;
    }
}
?>
