<?php

namespace App\Models;

use CodeIgniter\Model;

class ConversationModel extends Model
{
    protected $table         = 'conversations';
    protected $useTimestamps = true;
    protected $createdField  = 'created_at';
    protected $updatedField  = '';
    protected $allowedFields = ['job_application_id'];

    public function addParticipants(int $conversationId, array $userIds): void
    {
        $db = \Config\Database::connect();
        foreach ($userIds as $userId) {
            $exists = $db->table('conversation_participants')->where('conversation_id', $conversationId)->where('user_id', $userId)->get()->getRow();
            if (! $exists) {
                $db->table('conversation_participants')->insert(['conversation_id' => $conversationId, 'user_id' => $userId]);
            }
        }
    }

    public function isParticipant(int $conversationId, int $userId): bool
    {
        return \Config\Database::connect()->table('conversation_participants')
            ->where('conversation_id', $conversationId)->where('user_id', $userId)
            ->get()->getRow() !== null;
    }

    public function forUser(int $userId): array
    {
        $db = \Config\Database::connect();

        $conversations = $db->table('conversation_participants cp')
            ->select('c.*, (SELECT body FROM messages m WHERE m.conversation_id = c.id ORDER BY m.created_at DESC LIMIT 1) as last_message,
                      (SELECT created_at FROM messages m WHERE m.conversation_id = c.id ORDER BY m.created_at DESC LIMIT 1) as last_message_at')
            ->join('conversations c', 'c.id = cp.conversation_id')
            ->where('cp.user_id', $userId)
            ->orderBy('last_message_at', 'DESC')
            ->get()->getResultArray();

        // For each conversation, look up the OTHER participant(s) — this
        // is what actually makes the list usable: "Conversation #1" tells
        // you nothing, but "GMB Service" or "Ali Raza" does.
        foreach ($conversations as &$conv) {
            $otherParticipant = $db->table('conversation_participants cp')
                ->select('u.id, u.name, u.username, u.profile_photo_path, r.slug as role_slug, a.company_name, a.logo_path')
                ->join('users u', 'u.id = cp.user_id')
                ->join('roles r', 'r.id = u.role_id')
                ->join('agencies a', 'a.id = u.agency_id', 'left')
                ->where('cp.conversation_id', $conv['id'])
                ->where('cp.user_id !=', $userId)
                ->get()->getRow();

            $conv['other_participant'] = $otherParticipant ? [
                'user_id'      => $otherParticipant->id,
                'display_name' => $otherParticipant->company_name ?: $otherParticipant->name,
                'username'     => $otherParticipant->username,
                'photo_path'   => $otherParticipant->company_name ? $otherParticipant->logo_path : $otherParticipant->profile_photo_path,
                'role_slug'    => $otherParticipant->role_slug,
            ] : null;
        }

        return $conversations;
    }

    public function betweenUsers(array $userIds, ?int $jobApplicationId = null): ?array
    {
        // Finds an existing 1:1 (or n-party) conversation with exactly
        // these participants, optionally scoped to a specific application.
        $db = \Config\Database::connect();
        $builder = $db->table('conversations c');

        if ($jobApplicationId !== null) {
            $builder->where('c.job_application_id', $jobApplicationId);
        }

        $candidates = $builder->get()->getResultArray();

        foreach ($candidates as $conv) {
            $participants = $db->table('conversation_participants')->where('conversation_id', $conv['id'])->get()->getResultArray();
            $participantIds = array_map(fn ($p) => (int) $p['user_id'], $participants);
            sort($participantIds);
            $target = $userIds;
            sort($target);
            if ($participantIds === $target) {
                return $conv;
            }
        }

        return null;
    }
}
