import request from 'supertest'
import { prisma } from '../../lib/prisma'
import { createApp } from '../../app'
import {
  authHeader,
  createCompanyWithEmployee,
  createCustomer,
  createReservation,
  createVehicle,
  signEmployeeToken,
} from '../helpers/fixtures'

const app = createApp()

describe('Complaints and reviews integration', () => {
  let companyId: string
  let token: string
  let reservationId: string
  let customerId: string

  beforeAll(async () => {
    const { company, employee } = await createCompanyWithEmployee({ role: 'OWNER' })
    companyId = company.id
    token = signEmployeeToken(employee.id, companyId, 'OWNER')

    const vehicle = await createVehicle(companyId)
    const customer = await createCustomer(companyId)
    customerId = customer.id
    const reservation = await createReservation(companyId, vehicle.id, customer.id)
    reservationId = reservation.id
  })

  it('creates, lists, resolves, and deletes a tenant-scoped complaint', async () => {
    const createRes = await request(app)
      .post('/api/v1/complaints')
      .set(authHeader(token))
      .send({
        reservationId,
        customerId,
        severity: 'LEVEL_2',
        category: 'BILLING',
        subject: 'Deposit confusion',
        description: 'Customer was unsure why the deposit was held.',
      })

    expect(createRes.status).toBe(201)
    expect(createRes.body.data).toMatchObject({
      companyId,
      reservationId,
      customerId,
      severity: 'LEVEL_2',
      category: 'BILLING',
      subject: 'Deposit confusion',
      status: 'OPEN',
    })

    const complaintId = createRes.body.data.id
    const listRes = await request(app)
      .get('/api/v1/complaints?status=OPEN&severity=LEVEL_2&category=BILLING')
      .set(authHeader(token))

    expect(listRes.status).toBe(200)
    expect(listRes.body.data.data.some((item: any) => item.id === complaintId)).toBe(true)

    const patchRes = await request(app)
      .patch(`/api/v1/complaints/${complaintId}`)
      .set(authHeader(token))
      .send({ status: 'RESOLVED', resolution: 'Explained deposit release timing.' })

    expect(patchRes.status).toBe(200)
    expect(patchRes.body.data.status).toBe('RESOLVED')
    expect(patchRes.body.data.resolvedAt).toEqual(expect.any(String))

    const deleteRes = await request(app)
      .delete(`/api/v1/complaints/${complaintId}`)
      .set(authHeader(token))

    expect(deleteRes.status).toBe(200)
    expect(deleteRes.body.data).toEqual({ success: true })
  })

  it('lists reviews by rating and timestamps company replies', async () => {
    const review = await prisma.review.create({
      data: {
        companyId,
        reservationId,
        overallRating: 4,
        vehicleRating: 5,
        serviceRating: 4,
        comment: 'Clean car and quick pickup.',
        category: 'STAFF_SERVICE',
      } as any,
    })

    const listRes = await request(app)
      .get('/api/v1/reviews?rating=4&page=1&pageSize=10')
      .set(authHeader(token))

    expect(listRes.status).toBe(200)
    expect(listRes.body.data.data.some((item: any) => item.id === review.id)).toBe(true)

    const replyRes = await request(app)
      .patch(`/api/v1/reviews/${review.id}/reply`)
      .set(authHeader(token))
      .send({ companyReply: 'Thanks for renting with us.' })

    expect(replyRes.status).toBe(200)
    expect(replyRes.body.data.companyReply).toBe('Thanks for renting with us.')
    expect(replyRes.body.data.companyRepliedAt).toEqual(expect.any(String))
  })
})
