import { plainToInstance } from 'class-transformer';
import { validate } from 'class-validator';
import { describe, it, expect } from 'vitest';
import { UpdateListingDto } from '../dto/update-listing.dto';

describe('UpdateListingDto', () => {
  it('should pass validation with title only', async () => {
    const dto = plainToInstance(UpdateListingDto, {
      title: 'Căn hộ 3PN view sông Sài Gòn',
    });

    const errors = await validate(dto);
    expect(errors).toHaveLength(0);
  });

  it('should pass validation with description only', async () => {
    const dto = plainToInstance(UpdateListingDto, {
      description: 'Căn hộ cao cấp nội thất đầy đủ, view đẹp',
    });

    const errors = await validate(dto);
    expect(errors).toHaveLength(0);
  });

  it('should pass validation with priceVND only', async () => {
    const dto = plainToInstance(UpdateListingDto, {
      priceVND: '5500000000',
    });

    const errors = await validate(dto);
    expect(errors).toHaveLength(0);
  });

  it('should pass validation with amenities only', async () => {
    const dto = plainToInstance(UpdateListingDto, {
      amenities: ['Hồ bơi', 'Gym', 'Sân chơi trẻ em'],
    });

    const errors = await validate(dto);
    expect(errors).toHaveLength(0);
  });

  it('should pass validation with all fields', async () => {
    const dto = plainToInstance(UpdateListingDto, {
      title: 'Căn hộ 3PN view sông Sài Gòn',
      description: 'Căn hộ cao cấp nội thất đầy đủ, view đẹp',
      priceVND: '5500000000',
      rentPriceMonthly: '25000000',
      amenities: ['Hồ bơi', 'Gym'],
      mediaOrder: [{ mediaId: 'media-1', order: 0 }, { mediaId: 'media-2', order: 1 }],
    });

    const errors = await validate(dto);
    expect(errors).toHaveLength(0);
  });

  it('should pass validation with mediaOrder only', async () => {
    const dto = plainToInstance(UpdateListingDto, {
      mediaOrder: [{ mediaId: 'media-1', order: 0 }, { mediaId: 'media-2', order: 1 }],
    });

    const errors = await validate(dto);
    expect(errors).toHaveLength(0);
  });

  it('should fail validation when mediaOrder items have invalid order', async () => {
    const dto = plainToInstance(UpdateListingDto, {
      mediaOrder: [{ mediaId: 'media-1', order: -1 }],
    });

    const errors = await validate(dto);
    expect(errors.length).toBeGreaterThan(0);
  });

  it('should fail validation when title is too short', async () => {
    const dto = plainToInstance(UpdateListingDto, {
      title: 'AB',
    });

    const errors = await validate(dto);
    expect(errors.length).toBeGreaterThan(0);
    const titleError = errors.find((e) => e.property === 'title');
    expect(titleError).toBeDefined();
  });

  it('should fail validation when description is too short', async () => {
    const dto = plainToInstance(UpdateListingDto, {
      description: 'Ngắn quá',
    });

    const errors = await validate(dto);
    expect(errors.length).toBeGreaterThan(0);
    const descError = errors.find((e) => e.property === 'description');
    expect(descError).toBeDefined();
  });

  it('should fail validation when amenities is not an array', async () => {
    const dto = plainToInstance(UpdateListingDto, {
      amenities: 'Hồ bơi',
    });

    const errors = await validate(dto);
    expect(errors.length).toBeGreaterThan(0);
    const amenitiesError = errors.find((e) => e.property === 'amenities');
    expect(amenitiesError).toBeDefined();
  });

  it('should strip unknown properties with whitelist', async () => {
    const dto = plainToInstance(UpdateListingDto, {
      title: 'Căn hộ 3PN view sông',
      propertyType: 'APARTMENT',
      address: '123 ABC',
    });

    const errors = await validate(dto, { whitelist: true, forbidNonWhitelisted: true });
    // propertyType and address are not in UpdateListingDto — should be forbidden
    expect(errors.length).toBeGreaterThan(0);
  });
});
