package inventory;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

/**
 * Unit tests for ProductFactory class.
 */
class ProductFactoryTest {

    /**
     * Test creating a valid book product
     */
    @Test
    void testCreateValidBook() {
        Product book = ProductFactory.createProduct("B001", "Java Book", "BOOK", 15.99, 5);
        assertNotNull(book);
        assertEquals("B001", book.getId());
        assertEquals("BOOK", book.getType());
        assertEquals(15.99, book.getPrice());
    }

    /**
     * Test creating a valid electronics product
     */
    @Test
    void testCreateValidElectronics() {
        Product electronics = ProductFactory.createProduct("E001", "Java Book", "ELECTRONICS", 15.99, 5);
        assertNotNull(electronics);
        assertEquals("E001", electronics.getId());
        assertEquals("ELECTRONICS", electronics.getType());
        assertEquals(15.99, electronics.getPrice());
    }

    /**
     * Test book minimum price validation
     */
    @Test
    void testBookMinimumPriceValidation() {
        assertThrows(IllegalArgumentException.class, () -> {
            ProductFactory.createProduct("B001", "Cheap Book", "BOOK", 3.99, 5);
        });
    }

    /**
     * Test electronics minimum price validation
     */
    @Test
    void testElectronicsMinimumPriceValidation() {
        assertThrows(IllegalArgumentException.class, () -> {
            ProductFactory.createProduct("E001", "Cheap Electronics", "ELECTRONICS", 5.99, 5);
        });
    }

    /**
     * Test invalid product type
     */
    @Test
    void testInvalidProductType() {
        assertThrows(IllegalArgumentException.class, () -> {
            ProductFactory.createProduct("S001", "Sheep", "SHEEP", 1.99, 5);
        });
    }

    /**
     * Test boundary conditions
     */
    @Test
    void testBoundaryConditions() {
        Product book = ProductFactory.createProduct("B001", "Java Book", "BOOK", 5.00, 5);
        assertNotNull(book);
        Product electronics = ProductFactory.createProduct("B001", "Java Book", "ELECTRONICS", 10.00, 5);
        assertNotNull(electronics);
    }

    @Test
    void testNullValues() {
        assertThrows(IllegalArgumentException.class, () -> ProductFactory.createProduct(null, "Cheap Book", "BOOK", 1.99, 5));
        assertThrows(IllegalArgumentException.class, () -> ProductFactory.createProduct("B001", null, "BOOK", 3.99, 5));
        assertThrows(IllegalArgumentException.class, () -> ProductFactory.createProduct("B001", "Cheap Book", null, 3.99, 5));
    }

    @Test
    void testEmptyValues() {
        assertThrows(IllegalArgumentException.class, () -> ProductFactory.createProduct("", "Cheap Book", "BOOK", 1.99, 5));
        assertThrows(IllegalArgumentException.class, () -> ProductFactory.createProduct("B001", "", "BOOK", 3.99, 5));
        assertThrows(IllegalArgumentException.class, () -> ProductFactory.createProduct("B001", "Cheap Book", "", 3.99, 5));
    }

    @Test
    void testNegativeAndZeroValues() {
        assertThrows(IllegalArgumentException.class, () -> ProductFactory.createProduct("B001", "Cheap Book", "BOOK", 0, 5));
        assertThrows(IllegalArgumentException.class, () -> ProductFactory.createProduct("B001", "Cheap Book", "BOOK", 3.99, 0));
        assertThrows(IllegalArgumentException.class, () -> ProductFactory.createProduct("B001", "Cheap Book", "BOOK", -1, 5));
        assertThrows(IllegalArgumentException.class, () -> ProductFactory.createProduct("B001", "Cheap Book", "BOOK", 3.99, -1));
    }
}