<?php

namespace App\Http\Controllers\Webhook;

use App\Http\Controllers\Controller;
use App\Models\Admin;
use App\Models\Setting;
use App\Models\Ticket;
use App\Models\TicketReply;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class SlackWebhookController extends Controller
{
    /**
     * Handle incoming Slack Events API requests.
     */
    public function handle(Request $request): JsonResponse
    {
        // 1. Verify Slack signature
        if (!$this->verifySignature($request)) {
            Log::warning('Slack webhook: Invalid signature');
            return response()->json(['error' => 'Invalid signature'], 403);
        }

        $payload = $request->all();

        // 2. Handle URL verification challenge (Slack app setup)
        if (($payload['type'] ?? '') === 'url_verification') {
            return response()->json(['challenge' => $payload['challenge']]);
        }

        // 3. Handle event callbacks
        if (($payload['type'] ?? '') === 'event_callback') {
            $event = $payload['event'] ?? [];
            $eventType = $event['type'] ?? '';

            if ($eventType === 'message' && !isset($event['bot_id']) && !isset($event['subtype'])) {
                $this->handleMessage($event);
            }
        }

        return response()->json(['ok' => true]);
    }

    /**
     * Handle a Slack message event → create ticket reply.
     */
    private function handleMessage(array $event): void
    {
        $channelId = $event['channel'] ?? '';
        $slackUserId = $event['user'] ?? '';
        $text = $event['text'] ?? '';
        $threadTs = $event['thread_ts'] ?? null;

        if (empty($channelId) || empty($text)) {
            return;
        }

        // Find ticket by Slack channel ID
        $ticket = Ticket::where('slack_channel_id', $channelId)->first();
        if (!$ticket) {
            return;
        }

        // Find admin by Slack user ID
        $admin = Admin::where('slack_user_id', $slackUserId)->first();

        if (!$admin) {
            // Try to find admin by Slack email lookup
            $admin = $this->findAdminBySlackUser($slackUserId);
        }

        if (!$admin) {
            Log::info('Slack webhook: Unknown user, ignoring', ['slack_user_id' => $slackUserId, 'channel' => $channelId]);
            return;
        }

        // Check department access
        if (!$ticket->isAccessibleBy($admin)) {
            Log::warning('Slack webhook: Admin lacks department access', ['admin' => $admin->id, 'ticket' => $ticket->id]);
            return;
        }

        // Create ticket reply
        $reply = TicketReply::create([
            'ticket_id' => $ticket->id,
            'admin_id' => $admin->id,
            'mail' => $admin->email,
            'message' => $text . "\n\n_[Slack üzerinden yanıtlandı]_",
        ]);

        // Update timestamps
        $ticket->update(['last_admin_reply_at' => now()]);

        // Dispatch event → triggers email to client + other integrations
        \App\Events\TicketRepliedByAdmin::dispatch($ticket, $reply, $admin);

        Log::info('Slack webhook: Reply created', [
            'ticket_id' => $ticket->id,
            'reply_id' => $reply->id,
            'admin_id' => $admin->id,
            'source' => 'slack',
        ]);
    }

    /**
     * Find admin by looking up Slack user's email.
     */
    private function findAdminBySlackUser(string $slackUserId): ?Admin
    {
        $botToken = Setting::get('slack_bot_token', '');
        if (empty($botToken)) {
            return null;
        }

        try {
            $response = \Illuminate\Support\Facades\Http::withToken($botToken)
                ->get('https://slack.com/api/users.info', ['user' => $slackUserId]);

            $data = $response->json();
            if (!($data['ok'] ?? false)) {
                return null;
            }

            $email = $data['user']['profile']['email'] ?? null;
            if (!$email) {
                return null;
            }

            $admin = Admin::where('email', $email)->first();

            // Auto-save Slack user ID for future lookups
            if ($admin && !$admin->slack_user_id) {
                $admin->update(['slack_user_id' => $slackUserId]);
            }

            return $admin;
        } catch (\Exception $e) {
            Log::error('Slack user lookup failed', ['error' => $e->getMessage()]);
            return null;
        }
    }

    /**
     * Verify Slack request signature.
     */
    private function verifySignature(Request $request): bool
    {
        $signingSecret = Setting::get('slack_signing_secret', config('ticket-integrations.slack.signing_secret', ''));

        if (empty($signingSecret)) {
            return true; // Skip verification if no secret configured
        }

        $timestamp = $request->header('X-Slack-Request-Timestamp');
        $signature = $request->header('X-Slack-Signature');

        if (!$timestamp || !$signature) {
            return false;
        }

        // Prevent replay attacks (5 minute window)
        if (abs(time() - (int) $timestamp) > 300) {
            return false;
        }

        $sigBasestring = "v0:{$timestamp}:{$request->getContent()}";
        $expectedSignature = 'v0=' . hash_hmac('sha256', $sigBasestring, $signingSecret);

        return hash_equals($expectedSignature, $signature);
    }
}
