```php
<?php
/**
 * ========================================
 * PHP/OOP Best Practices & Patterns
 * ========================================
 */

// ============================================================================
// 1. ✅ KONSTANTY MÍSTO "MAGIC STRINGS"
// ============================================================================

// ❌ ŠPATNĚ - Magic strings, překlepy nenajdeš
if ($order->state === 'pending') { }
if ($order->state === 'pendig') { } // Překlep!

// ✅ DOBŘE - Konstanty, IDE ti pomůže
class OrderState 
{
    const PENDING = 'pending';
    const SHIPPED = 'shipped';
    const DELIVERED = 'delivered';
}

if ($order->state === OrderState::PENDING) { }
if ($order->state === OrderState::PENDIG) { } // IDE error!


// ============================================================================
// 2. 🎯 ENUM PATTERN (PHP 7.4) - Rozšířené konstanty
// ============================================================================

class OrderStateEnum 
{
    const PENDING = 1;
    const SHIPPED = 2;
    const DELIVERED = 3;
    
    private static $names = [
        self::PENDING => 'Čeká na zpracování',
        self::SHIPPED => 'Odesláno',
        self::DELIVERED => 'Doručeno',
    ];
    
    private static $colors = [
        self::PENDING => 'orange',
        self::SHIPPED => 'blue',
        self::DELIVERED => 'green',
    ];
    
    public static function getName(int $state): string
    {
        return self::$names[$state] ?? 'Neznámý stav';
    }
    
    public static function getColor(int $state): string
    {
        return self::$colors[$state] ?? 'gray';
    }
    
    public static function getAll(): array
    {
        return self::$names;
    }
}

// Použití:
$stateName = OrderStateEnum::getName(OrderStateEnum::PENDING); // "Čeká na zpracování"
$color = OrderStateEnum::getColor(OrderStateEnum::PENDING); // "orange"


// ============================================================================
// 3. 🚀 VALUE OBJECTS - Type Safety & Zapouzdření Logiky
// ============================================================================

// PŘÍKLAD 1: Money - Nemůžeš sčítat různé měny
// ❌ ŠPATNĚ
function calculateTotal(float $priceEur, float $priceCzk): float 
{
    return $priceEur + $priceCzk; // Sčítáš EUR + CZK?? 😱
}
$total = calculateTotal(100, 2500); // 2600 čeho??

// ✅ DOBŘE - Value Object
class Money 
{
    private float $amount;
    private string $currency;
    
    public function __construct(float $amount, string $currency) 
    {
        $this->amount = $amount;
        $this->currency = $currency;
    }
    
    public function add(Money $other): Money 
    {
        if ($this->currency !== $other->currency) {
            throw new \InvalidArgumentException(
                "Cannot add {$other->currency} to {$this->currency}"
            );
        }
        return new Money($this->amount + $other->amount, $this->currency);
    }
    
    public function multiply(float $multiplier): Money 
    {
        return new Money($this->amount * $multiplier, $this->currency);
    }
    
    public function getAmount(): float { return $this->amount; }
    public function getCurrency(): string { return $this->currency; }
}

// Použití:
$priceEur = new Money(100, 'EUR');
$priceCzk = new Money(2500, 'CZK');
$total = $priceEur->add($priceCzk); // ❌ Exception! Nelze EUR + CZK
$discount = $priceEur->multiply(0.9); // ✅ 90 EUR


// PŘÍKLAD 2: Percentage - Validace 0-100
// ❌ ŠPATNĚ
function applyDiscount(float $price, int $percent): float 
{
    return $price - ($price * $percent / 100);
}
$final = applyDiscount(1000, 150); // 150% sleva?? -500 Kč? 😱

// ✅ DOBŘE - Value Object
class Percentage 
{
    private int $value;
    
    public function __construct(int $value) 
    {
        if ($value < 0 || $value > 100) {
            throw new \InvalidArgumentException(
                "Percentage must be 0-100, got: $value"
            );
        }
        $this->value = $value;
    }
    
    public function getValue(): int { return $this->value; }
    
    public function applyTo(float $amount): float 
    {
        return $amount * ($this->value / 100);
    }
}

function applyDiscountSafe(float $price, Percentage $percent): float 
{
    return $price - $percent->applyTo($price);
}

$final = applyDiscountSafe(1000, new Percentage(150)); // ❌ Exception!
$final = applyDiscountSafe(1000, new Percentage(20));  // ✅ 800 Kč


// PŘÍKLAD 3: OrderState Value Object - Jen platné stavy
class OrderStateVO 
{
    private int $value;
    
    private const NEW = 1;
    private const PAID = 2;
    private const SHIPPED = 3;
    
    private static $valid = [self::NEW, self::PAID, self::SHIPPED];
    
    private function __construct(int $value) 
    {
        if (!in_array($value, self::$valid)) {
            throw new \InvalidArgumentException("Invalid state: $value");
        }
        $this->value = $value;
    }
    
    public static function new(): self { return new self(self::NEW); }
    public static function paid(): self { return new self(self::PAID); }
    public static function shipped(): self { return new self(self::SHIPPED); }
    
    public function isNew(): bool { return $this->value === self::NEW; }
    public function isPaid(): bool { return $this->value === self::PAID; }
    
    public function getValue(): int { return $this->value; }
}

// Použití:
$state = OrderStateVO::paid(); // ✅ Jen platné stavy!
$state = new OrderStateVO(999); // ❌ Private constructor - nelze!
if ($state->isPaid()) { /* Ship order */ }


// ============================================================================
// 4. 🛡️ NULL OBJECT PATTERN - Žádné null checks
// ============================================================================

// ❌ ŠPATNĚ - Null checks všude
$user = $userRepo->find($id);
if ($user !== null) {
    echo $user->getName();
} else {
    echo 'Guest';
}

// ✅ DOBŘE - Null Object
interface UserInterface 
{
    public function getName(): string;
    public function isGuest(): bool;
}

class User implements UserInterface 
{
    private string $name;
    
    public function __construct(string $name) 
    {
        $this->name = $name;
    }
    
    public function getName(): string { return $this->name; }
    public function isGuest(): bool { return false; }
}

class GuestUser implements UserInterface 
{
    public function getName(): string { return 'Guest'; }
    public function isGuest(): bool { return true; }
}

// Použití:
$user = $userRepo->find($id) ?? new GuestUser();
echo $user->getName(); // Vždy funguje, žádný null check!


// ============================================================================
// 5. 🎨 EARLY RETURN - Guard Clauses místo vnořených if
// ============================================================================

// ❌ ŠPATNĚ - Pyramid of Doom
function processOrder($data) 
{
    if ($data !== null) {
        if ($data->isValid()) {
            if ($data->hasPermission()) {
                return $data->process();
            } else {
                return 'No permission';
            }
        } else {
            return 'Invalid';
        }
    } else {
        return 'No data';
    }
}

// ✅ DOBŘE - Guard Clauses (Early Return)
function processOrderClean($data) 
{
    if ($data === null) {
        return 'No data';
    }
    
    if (!$data->isValid()) {
        return 'Invalid';
    }
    
    if (!$data->hasPermission()) {
        return 'No permission';
    }
    
    return $data->process();
}


// ============================================================================
// 6. 🔒 IMMUTABLE OBJECTS - Objekty se nemění
// ============================================================================

// ❌ ŠPATNĚ - Mutable (někdo změní a nevíš kde)
class MutablePrice 
{
    public float $value;
    
    public function __construct(float $value) 
    {
        $this->value = $value;
    }
    
    public function setValue(float $value) 
    {
        $this->value = $value;
    }
}

$price = new MutablePrice(100);
someFunction($price); // Co se stalo uvnitř?
echo $price->value; // Kdo ví... možná 100, možná 200?

// ✅ DOBŘE - Immutable (vrací nové instance)
class ImmutablePrice 
{
    private float $value;
    
    public function __construct(float $value) 
    {
        $this->value = $value;
    }
    
    public function getValue(): float { return $this->value; }
    
    public function withDiscount(int $percent): self 
    {
        return new self($this->value * (100 - $percent) / 100);
    }
    
    public function withTax(float $taxRate): self 
    {
        return new self($this->value * (1 + $taxRate));
    }
}

// Použití:
$price = new ImmutablePrice(100);
$discounted = $price->withDiscount(10); // Nový objekt
$withTax = $discounted->withTax(0.21); // Další nový objekt

echo $price->getValue(); // Stále 100! Původní nezměněn
echo $discounted->getValue(); // 90
echo $withTax->getValue(); // 108.9


// ============================================================================
// 7. 🎯 TYPE HINTS VŠUDE (PHP 7.4)
// ============================================================================

// ❌ ŠPATNĚ - Bez type hints
function calculate($a, $b) 
{
    return $a + $b;
}
calculate('10', '20'); // "1020" (string concatenation) 😱
calculate([1, 2], [3, 4]); // Fatal error až za běhu

// ✅ DOBŘE - S type hints
function calculateSafe(int $a, int $b): int 
{
    return $a + $b;
}
calculateSafe('10', '20'); // TypeError hned! ✅
calculateSafe(10, 20); // 30 ✅


// ============================================================================
// 8. 📦 DEPENDENCY INJECTION místo new
// ============================================================================

// ❌ ŠPATNĚ - Tight Coupling (pevné závislosti)
class OrderService 
{
    public function process() 
    {
        $mailer = new Mailer(); // ❌ Nelze testovat, nelze změnit
        $logger = new Logger(); // ❌ Pevně spojené třídy
        
        $mailer->send('order@email.com', 'Order processed');
        $logger->log('Order processed');
    }
}

// ✅ DOBŘE - Dependency Injection
class OrderServiceWithDI 
{
    private Mailer $mailer;
    private Logger $logger;
    
    public function __construct(Mailer $mailer, Logger $logger) 
    {
        $this->mailer = $mailer;
        $this->logger = $logger;
    }
    
    public function process() 
    {
        $this->mailer->send('order@email.com', 'Order processed');
        $this->logger->log('Order processed');
    }
}

// Použití - lze snadno měnit implementace, testovat s mocky
$service = new OrderServiceWithDI(
    new SmtpMailer(), // nebo MockMailer() v testech
    new FileLogger()  // nebo DatabaseLogger()
);


// ============================================================================
// 9. 🔥 SINGLE RESPONSIBILITY - Jedna třída = jeden důvod ke změně
// ============================================================================

// ❌ ŠPATNĚ - Dělá všechno
class OrderGod 
{
    public function createOrder($data) { /* ... */ }
    public function sendEmail($to, $subject) { /* ... */ }
    public function logToDatabase($message) { /* ... */ }
    public function validateCreditCard($number) { /* ... */ }
    public function generatePdf($order) { /* ... */ }
}

// ✅ DOBŘE - Každá třída má jednu odpovědnost
class OrderCreator 
{
    public function create($data) { /* ... */ }
}

class EmailSender 
{
    public function send($to, $subject, $body) { /* ... */ }
}

class Logger 
{
    public function log($message) { /* ... */ }
}

class CreditCardValidator 
{
    public function validate($number): bool { /* ... */ }
}

class PdfGenerator 
{
    public function generate($order): string { /* ... */ }
}


// ============================================================================
// 10. 🎭 INTERFACE SEGREGATION - Malé, specifické interfaces
// ============================================================================

// ❌ ŠPATNĚ - Obrovský interface, vynucuje nepotřebné metody
interface WorkerGod 
{
    public function work();
    public function eat();
    public function sleep();
    public function getPaid();
}

class Robot implements WorkerGod 
{
    public function work() { /* OK */ }
    public function eat() { /* Robot nejí! */ }
    public function sleep() { /* Robot nespí! */ }
    public function getPaid() { /* Robot nedostává výplatu! */ }
}

// ✅ DOBŘE - Malé, specifické interfaces
interface Workable 
{
    public function work();
}

interface Eatable 
{
    public function eat();
}

interface Sleepable 
{
    public function sleep();
}

interface Payable 
{
    public function getPaid();
}

class Human implements Workable, Eatable, Sleepable, Payable 
{
    public function work() { /* ... */ }
    public function eat() { /* ... */ }
    public function sleep() { /* ... */ }
    public function getPaid() { /* ... */ }
}

class RobotWorker implements Workable 
{
    public function work() { /* ... */ }
    // Jen to, co skutečně umí!
}


// ============================================================================
// 11. 🏭 FACTORY PATTERN - Vytváření komplexních objektů
// ============================================================================

// ❌ ŠPATNĚ - Složité vytváření všude v kódu
$order = new Order();
$order->setCustomer($customer);
$order->setShippingAddress($address);
$order->setPaymentMethod($payment);
$order->setState(OrderState::NEW);
$order->setCreatedAt(new DateTime());
// ... 20 dalších setterů

// ✅ DOBŘE - Factory zapouzdřuje logiku vytváření
class OrderFactory 
{
    public function createFromCart(Cart $cart, Customer $customer): Order 
    {
        $order = new Order();
        $order->setCustomer($customer);
        $order->setShippingAddress($customer->getDefaultAddress());
        $order->setPaymentMethod($cart->getPaymentMethod());
        $order->setState(OrderState::NEW);
        $order->setCreatedAt(new DateTime());
        $order->setTotal($cart->getTotal());
        
        foreach ($cart->getItems() as $item) {
            $order->addItem($item);
        }
        
        return $order;
    }
}

// Použití:
$orderFactory = new OrderFactory();
$order = $orderFactory->createFromCart($cart, $customer);


// ============================================================================
// 12. 🔗 METHOD CHAINING (Fluent Interface)
// ============================================================================

// ❌ ŠPATNĚ - Hodně řádků
$query = new QueryBuilder();
$query->select('*');
$query->from('users');
$query->where('active', true);
$query->orderBy('created_at', 'DESC');
$query->limit(10);
$result = $query->get();

// ✅ DOBŘE - Fluent interface (vrací $this)
class QueryBuilder 
{
    private string $select = '';
    private string $from = '';
    private array $where = [];
    
    public function select(string $columns): self 
    {
        $this->select = $columns;
        return $this; // Vrací sebe sama
    }
    
    public function from(string $table): self 
    {
        $this->from = $table;
        return $this;
    }
    
    public function where(string $column, $value): self 
    {
        $this->where[] = [$column, $value];
        return $this;
    }
    
    public function get(): array 
    {
        // Execute query
        return [];
    }
}

// Použití - řetězení metod:
$result = (new QueryBuilder())
    ->select('*')
    ->from('users')
    ->where('active', true)
    ->orderBy('created_at', 'DESC')
    ->limit(10)
    ->get();


// ============================================================================
// 13. 💎 BONUS: Praktické tipy
// ============================================================================

// TIP 1: Používej ?? místo ternary pro null checks
$name = $user->name ?? 'Guest'; // místo: $user->name ? $user->name : 'Guest'

// TIP 2: Spaceship operator pro porovnání
usort($array, fn($a, $b) => $a <=> $b); // místo: $a > $b ? 1 : ($a < $b ? -1 : 0)

// TIP 3: Null safe operator (PHP 8.0+, ale dobrý vědět)
// $country = $user?->getAddress()?->getCountry()?->getName();

// TIP 4: Array destructuring
[$firstName, $lastName] = explode(' ', $fullName);

// TIP 5: Arrow functions (PHP 7.4+)
$prices = array_map(fn($item) => $item->price, $items);

// TIP 6: Typed properties (PHP 7.4+)
class Product 
{
    private int $id;
    private string $name;
    private float $price;
    private ?string $description = null; // Nullable
}

// TIP 7: Spread operator
$array1 = [1, 2, 3];
$array2 = [...$array1, 4, 5, 6]; // [1, 2, 3, 4, 5, 6]

// TIP 8: Named arguments (PHP 8.0+, ale dobrý vědět)
// createOrder(customer: $customer, total: 1000, shipping: 'DHL');


// ============================================================================
// 📚 SHRNUTÍ - Co používat VŽDY:
// ============================================================================

/*
1. ✅ Konstanty místo magic strings/numbers
2. ✅ Type hints všude (int, string, array, vlastní třídy)
3. ✅ Early return (guard clauses)
4. ✅ Dependency Injection
5. ✅ Single Responsibility (malé, zaměřené třídy)
6. ✅ Value Objects pro důležitá data (Money, Email, Percentage)
7. ✅ Immutabilita kde to dává smysl
8. ✅ Null Object pattern místo null checks
9. ✅ PHPDoc kde type hints nestačí
10. ✅ Smysluplné názvy (ne $a, $tmp, $data)

❌ NIKDY:
- Magic strings/numbers bez konstant
- Velké třídy (God Objects)
- new v business logice (použij DI)
- Public properties (použij gettery/settery)
- Hluboké vnořené ify (pyramid of doom)
*/
```

Máš to! Celé najednou pro Gist. Chceš ještě něco konkrétního? 🚀