<?php

namespace App\Http\Controllers;

use App\Models\SmsLog;
use App\Models\User;
use App\Models\Order;
use App\Models\Appointment;
use App\Models\AuditLog;
use App\Models\SystemSetting;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Http;

class SmsController extends Controller
{
    /**
     * Send SMS to a single recipient
     */
    public function sendSms(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'recipient_phone' => 'required|string|max:20',
            'message' => 'required|string|max:160',
            'message_type' => 'required|in:booking_confirmation,payment_confirmation,appointment_reminder,promotional,system_notification',
            'order_id' => 'nullable|exists:orders,id',
            'customer_id' => 'nullable|exists:users,id',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'Validation failed',
                'errors' => $validator->errors()
            ], 422);
        }

        try {
            $user = auth()->user();
            $gateway = SystemSetting::getSmsGateway();

            // Send SMS via gateway
            $smsResult = $this->sendViaGateway($request->recipient_phone, $request->message, $gateway);

            // Log SMS
            $smsLog = SmsLog::create([
                'recipient_phone' => $request->recipient_phone,
                'message' => $request->message,
                'message_type' => $request->message_type,
                'status' => $smsResult['success'] ? 'sent' : 'failed',
                'gateway' => $gateway,
                'gateway_response' => $smsResult,
                'cost' => $smsResult['cost'] ?? 0,
                'sent_by' => $user->id,
                'order_id' => $request->order_id,
                'customer_id' => $request->customer_id,
            ]);

            // Log the SMS sending
            AuditLog::logCreate($user, $smsLog, $request);

            if ($smsResult['success']) {
                return response()->json([
                    'success' => true,
                    'message' => 'SMS sent successfully',
                    'data' => [
                        'sms_log' => $smsLog,
                        'gateway_response' => $smsResult
                    ]
                ]);
            } else {
                return response()->json([
                    'success' => false,
                    'message' => 'Failed to send SMS',
                    'error' => $smsResult['message'],
                    'data' => [
                        'sms_log' => $smsLog
                    ]
                ], 422);
            }

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to send SMS',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Get SMS history for authenticated user
     */
    public function smsHistory(Request $request)
    {
        try {
            $user = auth()->user();
            
            $query = SmsLog::with(['sender', 'order', 'customer'])
                ->where('sent_by', $user->id);

            // Filter by status
            if ($request->has('status') && $request->status) {
                $query->where('status', $request->status);
            }

            // Filter by message type
            if ($request->has('message_type') && $request->message_type) {
                $query->where('message_type', $request->message_type);
            }

            // Filter by date range
            if ($request->has('start_date') && $request->has('end_date')) {
                $query->byDateRange($request->start_date, $request->end_date);
            }

            // Sort by creation date (most recent first)
            $query->orderBy('created_at', 'desc');

            // Pagination
            $perPage = $request->get('per_page', 10);
            $smsLogs = $query->paginate($perPage);

            return response()->json([
                'success' => true,
                'message' => 'SMS history retrieved successfully',
                'data' => [
                    'sms_logs' => $smsLogs->items(),
                    'pagination' => [
                        'current_page' => $smsLogs->currentPage(),
                        'per_page' => $smsLogs->perPage(),
                        'total' => $smsLogs->total(),
                        'last_page' => $smsLogs->lastPage(),
                    ]
                ]
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to retrieve SMS history',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Display SMS logs (admin only)
     */
    public function adminLogs(Request $request)
    {
        try {
            $query = SmsLog::with(['sender', 'order', 'customer']);

            // Filter by status
            if ($request->has('status') && $request->status) {
                $query->where('status', $request->status);
            }

            // Filter by message type
            if ($request->has('message_type') && $request->message_type) {
                $query->where('message_type', $request->message_type);
            }

            // Filter by gateway
            if ($request->has('gateway') && $request->gateway) {
                $query->where('gateway', $request->gateway);
            }

            // Filter by date range
            if ($request->has('start_date') && $request->has('end_date')) {
                $query->byDateRange($request->start_date, $request->end_date);
            }

            // Search by recipient phone or message
            if ($request->has('search') && $request->search) {
                $query->where(function($q) use ($request) {
                    $q->where('recipient_phone', 'like', '%' . $request->search . '%')
                      ->orWhere('message', 'like', '%' . $request->search . '%');
                });
            }

            // Sort options
            $sortBy = $request->get('sort_by', 'created_at');
            $sortOrder = $request->get('sort_order', 'desc');
            $query->orderBy($sortBy, $sortOrder);

            // Pagination
            $perPage = $request->get('per_page', 15);
            $smsLogs = $query->paginate($perPage);

            return response()->json([
                'success' => true,
                'message' => 'SMS logs retrieved successfully',
                'data' => [
                    'sms_logs' => $smsLogs->items(),
                    'pagination' => [
                        'current_page' => $smsLogs->currentPage(),
                        'per_page' => $smsLogs->perPage(),
                        'total' => $smsLogs->total(),
                        'last_page' => $smsLogs->lastPage(),
                    ]
                ]
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to retrieve SMS logs',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Send bulk SMS (admin only)
     */
    public function sendBulkSms(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'recipients' => 'required|array|min:1',
            'recipients.*' => 'required|string|max:20',
            'message' => 'required|string|max:160',
            'message_type' => 'required|in:promotional,system_notification',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'Validation failed',
                'errors' => $validator->errors()
            ], 422);
        }

        try {
            $user = auth()->user();
            $gateway = SystemSetting::getSmsGateway();
            $results = [];
            $successCount = 0;
            $failureCount = 0;

            foreach ($request->recipients as $recipient) {
                // Send SMS via gateway
                $smsResult = $this->sendViaGateway($recipient, $request->message, $gateway);

                // Log SMS
                $smsLog = SmsLog::create([
                    'recipient_phone' => $recipient,
                    'message' => $request->message,
                    'message_type' => $request->message_type,
                    'status' => $smsResult['success'] ? 'sent' : 'failed',
                    'gateway' => $gateway,
                    'gateway_response' => $smsResult,
                    'cost' => $smsResult['cost'] ?? 0,
                    'sent_by' => $user->id,
                ]);

                $results[] = [
                    'recipient' => $recipient,
                    'success' => $smsResult['success'],
                    'message' => $smsResult['message'],
                    'sms_log_id' => $smsLog->id,
                ];

                if ($smsResult['success']) {
                    $successCount++;
                } else {
                    $failureCount++;
                }
            }

            // Log the bulk SMS sending
            AuditLog::log($user, 'bulk_sms', null, null, [
                'total_recipients' => count($request->recipients),
                'success_count' => $successCount,
                'failure_count' => $failureCount,
                'message_type' => $request->message_type
            ], $request);

            return response()->json([
                'success' => true,
                'message' => 'Bulk SMS sending completed',
                'data' => [
                    'summary' => [
                        'total_recipients' => count($request->recipients),
                        'success_count' => $successCount,
                        'failure_count' => $failureCount,
                    ],
                    'results' => $results
                ]
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to send bulk SMS',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Send booking confirmation SMS
     */
    public function sendBookingConfirmation(Order $order)
    {
        try {
            $user = auth()->user();
            $message = "Hello {$order->customer_name}, your booking #{$order->order_number} has been confirmed for {$order->booking_date} at {$order->booking_time}. Thank you for choosing us!";

            return $this->sendSms(new Request([
                'recipient_phone' => $order->customer_phone,
                'message' => $message,
                'message_type' => 'booking_confirmation',
                'order_id' => $order->id,
                'customer_id' => $order->customer_id,
            ]));

        } catch (\Exception $e) {
            \Log::error('Failed to send booking confirmation SMS: ' . $e->getMessage());
            return false;
        }
    }

    /**
     * Send payment confirmation SMS
     */
    public function sendPaymentConfirmation(Payment $payment)
    {
        try {
            $user = auth()->user();
            $order = $payment->order;
            $message = "Hello {$order->customer_name}, payment of KES {$payment->amount} for order #{$order->order_number} has been confirmed. Thank you for your payment!";

            return $this->sendSms(new Request([
                'recipient_phone' => $order->customer_phone,
                'message' => $message,
                'message_type' => 'payment_confirmation',
                'order_id' => $order->id,
                'customer_id' => $order->customer_id,
            ]));

        } catch (\Exception $e) {
            \Log::error('Failed to send payment confirmation SMS: ' . $e->getMessage());
            return false;
        }
    }

    /**
     * Send appointment reminder SMS
     */
    public function sendAppointmentReminder(Appointment $appointment)
    {
        try {
            $user = auth()->user();
            $customer = $appointment->customer;
            $message = "Reminder: You have an appointment scheduled for {$appointment->formatted_service_date} at {$appointment->formatted_service_time}. Please arrive on time.";

            $result = $this->sendSms(new Request([
                'recipient_phone' => $customer->phone,
                'message' => $message,
                'message_type' => 'appointment_reminder',
                'order_id' => $appointment->order_id,
                'customer_id' => $appointment->customer_id,
            ]));

            if ($result->getData()->success) {
                $appointment->update(['reminder_sent' => true]);
            }

            return $result;

        } catch (\Exception $e) {
            \Log::error('Failed to send appointment reminder SMS: ' . $e->getMessage());
            return false;
        }
    }

    /**
     * Send SMS via selected gateway
     */
    private function sendViaGateway($phone, $message, $gateway)
    {
        switch ($gateway) {
            case 'africastalking':
                return $this->sendViaAfricaTalking($phone, $message);
            default:
                return [
                    'success' => false,
                    'message' => 'Unsupported SMS gateway'
                ];
        }
    }

    /**
     * Send SMS via Africa's Talking
     */
    private function sendViaAfricaTalking($phone, $message)
    {
        try {
            // Get Africa's Talking credentials from settings
            $username = SystemSetting::getValue('africastalking_username');
            $apiKey = SystemSetting::getValue('africastalking_api_key');
            $senderId = SystemSetting::getValue('africastalking_sender_id');

            if (!$username || !$apiKey) {
                return [
                    'success' => false,
                    'message' => 'Africa\'s Talking credentials not configured'
                ];
            }

            // Format phone number (ensure it starts with +254 for Kenya)
            $formattedPhone = $this->formatPhoneNumber($phone);

            // Send SMS via Africa's Talking API
            $response = Http::withHeaders([
                'Accept' => 'application/json',
                'Content-Type' => 'application/x-www-form-urlencoded',
                'apiKey' => $apiKey,
            ])->post('https://api.africastalking.com/version1/messaging', [
                'username' => $username,
                'to' => $formattedPhone,
                'message' => $message,
                'from' => $senderId,
            ]);

            $responseData = $response->json();

            if ($response->successful() && isset($responseData['SMSMessageData']['Recipients'][0]['status'])) {
                $recipient = $responseData['SMSMessageData']['Recipients'][0];
                
                if ($recipient['status'] === 'Success') {
                    return [
                        'success' => true,
                        'message' => 'SMS sent successfully',
                        'message_id' => $recipient['messageId'],
                        'cost' => $recipient['cost'] ?? '1.00',
                        'gateway_response' => $responseData
                    ];
                } else {
                    return [
                        'success' => false,
                        'message' => $recipient['status'],
                        'gateway_response' => $responseData
                    ];
                }
            } else {
                return [
                    'success' => false,
                    'message' => $responseData['SMSMessageData']['Message'] ?? 'Failed to send SMS',
                    'gateway_response' => $responseData
                ];
            }

        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => $e->getMessage()
            ];
        }
    }


    /**
     * Format phone number to international format
     */
    private function formatPhoneNumber($phone)
    {
        // Remove any non-digit characters
        $phone = preg_replace('/\D/', '', $phone);

        // If phone starts with 0, replace with +254
        if (substr($phone, 0, 1) === '0') {
            $phone = '+254' . substr($phone, 1);
        }
        // If phone starts with 254, add +
        elseif (substr($phone, 0, 3) === '254') {
            $phone = '+' . $phone;
        }
        // If phone starts with 7 and is 9 digits, assume it's Kenyan and add +254
        elseif (substr($phone, 0, 1) === '7' && strlen($phone) === 9) {
            $phone = '+254' . $phone;
        }

        return $phone;
    }

    /**
     * Get SMS statistics (admin only)
     */
    public function getSmsStatistics(Request $request)
    {
        try {
            $startDate = $request->get('start_date', now()->subMonth()->format('Y-m-d'));
            $endDate = $request->get('end_date', now()->format('Y-m-d'));

            $stats = SmsLog::select(
                DB::raw('COUNT(*) as total_sms'),
                DB::raw('COUNT(CASE WHEN status = "sent" THEN 1 END) as successful_sms'),
                DB::raw('COUNT(CASE WHEN status = "failed" THEN 1 END) as failed_sms'),
                DB::raw('SUM(cost) as total_cost')
            )->whereBetween('created_at', [$startDate, $endDate])
             ->first();

            // Message type breakdown
            $typeBreakdown = SmsLog::select(
                'message_type',
                DB::raw('COUNT(*) as count'),
                DB::raw('SUM(cost) as cost')
            )->whereBetween('created_at', [$startDate, $endDate])
             ->groupBy('message_type')
             ->get();

            // Gateway performance
            $gatewayPerformance = SmsLog::select(
                'gateway',
                DB::raw('COUNT(*) as total'),
                DB::raw('COUNT(CASE WHEN status = "sent" THEN 1 END) as successful'),
                DB::raw('ROUND((COUNT(CASE WHEN status = "sent" THEN 1 END) * 100.0 / COUNT(*)), 2) as success_rate')
            )->whereBetween('created_at', [$startDate, $endDate])
             ->groupBy('gateway')
             ->get();

            return response()->json([
                'success' => true,
                'message' => 'SMS statistics retrieved successfully',
                'data' => [
                    'report_period' => [
                        'start_date' => $startDate,
                        'end_date' => $endDate,
                    ],
                    'summary' => $stats,
                    'type_breakdown' => $typeBreakdown,
                    'gateway_performance' => $gatewayPerformance,
                ]
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to retrieve SMS statistics',
                'error' => $e->getMessage()
            ], 500);
        }
    }
}