<?php

namespace App\Http\Controllers;

use App\Laravue\Models\User;
use App\UserConversation;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Pagination\LengthAwarePaginator;
use App\Http\Resources\ConversationResource;
use App\Conversation;
use App\Message;

class ConversationController extends Controller
{
	const ITEM_PER_PAGE = 20;
	private $user;
	
	public function __construct()
	{
		$this->user = null;
		if (auth('api')->check()) $this->user = auth('api')->user();
	}
	
	public function index(Request $request)
	{
		$params = $request->all();
		$keyword = Arr::get($params, 'keyword', '');
		$limit = Arr::get($params, 'limit', static::ITEM_PER_PAGE);
		$users = User::select('id', 'name', 'username', 'first_name', 'last_name', 'full_name', 'furigana_name', 'avatar', 'is_online', 'last_activity')
			->where('id', '!=', $this->user->id)
			->where('is_activated', 1)
			->where('is_deleted', 0);
		
		// Get all users except the current user
		if ($keyword != '' && $keyword != null) {
			$users = $users
				->where(function ($query) use ($keyword) {
					$query->where('name', 'LIKE', '%' . $keyword . '%');
				})
				->get();
		} else {
			$users = $users->get();
		}
		
		// Get all conversations of the current user
		$userConversations = UserConversation::where('user_id', $this->user->id)
			->with(['conversation.lastMessage', 'conversation.users.user'])
			->get();
		
		// Create a map of user_id to conversation
		$userConversationMap = [];
		foreach ($userConversations as $uc) {
			$conversation = $uc->conversation;
			if ($conversation) {
				// Find the other user in the conversation
				foreach ($conversation->users as $userConv) {
					if ($userConv->user_id != $this->user->id) {
						$userConversationMap[$userConv->user_id] = [
							'conversation'     => $conversation,
							'has_conversation' => true
						];
					}
				}
			}
		}
		
		// Merge user data with conversation data
		$result = $users->map(function ($user) use ($userConversationMap) {
			if (isset($userConversationMap[$user->id])) {
				$conversation = $userConversationMap[$user->id]['conversation'];
				$user->conversation_id = $conversation->id;
				$user->last_message = $conversation->lastMessage;
				$user->last_message_at = $conversation->last_message_at;
				
				// Check if user has unread messages in this conversation (not sent by themselves)
				$user->has_new = Message::where('conversation_id', $conversation->id)
					->where('sender_id', '!=', $this->user->id)
					->where('is_read', false)
					->exists();
					
				$user->important = $user->hasRole(['admin', 'manager']) ? true : false;
			} else {
				$user->conversation_id = null;
				$user->last_message = null;
				$user->last_message_at = null;
				$user->has_new = false;
				$user->important = false;
			}
			return $user;
		});
		
		// Sort by last_message_at desc, then by user name
		$sorted = $result->sortByDesc(function ($user) {
			return $user->last_message_at ? $user->last_message_at->timestamp : 0;
		})->values();
		
		// Paginate the results
		$page = LengthAwarePaginator::resolveCurrentPage('page');
		$paginated = new LengthAwarePaginator(
			$sorted->forPage($page, $limit),
			$sorted->count(),
			$limit,
			$page
		);
		
		return response()->json($paginated);
	}
	
	public function show($id = 0)
	{
		$conversation = Conversation::where('id', $id)->first();
		
		if ($conversation) {
			$isValidConversation = UserConversation::where('conversation_id', $conversation->id)
				->where('user_id', $this->user->id)
				->count();
			
			if ($isValidConversation > 0) {
				$conversationUser = UserConversation::with('user')
					->where('conversation_id', $conversation->id)
					->where('user_id', '!=', $this->user->id)
					->first();
				
				if ($conversationUser && $conversationUser->user) {
					$name = $conversationUser->user->name;
					if ($conversationUser->user->furigana_name) {
						$name .= ' (' . $conversationUser->user->furigana_name . ')';
					}
					
					return response()->json([
						'success' => true,
						'id'      => $conversation->id,
						'title'   => $name,
						'avatar'  => $conversationUser->user->avatar ?? 'avatar.png',
					]);
				}
			}
		}
		
		return response()->json([
			'success' => false,
			'id'      => null,
			'title'   => null,
			'avatar'  => null,
		]);
	}
	
	public function store(Request $request)
	{
		$request->validate([
			'user_id' => 'required'
		]);
		
		if (!$this->user) return response()->json(['error' => 'User not found'], 403);
		
		$params = $request->all();
		$targetUser = User::where('id', $params['user_id'])->first();
		if (!$targetUser) return response()->json(['error' => 'User not found'], 403);
		
		// Check if conversation already exists between these two users
		$userConversations = UserConversation::where('user_id', $this->user->id)->pluck('conversation_id');
		$targetUserConversations = UserConversation::where('user_id', $params['user_id'])->pluck('conversation_id');
		
		$existingConversationId = $userConversations->intersect($targetUserConversations)->first();
		
		if ($existingConversationId) {
			$conversation = Conversation::find($existingConversationId);
			return new ConversationResource($conversation);
		}
		
		// Create new conversation
		$conversation = Conversation::create([
			'user_id'    => $this->user->id,
			'title'      => $targetUser->name,
			'created_at' => now()->toDateTimeString(),
			'updated_at' => now()->toDateTimeString()
		]);
		
		UserConversation::create([
			'user_id'         => $this->user->id,
			'conversation_id' => $conversation->id,
			'created_at'      => now()->toDateTimeString(),
			'updated_at'      => now()->toDateTimeString()
		]);
		
		UserConversation::create([
			'user_id'         => $params['user_id'],
			'conversation_id' => $conversation->id,
			'created_at'      => now()->toDateTimeString(),
			'updated_at'      => now()->toDateTimeString()
		]);
		
		return new ConversationResource($conversation);
	}
}
