<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

/**
 * Public thumbs feedback for AI Knowledge Agent answers.
 *
 * Customers reach this endpoint via tokenised links rendered into
 * their inbound channel (email, widget, WhatsApp interactive button).
 * No authentication: the link itself proves which row may be updated,
 * using an HMAC signature bound to APP_KEY that AIManager generates
 * at reply-send time.
 *
 * GET (not POST) so the link works in plain-HTML emails without JS.
 * Idempotent: re-clicking the same link sets the same column to the
 * same value. The trade-off is that email link prefetchers can flip
 * a thumbs without the customer intending to — accepted because the
 * column is a soft signal, not anything destructive.
 *
 * Token format from AIManager::buildFeedbackToken():
 *   "{kb_query_logs.id}.{first 16 hex chars of sha256_hmac(APP_KEY, "kb_query_log:{id}")}"
 */
class KbFeedbackController extends Controller
{
    public function feedback(Request $request, string $token, string $verdict)
    {
        if (!in_array($verdict, ['up', 'down'], true)) {
            return $this->thanks(false, 'Invalid feedback value.');
        }

        // Parse + verify the signed token. Constant-time compare so a
        // brute-force attacker can't measure timing to forge sigs row by
        // row.
        if (!str_contains($token, '.')) {
            return $this->thanks(false, 'Invalid feedback link.');
        }
        [$idPart, $sigPart] = explode('.', $token, 2);
        if (!ctype_digit($idPart) || !ctype_xdigit($sigPart) || strlen($sigPart) !== 16) {
            return $this->thanks(false, 'Invalid feedback link.');
        }
        $id = (int) $idPart;

        $key = config('app.key') ?: 'kb-fallback-key';
        $expected = substr(hash_hmac('sha256', "kb_query_log:{$id}", $key), 0, 16);
        if (!hash_equals($expected, $sigPart)) {
            return $this->thanks(false, 'Invalid feedback link.');
        }

        // Update is best-effort: if the row was deleted (workspace gone,
        // KB log purged) we still show the thank-you page so the customer
        // doesn't see an error after clicking a friendly button.
        try {
            $affected = DB::table('kb_query_logs')
                ->where('id', $id)
                ->update([
                    'was_helpful' => $verdict === 'up',
                    'updated_at' => now(),
                ]);

            if ($affected === 0) {
                Log::info('KB feedback for missing log row', ['id' => $id]);
            }
        } catch (\Throwable $e) {
            Log::warning('KB feedback update failed', [
                'id' => $id,
                'error' => $e->getMessage(),
            ]);
        }

        return $this->thanks($verdict === 'up');
    }

    /**
     * Tiny standalone confirmation page. Standalone (not the app layout)
     * because the audience here is anonymous customers — they should
     * not see the MailTrixy navigation, login button, or anything else
     * that suggests they're inside the product.
     */
    private function thanks(bool $positive, ?string $error = null)
    {
        return response()->view('kb-feedback.thanks', [
            'positive' => $positive,
            'error' => $error,
        ]);
    }
}
