import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter_scene/camera.dart';
import 'package:flutter_scene/node.dart';
import 'package:flutter_scene/scene.dart';
import 'package:vector_math/vector_math.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  MyAppState createState() => MyAppState();
}

class MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
  double elapsedSeconds = 0.009;
  Scene scene = Scene();

  double pointerx = 0.0;
  double pointery = 0.0;

  double cameraRotateX = 0.0;
  double cameraRotateY = 0.0;

  @override
  void initState() {
    createTicker((elapsed) {
      setState(() {
        elapsedSeconds = elapsed.inMilliseconds.toDouble() / 1000;
        // print(elapsedSeconds);
        // elapsedSeconds = cameraRotateX;
      });
    }).start();

    setState(() {});

    Node.fromAsset('assets/DamagedHelmet.model').then(
      (model) {
        model.name = 'Helmet';
        scene.add(model);
      },
    );

    super.initState();
  }

  void pointerUpdate(details, BuildContext context) {
    final screenWidth = MediaQuery.of(context).size.width;
    // print(screenWidth);
    final lastPointerX = pointerx;
    final lastPointerY = pointery;
    pointerx = details.globalPosition.dx;
    pointery = details.globalPosition.dy;
    // print(pointerx);
    // print(pointery);
    if (pointerx > lastPointerX) {
      print("ROTATE RIGHT!");
      setState(() {
        cameraRotateX += 1 / 80;
      });
    } else {
      print("ROTATE LEFT!");
      setState(() {
        cameraRotateX -= 1 / 80;
      });
    }

    if (pointery > lastPointerY) {
      print("ROTATE RIGHT!");
      setState(() {
        cameraRotateY += 1 / 80;
      });
    } else {
      print("ROTATE LEFT!");
      setState(() {
        cameraRotateY -= 1 / 80;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    final painter = ScenePainter(
      scene: scene,
      camera: PerspectiveCamera(
        // position: Vector3(sin(cameraRotateX) * 3, 3, cos(cameraRotateX) * 3),
        position: Vector3(sin(elapsedSeconds) * 3, 3, cos(elapsedSeconds) * 3),
        target: Vector3(0, 0, 0),
      ),
    );

    return MaterialApp(
      title: 'My 3D app',
      home: GestureDetector(
        onTapDown: (details) => pointerUpdate(details, context),
        onTapUp: (details) => pointerUpdate(details, context),
        onVerticalDragUpdate: (details) => pointerUpdate(details, context),
        onHorizontalDragUpdate: (details) => pointerUpdate(details, context),
        child: CustomPaint(
          painter: painter,
        ),
      ),
    );
  }
}

class ScenePainter extends CustomPainter {
  ScenePainter({
    required this.scene,
    required this.camera,
  });

  Scene scene;
  Camera camera;

  @override
  void paint(Canvas canvas, Size size) {
    scene.render(camera, canvas, viewport: Offset.zero & size);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}
