// modules/helpdesk/helpdesk.conversation.service.ts
import { FastifyInstance } from 'fastify'
import { getOrCreateContact } from './helpdesk.contact.service.js'
import {useNextNumberRangeNumber} from "../../utils/functions";
import { and, desc, eq } from "drizzle-orm";
import { customers, helpdesk_contacts, helpdesk_conversations } from "../../../db/schema";

export async function createConversation(
    server: FastifyInstance,
    {
        tenant_id,
        contact,
        channel_instance_id,
        subject,
        customer_id = null,
        contact_person_id = null,
    }: {
        tenant_id: number
        contact: { email?: string; phone?: string; display_name?: string }
        channel_instance_id: string
        subject?: string,
        customer_id?: number,
        contact_person_id?: number
    }
) {
    const contactRecord = await getOrCreateContact(server, tenant_id, contact)

    const {usedNumber } = await useNextNumberRangeNumber(server, tenant_id, "tickets")

    const inserted = await server.db
        .insert(helpdesk_conversations)
        .values({
            tenantId: tenant_id,
            contactId: contactRecord.id,
            channelInstanceId: channel_instance_id,
            subject: subject || null,
            status: 'open',
            createdAt: new Date(),
            customerId: customer_id,
            contactPersonId: contact_person_id,
            ticketNumber: usedNumber
        })
        .returning()

    const data = inserted[0]

    return {
        ...data,
        channel_instance_id: data.channelInstanceId,
        contact_id: data.contactId,
        contact_person_id: data.contactPersonId,
        created_at: data.createdAt,
        customer_id: data.customerId,
        last_message_at: data.lastMessageAt,
        tenant_id: data.tenantId,
        ticket_number: data.ticketNumber,
    }
}

export async function getConversations(
    server: FastifyInstance,
    tenant_id: number,
    opts?: { status?: string; limit?: number }
) {
    const { status, limit = 50 } = opts || {}

    const filters = [eq(helpdesk_conversations.tenantId, tenant_id)]
    if (status) filters.push(eq(helpdesk_conversations.status, status))

    const data = await server.db
        .select({
            conversation: helpdesk_conversations,
            contact: helpdesk_contacts,
            customer: customers,
        })
        .from(helpdesk_conversations)
        .leftJoin(helpdesk_contacts, eq(helpdesk_contacts.id, helpdesk_conversations.contactId))
        .leftJoin(customers, eq(customers.id, helpdesk_conversations.customerId))
        .where(and(...filters))
        .orderBy(desc(helpdesk_conversations.lastMessageAt))
        .limit(limit)

    return data.map((entry) => ({
        ...entry.conversation,
        helpdesk_contacts: entry.contact,
        channel_instance_id: entry.conversation.channelInstanceId,
        contact_id: entry.conversation.contactId,
        contact_person_id: entry.conversation.contactPersonId,
        created_at: entry.conversation.createdAt,
        customer_id: entry.customer,
        last_message_at: entry.conversation.lastMessageAt,
        tenant_id: entry.conversation.tenantId,
        ticket_number: entry.conversation.ticketNumber,
    }))
}

export async function updateConversationStatus(
    server: FastifyInstance,
    conversation_id: string,
    status: string
) {
    const valid = ['open', 'in_progress', 'waiting_for_customer', 'answered', 'closed']
    if (!valid.includes(status)) throw new Error('Invalid status')

    const updated = await server.db
        .update(helpdesk_conversations)
        .set({ status })
        .where(eq(helpdesk_conversations.id, conversation_id))
        .returning()

    const data = updated[0]
    return {
        ...data,
        channel_instance_id: data.channelInstanceId,
        contact_id: data.contactId,
        contact_person_id: data.contactPersonId,
        created_at: data.createdAt,
        customer_id: data.customerId,
        last_message_at: data.lastMessageAt,
        tenant_id: data.tenantId,
        ticket_number: data.ticketNumber,
    }
}
