<?php

namespace App\Http\Controllers\Api;

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

class WorkerMessageController extends Controller
{
    /**
     * 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(),
                ];
            });

            $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|string|max:1000',
        ]);

        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);
            }

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

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

            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(),
                    ]
                ]
            ], 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);
        }
    }
}
