<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\CallLog;
use App\Models\SmsLog;
use App\Models\PromotionLog;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Carbon\Carbon;

class SyncController extends Controller
{
    /**
     * Sync call logs from the mobile app.
     */
    public function syncCalls(Request $request)
    {
        \Log::info('Sync Calls Request RECEIVED', [
            'user_id' => $request->user()->id ?? 'unknown',
            'call_logs_count' => is_array($request->call_logs) ? count($request->call_logs) : 'not array'
        ]);

        $validator = Validator::make($request->all(), [
            'call_logs' => 'required|array',
            'call_logs.*.local_id' => 'required|integer',
            'call_logs.*.phone_number' => 'required|string|max:20',
            'call_logs.*.call_type' => 'required|string|max:50', // Accept any call type from Android, normalize on save
            'call_logs.*.call_time' => 'required|integer',
            'call_logs.*.call_duration' => 'sometimes|integer',
            'call_logs.*.sms_sent' => 'required|boolean',
        ]);

        if ($validator->fails()) {
            \Log::error('Sync Calls Validation Failed', ['errors' => $validator->errors()]);
            return response()->json([
                'success' => false,
                'message' => 'Validation error',
                'errors' => $validator->errors(),
            ], 422);
        }

        try {
            $user = $request->user();
            $syncedCount = 0;
            $syncedIds = [];

            if (empty($request->call_logs)) {
                return response()->json([
                    'success' => true,
                    'message' => 'No call logs to sync',
                    'synced_ids' => [],
                ]);
            }

            foreach ($request->call_logs as $callData) {
                $callTime = Carbon::createFromTimestampMs($callData['call_time']);

                $existingCall = CallLog::where('user_id', $user->id)
                    ->where('phone_number', $callData['phone_number'])
                    ->where('call_time', $callTime)
                    ->first();

                if (!$existingCall) {
                    // Get device info from session or request header
                    $session = $request->get('user_session');
                    $deviceId = $session?->device_id ?? $request->header('X-Device-ID');
                    $deviceName = $session?->device_name ?? $request->header('X-Device-Name');

                    // Normalize call type (REJECTED, BLOCKED -> missed, etc.)
                    $callType = strtolower($callData['call_type']);
                    $normalizedCallType = match ($callType) {
                        'incoming', 'answered_externally', 'wifi' => 'incoming',
                        'outgoing' => 'outgoing',
                        'missed', 'rejected', 'blocked', 'voicemail' => 'missed',
                        default => $callType, // Keep original if not recognized
                    };

                    CallLog::create([
                        'user_id' => $user->id,
                        'device_id' => $deviceId,
                        'device_name' => $deviceName,
                        'phone_number' => $callData['phone_number'],
                        'call_type' => $normalizedCallType,
                        'call_time' => $callTime,
                        'call_duration' => $callData['call_duration'] ?? 0,
                        'sms_sent' => $callData['sms_sent'],
                    ]);

                    $syncedIds[] = $callData['local_id'];
                    $syncedCount++;
                }
            }

            return response()->json([
                'success' => true,
                'message' => "Synced {$syncedCount} call logs",
                'synced_ids' => $syncedIds,
            ]);
        } catch (\Exception $e) {
            \Log::error('Sync Calls Exception', ['error' => $e->getMessage()]);
            return response()->json([
                'success' => false,
                'message' => 'Sync failed: ' . $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Sync SMS logs from the mobile app.
     */
    public function syncSms(Request $request)
    {
        \Log::info('Sync SMS Request RECEIVED', [
            'user_id' => $request->user()->id ?? 'unknown',
            'sms_logs_count' => is_array($request->sms_logs) ? count($request->sms_logs) : 'not array'
        ]);

        $validator = Validator::make($request->all(), [
            'sms_logs' => 'required|array',
            'sms_logs.*.local_id' => 'required|integer',
            'sms_logs.*.call_log_id' => 'sometimes|integer',
            'sms_logs.*.phone_number' => 'required|string|max:20',
            'sms_logs.*.message' => 'required|string',
            'sms_logs.*.status' => 'required|string|max:20', // Accept any status, normalize on save
            'sms_logs.*.sent_at' => 'required|integer',
            'sms_logs.*.template_name' => 'nullable|string',
            'sms_logs.*.sms_type' => 'nullable|string|in:auto_reply,promotion',
            'sms_logs.*.channel' => 'nullable|string|in:sms,whatsapp',
        ]);

        if ($validator->fails()) {
            \Log::error('Sync SMS Validation Failed', ['errors' => $validator->errors()]);
            return response()->json([
                'success' => false,
                'message' => 'Validation error',
                'errors' => $validator->errors(),
            ], 422);
        }

        $user = $request->user();
        $syncedCount = 0;
        $syncedIds = [];

        if (empty($request->sms_logs)) {
            return response()->json([
                'success' => true,
                'message' => 'No SMS logs to sync',
                'synced_ids' => [],
            ]);
        }

        foreach ($request->sms_logs as $smsData) {
            $sentAt = Carbon::createFromTimestampMs($smsData['sent_at']);

            $callLog = null;
            if (isset($smsData['call_log_id'])) {
                $callLog = CallLog::where('user_id', $user->id)
                    ->where('id', $smsData['call_log_id'])
                    ->first();
            }

            if (!$callLog) {
                $callLog = CallLog::where('user_id', $user->id)
                    ->where('phone_number', $smsData['phone_number'])
                    ->where('call_time', '<=', $sentAt)
                    ->orderBy('call_time', 'desc')
                    ->first();
            }

            $existingSms = SmsLog::where('user_id', $user->id)
                ->where('phone_number', $smsData['phone_number'])
                ->where('sent_at', $sentAt)
                ->first();

            if (!$existingSms) {
                // Get device info from session or request header
                $session = $request->get('user_session');
                $deviceId = $session?->device_id ?? $request->header('X-Device-ID');
                $deviceName = $session?->device_name ?? $request->header('X-Device-Name');

                // Normalize status
                $status = strtolower($smsData['status']);
                $channel = $smsData['channel'] ?? 'sms';

                // For WhatsApp: 'triggered' means the message was opened in WhatsApp
                // (user saw it / auto-send attempted). Treat as 'sent' since we can't
                // get a delivery callback from WhatsApp like we can with SMS.
                if ($channel === 'whatsapp' && in_array($status, ['triggered', 'pending'])) {
                    $status = 'sent';
                }

                SmsLog::create([
                    'user_id' => $user->id,
                    'device_id' => $deviceId,
                    'device_name' => $deviceName,
                    'call_log_id' => $callLog?->id,
                    'phone_number' => $smsData['phone_number'],
                    'contact_name' => $smsData['contact_name'] ?? null,
                    'message' => $smsData['message'],
                    'status' => $status,
                    'channel' => $channel,
                    'sms_type' => $smsData['sms_type'] ?? 'auto_reply',
                    'sent_at' => $sentAt,
                ]);

                $syncedIds[] = $smsData['local_id'];
                $syncedCount++;
            }
        }

        \Log::info('Sync SMS Completed', [
            'user_id' => $user->id,
            'synced_count' => $syncedCount,
            'synced_ids' => $syncedIds
        ]);

        return response()->json([
            'success' => true,
            'message' => "Synced {$syncedCount} SMS logs",
            'synced_ids' => $syncedIds,
        ]);
    }

    /**
     * Sync promotion logs from the mobile app.
     */
    public function syncPromotions(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'promotion_logs' => 'required|array',
            'promotion_logs.*.local_id' => 'required|integer',
            'promotion_logs.*.call_log_id' => 'sometimes|integer',
            'promotion_logs.*.template_id' => 'sometimes|integer',
            'promotion_logs.*.phone_number' => 'required|string|max:20',
            'promotion_logs.*.message' => 'required|string',
            'promotion_logs.*.status' => 'required|in:SENT,FAILED,PENDING,sent,failed,pending',
            'promotion_logs.*.trigger_type' => 'required|in:incoming,outgoing,missed',
            'promotion_logs.*.sent_at' => 'required|integer',
        ]);

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

        $user = $request->user();
        $syncedCount = 0;
        $syncedIds = [];

        if (empty($request->promotion_logs)) {
            return response()->json([
                'success' => true,
                'message' => 'No promotion logs to sync',
                'synced_ids' => [],
            ]);
        }

        foreach ($request->promotion_logs as $promoData) {
            $sentAt = Carbon::createFromTimestampMs($promoData['sent_at']);

            $existingPromo = PromotionLog::where('user_id', $user->id)
                ->where('phone_number', $promoData['phone_number'])
                ->where('sent_at', $sentAt)
                ->first();

            if (!$existingPromo) {
                PromotionLog::create([
                    'user_id' => $user->id,
                    'call_log_id' => $promoData['call_log_id'] ?? null,
                    'template_id' => $promoData['template_id'] ?? null,
                    'phone_number' => $promoData['phone_number'],
                    'message' => $promoData['message'],
                    'status' => strtolower($promoData['status']),
                    'trigger_type' => $promoData['trigger_type'],
                    'sent_at' => $sentAt,
                ]);

                $syncedIds[] = $promoData['local_id'];
                $syncedCount++;
            }
        }

        return response()->json([
            'success' => true,
            'message' => "Synced {$syncedCount} promotion logs",
            'synced_ids' => $syncedIds,
        ]);
    }

    /**
     * Get call logs for the authenticated user.
     */
    public function getCallLogs(Request $request)
    {
        $user = $request->user();

        $query = CallLog::where('user_id', $user->id)
            ->orderBy('call_time', 'desc');

        if ($request->has('call_type')) {
            $query->where('call_type', $request->call_type);
        }

        if ($request->has('from_date')) {
            $query->where('call_time', '>=', Carbon::parse($request->from_date));
        }

        if ($request->has('to_date')) {
            $query->where('call_time', '<=', Carbon::parse($request->to_date));
        }

        $perPage = $request->get('per_page', 50);
        $callLogs = $query->paginate($perPage);

        return response()->json([
            'success' => true,
            'data' => $callLogs,
        ]);
    }

    /**
     * Get SMS logs for the authenticated user.
     */
    public function getSmsLogs(Request $request)
    {
        $user = $request->user();

        $query = SmsLog::where('user_id', $user->id)
            ->orderBy('sent_at', 'desc');

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

        if ($request->has('from_date')) {
            $query->where('sent_at', '>=', Carbon::parse($request->from_date));
        }

        if ($request->has('to_date')) {
            $query->where('sent_at', '<=', Carbon::parse($request->to_date));
        }

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

        return response()->json([
            'success' => true,
            'data' => $smsLogs,
        ]);
    }

    /**
     * Get promotion logs for the authenticated user.
     */
    public function getPromotionLogs(Request $request)
    {
        $user = $request->user();

        $query = PromotionLog::where('user_id', $user->id)
            ->orderBy('sent_at', 'desc');

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

        if ($request->has('trigger_type')) {
            $query->where('trigger_type', $request->trigger_type);
        }

        if ($request->has('from_date')) {
            $query->where('sent_at', '>=', Carbon::parse($request->from_date));
        }

        if ($request->has('to_date')) {
            $query->where('sent_at', '<=', Carbon::parse($request->to_date));
        }

        $perPage = $request->get('per_page', 50);
        $promotionLogs = $query->paginate($perPage);

        return response()->json([
            'success' => true,
            'data' => $promotionLogs,
        ]);
    }

    /**
     * Get sync status and statistics.
     */
    public function getStatus(Request $request)
    {
        $user = $request->user();
        $stats = $user->getStats();
        $settings = $user->getOrCreateSettings();

        return response()->json([
            'success' => true,
            'data' => [
                'stats' => $stats,
                'sms_service_enabled' => $user->sms_service_enabled,
                'promotions_enabled' => $user->promotions_enabled,
                'whatsapp_enabled' => $settings->whatsapp_enabled ?? false,
                'last_active_at' => $user->last_active_at?->toIso8601String(),
            ],
        ]);
    }

    /**
     * Get all data for initial sync.
     */
    public function getAllData(Request $request)
    {
        $user = $request->user();
        $settings = $user->getOrCreateSettings();

        // Get templates
        $templates = $user->messageTemplates()
            ->where('is_active', true)
            ->orderBy('priority')
            ->get()
            ->map(fn($t) => $t->toApiResponse());

        // Get recent logs
        $callLogs = CallLog::where('user_id', $user->id)
            ->orderBy('call_time', 'desc')
            ->limit(100)
            ->get();

        $smsLogs = SmsLog::where('user_id', $user->id)
            ->orderBy('sent_at', 'desc')
            ->limit(100)
            ->get();

        $promotionLogs = PromotionLog::where('user_id', $user->id)
            ->orderBy('sent_at', 'desc')
            ->limit(100)
            ->get();

        return response()->json([
            'success' => true,
            'data' => [
                'user' => [
                    'id' => $user->id,
                    'name' => $user->name,
                    'phone' => $user->phone,
                    'sms_service_enabled' => $user->sms_service_enabled,
                    'promotions_enabled' => $user->promotions_enabled,
                ],
                'settings' => [
                    'cooldown_hours' => $settings->cooldown_hours,
                    'exclude_contacts' => $settings->exclude_contacts,
                    'sync_enabled' => $settings->sync_enabled,
                    'sync_interval_minutes' => $settings->sync_interval_minutes ?? 15,
                    'reply_to_incoming' => $settings->reply_to_incoming ?? true,
                    'reply_to_missed' => $settings->reply_to_missed ?? true,
                    'reply_to_outgoing' => $settings->reply_to_outgoing ?? false,
                    'promotion_on_incoming' => $settings->promotion_on_incoming ?? false,
                    'promotion_on_outgoing' => $settings->promotion_on_outgoing ?? false,
                    'promotion_on_missed' => $settings->promotion_on_missed ?? false,
                    // WhatsApp settings
                    'whatsapp_enabled' => $settings->whatsapp_enabled ?? false,
                    'whatsapp_reply_to_incoming' => $settings->whatsapp_reply_to_incoming ?? false,
                    'whatsapp_reply_to_missed' => $settings->whatsapp_reply_to_missed ?? false,
                    'whatsapp_reply_to_outgoing' => $settings->whatsapp_reply_to_outgoing ?? false,
                    'whatsapp_promotion_on_incoming' => $settings->whatsapp_promotion_on_incoming ?? false,
                    'whatsapp_promotion_on_outgoing' => $settings->whatsapp_promotion_on_outgoing ?? false,
                    'whatsapp_promotion_on_missed' => $settings->whatsapp_promotion_on_missed ?? false,
                    'whatsapp_mode' => $settings->whatsapp_mode ?? 'manual',
                    'whatsapp_cooldown_hours' => $settings->whatsapp_cooldown_hours ?? 24,
                ],
                'templates' => $templates,
                'stats' => $user->getStats(),
                'recent_logs' => [
                    'calls' => $callLogs,
                    'sms' => $smsLogs,
                    'promotions' => $promotionLogs,
                ],
            ],
        ]);
    }
}
