// 1. Union Types & Intersection Types
type User = { name: string; email: string };
type Admin = { name: string; adminLevel: number };
type Person = { name: string; age: number };
type Worker = { employeeId: number };

type UserOrAdmin = User | Admin;
type Employee = Person & Worker;

// 2. Discriminated Unions
type Circle = { kind: 'circle'; radius: number };
type Rectangle = { kind: 'rectangle'; width: number; height: number };

type Shape = Circle | Rectangle;

function calculateArea(shape: Shape): number {
  switch (shape.kind) {
    case 'circle':
      return Math.PI * shape.radius ** 2;
    case 'rectangle':
      return shape.width * shape.height;
  }
}

// 3. Tuple Types
type Coordinate = [number, number];

function getDistance(a: Coordinate, b: Coordinate): number {
  const dx = a[0] - b[0];
  const dy = a[1] - b[1];
  return Math.sqrt(dx ** 2 + dy ** 2);
}

// 4. Mapped Types & Utility Types
type ReadonlyPerson = Readonly<Person>;

function updatePerson(person: ReadonlyPerson) {
  // person.age = 30; Fehler: Readonly verhindert Änderungen
  console.log('Kann nicht geändert werden!');
}

// 5. Conditional Types
type IsString<T> = T extends string
  ? 'Ja'
  : unknown extends T
  ? 'unbekannt'
  : 'Nein';

type Test1 = IsString<string>; // "Ja"
type Test2 = IsString<number>; // "Nein"
type Test3 = IsString<unknown>; // "Unbekannt"

// 6. Type Guards
function isString(value: unknown): value is string {
  return typeof value === 'string';
}

function printUpperCase(value: unknown): void {
  if (isString(value)) {
    console.log(value.toUpperCase());
  } else {
    console.log('Kein String');
  }
}

// Bonus Challenge: Erweiterter Type Guard mit mehreren Typen
type Car = { type: 'car'; speed: number };
type Vehicle = Car | { type: 'bike'; gear: number };

function isCar(vehicle: Vehicle): vehicle is Car {
  return vehicle.type === 'car';
}

function describeVehicle(vehicle: Vehicle) {
  if (isCar(vehicle)) {
    console.log(`Auto mit Geschwindigkeit: ${vehicle.speed} km/h`);
  } else {
    console.log(`Fahrrad mit Gangzahl: ${vehicle.gear}`);
  }
}

const myCar: Vehicle = { type: 'car', speed: 120 };
const myBike: Vehicle = { type: 'bike', gear: 21 };

describeVehicle(myCar); // "Auto mit Geschwindigkeit: 120 km/h"
describeVehicle(myBike); // "Fahrrad mit Gangzahl: 21"
