import 'package:shelf/shelf.dart';
import 'package:shelf_router/shelf_router.dart';
import 'package:bcrypt/bcrypt.dart';
import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart';
import 'package:dotenv/dotenv.dart';
import '../database/database_provider.dart';
import '../middleware/auth_middleware.dart';
import 'dart:convert';

class AuthRoutes {
  final DatabaseProvider database;

  AuthRoutes(this.database);

  Router get routes {
    final router = Router();
    router.post('/login', _login);
    router.post('/reg', _register);
    router.get('/watch', AuthMiddleware(_watch).call);
    return router;
  }

  Future<Response> _login(Request request) async {
    final body = await request.readAsString();
    final data = jsonDecode(body);

    final login = data['login'];
    final password = data['password'];

    final user = await database.findUserByLogin(login);

    if (user == null || !BCrypt.checkpw(password, user.pwdHash)) {
      await database.createLog(login, 'Failed login attempt');
      return Response(401, body: jsonEncode({'error': 'Invalid credentials'}), headers: {'Content-Type': 'application/json'});
    }

    // Генерация JWT токена
    final dotenv = DotEnv();
    final secret = dotenv['JWT_SECRET'] ?? '';
    final jwt = JWT(
      {'user_id': user.id, 'login': user.login},
      issuer: 'family_safety_tracker'
    );
    final token = jwt.sign(SecretKey(secret));

    await database.createLog(login, 'Successful login');
    return Response(200, body: jsonEncode({'token': token}), headers: {'Content-Type': 'application/json'});
  }

  Future<Response> _register(Request request) async {
    final body = await request.readAsString();
    final data = jsonDecode(body);

    final login = data['login'];
    final password = data['password'];

    await database.createUser(login, password);
    await database.createLog(login, 'User registration');
    return Response(201, body: jsonEncode({'message': 'User registered'}), headers: {'Content-Type': 'application/json'});
  }

  Future<Response> _watch(Request request, String login) async {
    final uniqueId = request.url.queryParameters['unique_id'];

    if (!database.isValidShareId(uniqueId!)) {
      await database.createLog(login, 'Accessed invalid share link');
      return Response(404, body: jsonEncode({'error': 'Share link not found'}), headers: {'Content-Type': 'application/json'});
    }

    final position = await database.getLatestPosition();

    if (position == null) {
      await database.createLog(login, 'Accessed share link - no position');
      return Response(404, body: jsonEncode({'error': 'No position available'}), headers: {'Content-Type': 'application/json'});
    }

    await database.createLog(login, 'Accessed share link');
    return Response(200, body: jsonEncode({
      'x': position.xValue,
      'y': position.yValue,
      'last_update': position.lastUpdate,
      'expires_at': position.expiresAt,
    }), headers: {'Content-Type': 'application/json'});
  }
}