import { describe, it, expect } from 'vitest';
import { CreateListingCommand } from '../commands/create-listing/create-listing.command';
import { ModerateListingCommand } from '../commands/moderate-listing/moderate-listing.command';
import { UpdateListingStatusCommand } from '../commands/update-listing-status/update-listing-status.command';
import { UploadMediaCommand } from '../commands/upload-media/upload-media.command';

describe('CreateListingCommand', () => {
  it('should store all required properties', () => {
    const command = new CreateListingCommand(
      'seller-1',
      'SALE',
      5_000_000_000n,
      'APARTMENT',
      'Căn hộ đẹp Quận 1',
      'Mô tả chi tiết',
      '123 Nguyễn Huệ',
      'Bến Nghé',
      'Quận 1',
      'Hồ Chí Minh',
      10.7769,
      106.7009,
      80,
    );

    expect(command.sellerId).toBe('seller-1');
    expect(command.transactionType).toBe('SALE');
    expect(command.priceVND).toBe(5_000_000_000n);
    expect(command.propertyType).toBe('APARTMENT');
    expect(command.title).toBe('Căn hộ đẹp Quận 1');
    expect(command.description).toBe('Mô tả chi tiết');
    expect(command.address).toBe('123 Nguyễn Huệ');
    expect(command.ward).toBe('Bến Nghé');
    expect(command.district).toBe('Quận 1');
    expect(command.city).toBe('Hồ Chí Minh');
    expect(command.latitude).toBe(10.7769);
    expect(command.longitude).toBe(106.7009);
    expect(command.areaM2).toBe(80);
  });

  it('should store optional properties', () => {
    const command = new CreateListingCommand(
      'seller-1',
      'RENT',
      3_000_000_000n,
      'TOWNHOUSE',
      'Nhà phố cho thuê',
      'Nhà phố 3 tầng mặt tiền rộng',
      '456 Lê Lợi',
      'Phường 1',
      'Quận 3',
      'Hồ Chí Minh',
      10.78,
      106.69,
      120,
      100,      // usableAreaM2
      3,        // bedrooms
      2,        // bathrooms
      3,        // floors
      undefined, // floor
      undefined, // totalFloors
      'EAST',   // direction
      2020,     // yearBuilt
      'Sổ hồng', // legalStatus
      { parking: true }, // amenities
      [],       // nearbyPOIs
      500,      // metroDistanceM
      undefined, // projectName
      'agent-1', // agentId
      25_000_000n, // rentPriceMonthly
      2.5,      // commissionPct
    );

    expect(command.usableAreaM2).toBe(100);
    expect(command.bedrooms).toBe(3);
    expect(command.bathrooms).toBe(2);
    expect(command.floors).toBe(3);
    expect(command.direction).toBe('EAST');
    expect(command.yearBuilt).toBe(2020);
    expect(command.legalStatus).toBe('Sổ hồng');
    expect(command.agentId).toBe('agent-1');
    expect(command.rentPriceMonthly).toBe(25_000_000n);
    expect(command.commissionPct).toBe(2.5);
  });

  it('should default optional properties to undefined', () => {
    const command = new CreateListingCommand(
      'seller-1', 'SALE', 1_000_000_000n,
      'LAND', 'Đất nền', 'Mô tả',
      '789 ABC', 'Ward', 'District', 'City',
      10.0, 106.0, 200,
    );

    expect(command.usableAreaM2).toBeUndefined();
    expect(command.bedrooms).toBeUndefined();
    expect(command.agentId).toBeUndefined();
    expect(command.rentPriceMonthly).toBeUndefined();
  });
});

describe('ModerateListingCommand', () => {
  it('should store all properties for approve', () => {
    const command = new ModerateListingCommand(
      'listing-1',
      'admin-1',
      'approve',
      95,
      'Tin đăng hợp lệ',
    );

    expect(command.listingId).toBe('listing-1');
    expect(command.moderatorId).toBe('admin-1');
    expect(command.action).toBe('approve');
    expect(command.moderationScore).toBe(95);
    expect(command.notes).toBe('Tin đăng hợp lệ');
  });

  it('should store properties for reject without score', () => {
    const command = new ModerateListingCommand(
      'listing-2',
      'admin-1',
      'reject',
      undefined,
      'Nội dung vi phạm',
    );

    expect(command.action).toBe('reject');
    expect(command.moderationScore).toBeUndefined();
    expect(command.notes).toBe('Nội dung vi phạm');
  });

  it('should default optional fields to undefined', () => {
    const command = new ModerateListingCommand(
      'listing-3',
      'admin-1',
      'approve',
    );

    expect(command.moderationScore).toBeUndefined();
    expect(command.notes).toBeUndefined();
  });
});

describe('UpdateListingStatusCommand', () => {
  it('should store all properties', () => {
    const command = new UpdateListingStatusCommand(
      'listing-1',
      'ACTIVE',
      'user-1',
      'Đã xác minh thông tin',
    );

    expect(command.listingId).toBe('listing-1');
    expect(command.newStatus).toBe('ACTIVE');
    expect(command.userId).toBe('user-1');
    expect(command.moderationNotes).toBe('Đã xác minh thông tin');
  });

  it('should default moderationNotes to undefined', () => {
    const command = new UpdateListingStatusCommand(
      'listing-2',
      'SOLD',
      'user-2',
    );

    expect(command.moderationNotes).toBeUndefined();
  });
});

describe('UploadMediaCommand', () => {
  it('should store all properties', () => {
    const file = {
      buffer: Buffer.from('test-image-data'),
      mimetype: 'image/jpeg',
      originalname: 'photo.jpg',
      size: 1024,
    };

    const command = new UploadMediaCommand(
      'prop-1',
      'user-1',
      file,
      'Mặt tiền nhà',
    );

    expect(command.propertyId).toBe('prop-1');
    expect(command.userId).toBe('user-1');
    expect(command.file.mimetype).toBe('image/jpeg');
    expect(command.file.originalname).toBe('photo.jpg');
    expect(command.file.size).toBe(1024);
    expect(command.caption).toBe('Mặt tiền nhà');
  });

  it('should default caption to undefined', () => {
    const file = {
      buffer: Buffer.from('test-video-data'),
      mimetype: 'video/mp4',
      originalname: 'tour.mp4',
      size: 50_000_000,
    };

    const command = new UploadMediaCommand('prop-2', 'user-2', file);

    expect(command.caption).toBeUndefined();
  });
});
