import { db } from '../config/database.js'
import { personalContacts, companies } from '../db/schema.js'
import { eq, and, desc, ne } from 'drizzle-orm'
import { ConflictError, NotFoundError } from '../utils/errors.js'

export const listPersonalContacts = async (userId) => {
  const contacts = await db
    .select({
      id: personalContacts.id,
      userId: personalContacts.userId,
      companyId: personalContacts.companyId,
      firstName: personalContacts.firstName,
      lastName: personalContacts.lastName,
      phone: personalContacts.phone,
      email: personalContacts.email,
      secondaryEmail: personalContacts.secondaryEmail,
      description: personalContacts.description,
      createdAt: personalContacts.createdAt,
      updatedAt: personalContacts.updatedAt,
      companyName: companies.name,
    })
    .from(personalContacts)
    .leftJoin(companies, eq(personalContacts.companyId, companies.id))
    .where(eq(personalContacts.userId, userId))
    .orderBy(desc(personalContacts.updatedAt))

  return contacts
}

export const getContactsByCompanyId = async (companyId) => {
  return db
    .select()
    .from(personalContacts)
    .where(eq(personalContacts.companyId, companyId))
    .orderBy(desc(personalContacts.updatedAt))
}

const getContactById = async (contactId, userId) => {
  const [contact] = await db
    .select()
    .from(personalContacts)
    .where(and(eq(personalContacts.id, contactId), eq(personalContacts.userId, userId)))
    .limit(1)

  if (!contact) {
    throw new NotFoundError('Kontakt nenájdený')
  }

  return contact
}

export const createPersonalContact = async (userId, contact) => {
  const [existing] = await db
    .select({ id: personalContacts.id })
    .from(personalContacts)
    .where(and(eq(personalContacts.userId, userId), eq(personalContacts.email, contact.email)))
    .limit(1)

  if (existing) {
    throw new ConflictError('Kontakt s týmto emailom už existuje')
  }

  const [created] = await db
    .insert(personalContacts)
    .values({
      userId,
      companyId: contact.companyId || null,
      firstName: contact.firstName,
      lastName: contact.lastName || null,
      phone: contact.phone || null,
      email: contact.email,
      secondaryEmail: contact.secondaryEmail || null,
      description: contact.description || null,
    })
    .returning()

  return created
}

export const updatePersonalContact = async (contactId, userId, updates) => {
  await getContactById(contactId, userId)

  if (updates.email) {
    const [existing] = await db
      .select({ id: personalContacts.id })
      .from(personalContacts)
      .where(
        and(
          eq(personalContacts.userId, userId),
          eq(personalContacts.email, updates.email),
          ne(personalContacts.id, contactId)
        )
      )
      .limit(1)

    if (existing) {
      throw new ConflictError('Kontakt s týmto emailom už existuje')
    }
  }

  const updateData = { updatedAt: new Date() }

  if (updates.firstName !== undefined) updateData.firstName = updates.firstName
  if (updates.lastName !== undefined) updateData.lastName = updates.lastName
  if (updates.phone !== undefined) updateData.phone = updates.phone
  if (updates.email !== undefined) updateData.email = updates.email
  if (updates.secondaryEmail !== undefined) updateData.secondaryEmail = updates.secondaryEmail
  if (updates.companyId !== undefined) updateData.companyId = updates.companyId || null
  if (updates.description !== undefined) updateData.description = updates.description || null

  const [updated] = await db
    .update(personalContacts)
    .set(updateData)
    .where(and(eq(personalContacts.id, contactId), eq(personalContacts.userId, userId)))
    .returning()

  if (!updated) {
    throw new NotFoundError('Kontakt nenájdený')
  }

  return updated
}

export const deletePersonalContact = async (contactId, userId) => {
  await getContactById(contactId, userId)

  await db
    .delete(personalContacts)
    .where(and(eq(personalContacts.id, contactId), eq(personalContacts.userId, userId)))

  return { success: true, message: 'Kontakt bol odstránený' }
}
