import 'dart:math' as math;
import 'package:flutter/material.dart';

/// Class utility untuk transformasi koordinat 3D World (meter) ke 2D Screen (piksel)
/// dengan proyeksi Isometrik.
class IsometricTransform {
  /// Skala piksel per meter (misalnya 1 meter = 40 piksel)
  final double scale;
  
  /// Titik origin (0,0,0) di layar
  final Offset origin;

  const IsometricTransform({
    required this.scale,
    required this.origin,
  });

  /// Mengonversi koordinat 3D World (x, y, z) dalam satuan meter ke Offset 2D Canvas (piksel).
  /// * [x] : Arah kedalaman kumbung (dari depan ke belakang) - e.g. 0 s.d 8 meter.
  /// * [y] : Arah lebar kumbung (dari kiri ke kanan) - e.g. 0 s.d 6 meter.
  /// * [z] : Arah tinggi kumbung (dari lantai ke atap) - e.g. 0 s.d 3 meter.
  Offset toScreen(double x, double y, double z) {
    const double angle = 30.0 * math.pi / 180.0; // Sudut proyeksi isometrik 30 derajat
    
    // dx = (x - y) * cos(30) * scale
    // dy = ((x + y) * sin(30) - z) * scale
    final double dx = (x - y) * math.cos(angle) * scale;
    final double dy = ((x + y) * math.sin(angle) - z) * scale;

    return Offset(origin.dx + dx, origin.dy + dy);
  }

  /// Mengonversi koordinat 2D Screen (tap) kembali ke koordinat 2D World Ground (x, y) pada z = 0.
  /// Berguna untuk mendeteksi penempatan/interaksi ketukan jari di lantai kumbung.
  Offset toWorldGround(Offset screenPt) {
    const double angle = 30.0 * math.pi / 180.0;
    final double cos30 = math.cos(angle);
    final double sin30 = math.sin(angle);

    final double rx = screenPt.dx - origin.dx;
    final double ry = screenPt.dy - origin.dy;

    // x - y = rx / (cos(30) * scale)
    // x + y = ry / (sin(30) * scale)
    final double diffVal = rx / (cos30 * scale);
    final double sumVal = ry / (sin30 * scale);

    final double x = (sumVal + diffVal) / 2;
    final double y = (sumVal - diffVal) / 2;

    return Offset(x, y);
  }
}
