<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Conversation;
use App\Models\Message;
use App\Models\Worker;
use App\Models\JobOffer;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;

class WorkerMessageController extends Controller
{
    public static function processWorkerResponse($conv, $worker, $text)
    {
        $replyText = strtolower(trim($text));
        
        if ($replyText === 'yes' || $replyText === 'no') {
            // Find the last message sent by the employer in this conversation (excluding the current worker message)
            $lastEmployerMessage = Message::where('conversation_id', $conv->id)
                ->where('sender_type', 'employer')
                ->latest()
                ->first();

            if ($lastEmployerMessage) {
                $questionText = strtolower($lastEmployerMessage->text);
                $isLookingJobQuestion = str_contains($questionText, 'looking job') ||
                                        str_contains($questionText, 'looking for a job') ||
                                        str_contains($questionText, 'looking for job') ||
                                        str_contains($questionText, 'are you looking');

                if ($isLookingJobQuestion) {
                    if ($replyText === 'yes') {
                        // S6 Outcome: Update status as Hired
                        $worker->update([
                            'status' => 'Hired',
                            'availability' => 'Hired'
                        ]);

                        // Accept existing direct offer or application
                        $offer = JobOffer::where('employer_id', $conv->employer_id)
                            ->where('worker_id', $worker->id)
                            ->first();

                        if ($offer) {
                            $offer->update(['status' => 'accepted']);
                        } else {
                            JobOffer::create([
                                'employer_id' => $conv->employer_id,
                                'worker_id' => $worker->id,
                                'work_date' => now()->format('Y-m-d'),
                                'location' => 'Dubai',
                                'salary' => $worker->salary ?: 2000,
                                'notes' => 'Hired via chat agreement.',
                                'status' => 'accepted',
                            ]);
                        }
                    } else if ($replyText === 'no') {
                        // S5 Outcome: Update status as Hidden (Auto-Hidden from search)
                        $worker->update([
                            'status' => 'hidden',
                            'availability' => 'Not Available'
                        ]);
                    }
                }
            }
        }
    }

    /**
     * Get all conversations for the authorized worker.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getConversations(Request $request)
    {
        /** @var Worker $worker */
        $worker = $request->attributes->get('worker');

        try {
            $dbConversations = Conversation::where('worker_id', $worker->id)
                ->with(['employer.employerProfile', 'messages'])
                ->latest('updated_at')
                ->get();

            $conversations = $dbConversations->map(function ($conv) {
                $lastMsg = $conv->messages->last();
                
                // Calculate unread count (messages sent by employer that are not read by worker)
                $unreadCount = $conv->messages->filter(function ($msg) {
                    return $msg->sender_type === 'employer' && is_null($msg->read_at);
                })->count();

                return [
                    'id' => $conv->id,
                    'employer_id' => $conv->employer_id,
                    'employer_name' => $conv->employer->name ?? 'Employer',
                    'company_name' => $conv->employer->employerProfile->company_name ?? 'Individual Employer',
                    'last_message' => $lastMsg->text ?? 'No messages yet.',
                    'unread_count' => $unreadCount,
                    'sent_at' => $lastMsg ? $lastMsg->created_at->diffForHumans() : 'Just now',
                    'updated_at' => $conv->updated_at->toISOString(),
                ];
            });

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

        } catch (\Exception $e) {
            logger()->error('Mobile Worker Get Conversations Failure: ' . $e->getMessage());

            return response()->json([
                'success' => false,
                'message' => 'An error occurred while fetching conversations.',
                'error' => app()->environment('local') ? $e->getMessage() : 'Internal Server Error'
            ], 500);
        }
    }

    /**
     * Get messages in a single conversation and mark unread incoming messages as read.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\JsonResponse
     */
    public function getMessages(Request $request, $id)
    {
        /** @var Worker $worker */
        $worker = $request->attributes->get('worker');

        try {
            $conv = Conversation::where('worker_id', $worker->id)
                ->where('id', $id)
                ->with(['employer.employerProfile', 'messages'])
                ->first();

            if (!$conv) {
                return response()->json([
                    'success' => false,
                    'message' => 'Conversation not found.'
                ], 404);
            }

            // Mark incoming employer messages in this conversation as read
            Message::where('conversation_id', $conv->id)
                ->where('sender_type', 'employer')
                ->whereNull('read_at')
                ->update(['read_at' => now()]);

            $messages = $conv->messages->map(function ($msg) {
                return [
                    'id' => $msg->id,
                    'sender_type' => $msg->sender_type, // employer or worker
                    'text' => $msg->text,
                    'time' => $msg->created_at->format('g:i A') . ($msg->created_at->isToday() ? ' Today' : ' ' . $msg->created_at->format('M d')),
                    'read_at' => $msg->read_at ? $msg->read_at->toISOString() : null,
                    'created_at' => $msg->created_at->toISOString(),
                    'attachment_url' => $msg->attachment_path ? asset('storage/' . $msg->attachment_path) : null,
                    'attachment_type' => $msg->attachment_type,
                ];
            });

            $conversationDetail = [
                'id' => $conv->id,
                'employer_name' => $conv->employer->name ?? 'Employer',
                'company_name' => $conv->employer->employerProfile->company_name ?? 'Individual Employer',
            ];

            return response()->json([
                'success' => true,
                'data' => [
                    'conversation' => $conversationDetail,
                    'messages' => $messages
                ]
            ], 200);

        } catch (\Exception $e) {
            logger()->error('Mobile Worker Get Messages Failure: ' . $e->getMessage());

            return response()->json([
                'success' => false,
                'message' => 'An error occurred while fetching messages.',
                'error' => app()->environment('local') ? $e->getMessage() : 'Internal Server Error'
            ], 500);
        }
    }

    /**
     * Send a reply message from the worker to the employer.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\JsonResponse
     */
    public function sendMessage(Request $request, $id)
    {
        /** @var Worker $worker */
        $worker = $request->attributes->get('worker');

        $validator = Validator::make($request->all(), [
            'text' => 'required_without:file|string|max:1000|nullable',
            'file' => 'nullable|file|mimes:jpg,jpeg,png,pdf,mp3,wav,m4a,ogg,webm,mp4,aac,3gp,amr|max:10240', // 10MB limit
        ]);

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

        try {
            $conv = Conversation::where('worker_id', $worker->id)
                ->where('id', $id)
                ->first();

            if (!$conv) {
                return response()->json([
                    'success' => false,
                    'message' => 'Conversation not found.'
                ], 404);
            }

            $attachmentPath = null;
            $attachmentType = null;
            
            if ($request->hasFile('file')) {
                $file = $request->file('file');
                $attachmentPath = $file->store('chat_attachments', 'public');
                
                $mime = $file->getMimeType();
                $extension = strtolower($file->getClientOriginalExtension());
                $audioExtensions = ['mp3', 'wav', 'm4a', 'ogg', 'webm', 'aac', '3gp', 'amr'];
                $imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
                
                if (str_starts_with($mime, 'image/') || in_array($extension, $imageExtensions)) {
                    $attachmentType = 'image';
                } elseif (str_starts_with($mime, 'audio/') || in_array($extension, $audioExtensions)) {
                    $attachmentType = 'voice';
                } else {
                    $attachmentType = 'document';
                }
            }

            $message = null;
            DB::transaction(function () use ($conv, $worker, $request, $attachmentPath, $attachmentType, &$message) {
                $message = Message::create([
                    'conversation_id' => $conv->id,
                    'sender_type' => 'worker',
                    'sender_id' => $worker->id,
                    'text' => $request->text,
                    'attachment_path' => $attachmentPath,
                    'attachment_type' => $attachmentType,
                ]);

                // Touch conversation updated_at for sorting
                $conv->touch();

                // Process the worker response to update status to Hired or Hidden
                if ($request->text) {
                    self::processWorkerResponse($conv, $worker, $request->text);
                }
            });

            return response()->json([
                'success' => true,
                'message' => 'Message sent successfully.',
                'data' => [
                    'message' => [
                        'id' => $message->id,
                        'sender_type' => $message->sender_type,
                        'text' => $message->text,
                        'time' => $message->created_at->format('g:i A') . ' Today',
                        'created_at' => $message->created_at->toISOString(),
                        'attachment_url' => $message->attachment_path ? asset('storage/' . $message->attachment_path) : null,
                        'attachment_type' => $message->attachment_type,
                    ]
                ]
            ], 201);

        } catch (\Exception $e) {
            logger()->error('Mobile Worker Send Message Failure: ' . $e->getMessage());

            return response()->json([
                'success' => false,
                'message' => 'An error occurred while sending the message.',
                'error' => app()->environment('local') ? $e->getMessage() : 'Internal Server Error'
            ], 500);
        }
    }
}
