TA/web_JMW/app/Http/Controllers/ChatController.php

313 lines
9.7 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Models\Category;
use App\Services\WhatsAppBusinessService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class ChatController extends Controller
{
/**
* @var \App\Services\WhatsAppBusinessService
*/
private $whatsAppBusinessService;
/**
* @param \App\Services\WhatsAppBusinessService $whatsAppBusinessService
*/
public function __construct(WhatsAppBusinessService $whatsAppBusinessService)
{
$this->whatsAppBusinessService = $whatsAppBusinessService;
}
/**
* Get WhatsApp link for admin showroom
*
* @param int $categoryId - The category/car ID (optional)
* @return \Illuminate\Http\JsonResponse
*/
public function getAdminWhatsAppLink($categoryId = null)
{
try {
// Get admin phone number from centralized service configuration.
$phoneNumber = config('services.whatsapp.admin_recipient');
$adminName = config('services.whatsapp.admin_name', 'Showroom');
if (!$phoneNumber) {
return response()->json([
'success' => false,
'message' => 'Nomor WhatsApp admin tidak dikonfigurasi',
], 422);
}
$carName = null;
$carImageUrl = null;
$carDetailUrl = null;
$category = null;
if ($categoryId) {
$category = Category::find($categoryId);
if ($category) {
$carName = $category->name;
$carImageUrl = $this->getCarImageUrl($category);
$carDetailUrl = $this->getCarDetailUrl($category);
}
}
// Format phone number
$formattedPhone = $this->formatPhoneNumber($phoneNumber);
// Create WhatsApp message
$message = $this->buildWhatsAppMessage($category, $carImageUrl, $carDetailUrl);
$encodedMessage = urlencode($message);
// WhatsApp Web link format
$whatsappLink = "https://wa.me/{$formattedPhone}?text={$encodedMessage}";
return response()->json([
'success' => true,
'message' => 'Link WhatsApp berhasil dibuat',
'data' => [
'admin_name' => $adminName,
'phone_number' => $phoneNumber,
'whatsapp_link' => $whatsappLink,
'car_name' => $carName,
'car_image_url' => $carImageUrl,
'car_detail_url' => $carDetailUrl,
]
], 200);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => 'Terjadi kesalahan: ' . $e->getMessage(),
], 500);
}
}
/**
* Direct redirect to WhatsApp admin.
*
* @param int $categoryId - The category/car ID (optional)
* @return \Illuminate\Http\RedirectResponse
*/
public function redirectAdminWhatsApp($categoryId = null)
{
try {
$phoneNumber = config('services.whatsapp.admin_recipient');
if (!$phoneNumber) {
return redirect()->back()->with('error', 'Nomor WhatsApp admin tidak dikonfigurasi');
}
// Format phone number
$formattedPhone = $this->formatPhoneNumber($phoneNumber);
$carImageUrl = null;
$carDetailUrl = null;
$category = null;
if ($categoryId) {
$category = Category::find($categoryId);
if ($category) {
$carImageUrl = $this->getCarImageUrl($category);
$carDetailUrl = $this->getCarDetailUrl($category);
$this->sendBusinessImageNotification($category, auth()->user());
}
}
// Create message
$message = $this->buildWhatsAppMessage($category, $carImageUrl, $carDetailUrl);
$encodedMessage = urlencode($message);
// Redirect to WhatsApp, but keep catalog/detail URLs based on this local app host.
$whatsappLink = "https://wa.me/{$formattedPhone}?text={$encodedMessage}";
return redirect($whatsappLink);
} catch (\Exception $e) {
return redirect()->back()->with('error', 'Terjadi kesalahan saat membuka WhatsApp');
}
}
/**
* Send a WhatsApp Business notification with the car image to admin.
*
* @param \Illuminate\Http\Request $request
* @param int $categoryId
* @return \Illuminate\Http\JsonResponse
*/
public function notifyAdminWithCarImage(Request $request, $categoryId)
{
try {
$category = Category::find($categoryId);
if (!$category) {
return response()->json([
'success' => false,
'message' => 'Mobil tidak ditemukan.',
], 404);
}
$result = $this->whatsAppBusinessService->sendCarNotificationToAdmin(
$category,
$request->user()
);
return response()->json($result, $result['success'] ? 200 : 422);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => 'Terjadi kesalahan saat mengirim notifikasi ke admin.',
'error' => $e->getMessage(),
], 500);
}
}
/**
* Format phone number to WhatsApp format
* Converts various formats to 62xxxxxxxxxx
*
* @param string $phoneNumber
* @return string
*/
private function formatPhoneNumber($phoneNumber)
{
// Remove all non-numeric characters
$phoneNumber = preg_replace('/[^0-9]/', '', $phoneNumber);
// Handle Indonesian phone numbers
// 081234567890 -> 6281234567890
if (strlen($phoneNumber) == 10 && substr($phoneNumber, 0, 1) == '8') {
$phoneNumber = '62' . $phoneNumber;
}
// 08xxxxxxxxxx -> 62xxxxxxxxxx
elseif (strlen($phoneNumber) >= 11 && substr($phoneNumber, 0, 2) == '08') {
$phoneNumber = '62' . substr($phoneNumber, 1);
}
// If doesn't start with 62, prepend it
elseif (substr($phoneNumber, 0, 2) != '62') {
$phoneNumber = '62' . $phoneNumber;
}
return $phoneNumber;
}
/**
* Build WhatsApp message with optional car image link.
*
* @param \App\Models\Category|null $category
* @param string|null $carImageUrl
* @param string|null $carDetailUrl
* @return string
*/
private function buildWhatsAppMessage(?Category $category = null, $carImageUrl = null, $carDetailUrl = null)
{
if (!$category) {
return "Halo admin, saya tertarik dengan salah satu mobil bekas yang ada di website. Apakah masih tersedia?";
}
$lines = [
'Halo admin, saya tertarik dengan mobil katalog ini.',
'',
'Nama mobil: ' . $category->name,
'Harga: Rp ' . number_format((float) $category->price, 0, ',', '.'),
'Tahun: ' . ($category->year ?: '-'),
];
if ($carImageUrl) {
$lines[] = 'Foto katalog: ' . $carImageUrl;
}
if ($carDetailUrl) {
$lines[] = 'Link detail: ' . $carDetailUrl;
}
$lines[] = '';
$lines[] = 'Apakah mobil ini masih tersedia?';
return implode("\n", $lines);
}
/**
* Get absolute public URL for the car image if available.
*
* @param \App\Models\Category $category
* @return string|null
*/
private function getCarImageUrl(Category $category)
{
if (!$category->image) {
return null;
}
return $this->publicUrl(Storage::disk('public')->url($category->image), $this->getClickableBaseUrl());
}
/**
* Get absolute detail page URL for the car.
*
* @param \App\Models\Category $category
* @return string
*/
private function getCarDetailUrl(Category $category)
{
return $this->publicUrl('/mobil-bekas/' . $category->id, $this->getClickableBaseUrl());
}
/**
* Build an absolute URL from the current local app host.
*
* @param string $path
* @return string
*/
private function publicUrl($path, $baseUrl = null)
{
if (filter_var($path, FILTER_VALIDATE_URL)) {
return $path;
}
$baseUrl = $baseUrl ?: url('/');
return rtrim($baseUrl, '/') . '/' . ltrim($path, '/');
}
/**
* Prefer a public local tunnel URL for WhatsApp, because WhatsApp often
* does not turn 127.0.0.1/localhost links into clickable links.
*
* @return string
*/
private function getClickableBaseUrl()
{
$requestUrl = rtrim(request()->getSchemeAndHttpHost(), '/');
if ($requestUrl) {
return $requestUrl;
}
$configuredUrl = rtrim((string) config('app.url'), '/');
if ($configuredUrl && ! preg_match('/^https?:\/\/(127\.0\.0\.1|localhost)(:\d+)?$/i', $configuredUrl)) {
return $configuredUrl;
}
return url('/');
}
/**
* Send selected catalog image through WhatsApp Business Cloud API.
* The direct WhatsApp redirect still works if the API send fails.
*/
private function sendBusinessImageNotification(Category $category, $customer = null)
{
try {
if ($this->whatsAppBusinessService->isConfigured()) {
$this->whatsAppBusinessService->sendCarNotificationToAdmin($category, $customer);
}
} catch (\Throwable $e) {
report($e);
}
}
}