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

describe('CreateListingDto', () => {
  it('should pass validation with all required fields', async () => {
    const dto = plainToInstance(CreateListingDto, {
      transactionType: 'SALE',
      priceVND: '5500000000',
      propertyType: 'APARTMENT',
      title: 'Căn hộ 3PN view sông Sài Gòn',
      description: 'Căn hộ cao cấp 3 phòng ngủ, nội thất đầy đủ',
      address: '208 Nguyễn Hữu Cảnh',
      ward: 'Phường 22',
      district: 'Bình Thạnh',
      city: 'Hồ Chí Minh',
      latitude: 10.7942,
      longitude: 106.7219,
      areaM2: 85.5,
    });

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

  it('should fail validation when title is too short', async () => {
    const dto = plainToInstance(CreateListingDto, {
      transactionType: 'SALE',
      priceVND: '5000000000',
      propertyType: 'APARTMENT',
      title: 'AB',
      description: 'Căn hộ cao cấp 3 phòng ngủ, nội thất đầy đủ',
      address: '123 ABC',
      ward: 'Ward',
      district: 'District',
      city: 'City',
      latitude: 10.77,
      longitude: 106.70,
      areaM2: 80,
    });

    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 with invalid transactionType', async () => {
    const dto = plainToInstance(CreateListingDto, {
      transactionType: 'INVALID',
      priceVND: '5000000000',
      propertyType: 'APARTMENT',
      title: 'Căn hộ đẹp Quận 1',
      description: 'Mô tả đầy đủ chi tiết',
      address: '123 ABC',
      ward: 'Ward',
      district: 'District',
      city: 'City',
      latitude: 10.77,
      longitude: 106.70,
      areaM2: 80,
    });

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

  it('should fail validation when latitude is out of range', async () => {
    const dto = plainToInstance(CreateListingDto, {
      transactionType: 'SALE',
      priceVND: '5000000000',
      propertyType: 'APARTMENT',
      title: 'Căn hộ đẹp Quận 1',
      description: 'Mô tả đầy đủ chi tiết',
      address: '123 ABC',
      ward: 'Ward',
      district: 'District',
      city: 'City',
      latitude: 999,
      longitude: 106.70,
      areaM2: 80,
    });

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

  it('should pass validation with optional fields', async () => {
    const dto = plainToInstance(CreateListingDto, {
      transactionType: 'SALE',
      priceVND: '5500000000',
      propertyType: 'TOWNHOUSE',
      title: 'Nhà phố đẹp Quận 3',
      description: 'Nhà phố 3 tầng mặt tiền rộng',
      address: '456 Lê Lợi',
      ward: 'Phường 1',
      district: 'Quận 3',
      city: 'Hồ Chí Minh',
      latitude: 10.78,
      longitude: 106.69,
      areaM2: 120,
      bedrooms: 3,
      bathrooms: 2,
      floors: 3,
      direction: 'EAST',
      yearBuilt: 2020,
      legalStatus: 'Sổ hồng',
    });

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

  it('should fail validation when areaM2 is less than 1', async () => {
    const dto = plainToInstance(CreateListingDto, {
      transactionType: 'SALE',
      priceVND: '5000000000',
      propertyType: 'APARTMENT',
      title: 'Căn hộ đẹp Quận 1',
      description: 'Mô tả đầy đủ chi tiết',
      address: '123 ABC',
      ward: 'Ward',
      district: 'District',
      city: 'City',
      latitude: 10.77,
      longitude: 106.70,
      areaM2: 0,
    });

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