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

const app = createApp()

describe('Customers API', () => {
  let companyId: string
  let token: string
  let agentToken: string

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

    const { employee: agent } = await createCompanyWithEmployee({ role: 'AGENT' })
    agentToken = signEmployeeToken(agent.id, agent.companyId, 'AGENT')
  })

  describe('GET /api/v1/customers', () => {
    it('returns 401 without auth', async () => {
      const res = await request(app).get('/api/v1/customers')
      expect(res.status).toBe(401)
    })

    it('returns paginated customer list', async () => {
      await createCustomer(companyId)
      await createCustomer(companyId)

      const res = await request(app)
        .get('/api/v1/customers')
        .set(authHeader(token))

      expect(res.status).toBe(200)
      expect(typeof res.body.total).toBe('number')
      expect(res.body.total).toBeGreaterThanOrEqual(2)
      expect(Array.isArray(res.body.data)).toBe(true)
    })

    it('filters by search query q', async () => {
      await createCustomer(companyId, { firstName: 'Unique', lastName: 'Xyzzy' })

      const res = await request(app)
        .get('/api/v1/customers?q=Xyzzy')
        .set(authHeader(token))

      expect(res.status).toBe(200)
      expect(res.body.total).toBeGreaterThanOrEqual(1)
      expect(res.body.data[0].lastName).toBe('Xyzzy')
    })
  })

  describe('POST /api/v1/customers', () => {
    it('creates a new customer', async () => {
      const res = await request(app)
        .post('/api/v1/customers')
        .set(authHeader(token))
        .send({
          firstName: 'Alice',
          lastName:  'Smith',
          email:     `alice-${Date.now()}@example.com`,
        })

      expect(res.status).toBe(201)
      expect(res.body.data.firstName).toBe('Alice')
      expect(res.body.data.lastName).toBe('Smith')
    })

    it('returns 400 for missing required fields', async () => {
      const res = await request(app)
        .post('/api/v1/customers')
        .set(authHeader(token))
        .send({ firstName: 'Noemail' })

      expect(res.status).toBe(400)
    })
  })

  describe('GET /api/v1/customers/:id', () => {
    it('returns a single customer', async () => {
      const customer = await createCustomer(companyId, { firstName: 'Bob', lastName: 'Test' })

      const res = await request(app)
        .get(`/api/v1/customers/${customer.id}`)
        .set(authHeader(token))

      expect(res.status).toBe(200)
      expect(res.body.data.id).toBe(customer.id)
      expect(res.body.data.firstName).toBe('Bob')
    })

    it('returns 404 for unknown id', async () => {
      const res = await request(app)
        .get('/api/v1/customers/clzunknownidzzzzzzzzzzz')
        .set(authHeader(token))

      expect(res.status).toBe(404)
    })
  })

  describe('POST /api/v1/customers/:id/flag', () => {
    it('flags a customer (MANAGER+)', async () => {
      const customer = await createCustomer(companyId)

      const res = await request(app)
        .post(`/api/v1/customers/${customer.id}/flag`)
        .set(authHeader(token))
        .send({ reason: 'Suspicious activity' })

      expect(res.status).toBe(200)
      expect(res.body.data.success).toBe(true)
    })

    it('returns 403 for AGENT role', async () => {
      const customer = await createCustomer(companyId)

      const res = await request(app)
        .post(`/api/v1/customers/${customer.id}/flag`)
        .set(authHeader(agentToken))
        .send({ reason: 'Test' })

      expect(res.status).toBe(403)
    })
  })
})
