import 'dart:convert';
import 'dart:io';

import 'package:school_management_system/components/default_values.dart';

// To parse this JSON data, do
//
//     final result = resultFromJson(jsonString);

Result resultFromJson(String str) => Result.fromJson(json.decode(str));

String resultToJson(Result data) => json.encode(data.toJson());

class Result {
  final String? studentid;
  final String? session;
  final String? comments;
  final bool? resit;
  final String? semester;
  final List<Score>? scores;

  Result({
    this.studentid,
    this.session,
    this.comments,
    this.resit,
    this.semester,
    this.scores,
  });

  factory Result.fromJson(Map<String, dynamic> json) => Result(
        studentid: json["studentid"],
        session: json["session"],
        comments: json["comments"],
        resit: json["resit"],
        semester: json["semester"],
        scores: json["scores"] == null
            ? []
            : List<Score>.from(json["scores"]!.map((x) => Score.fromJson(x))),
      );

  Map<String, dynamic> toJson() => {
        "studentid": studentid,
        "session": session,
        "comments": comments,
        "resit": resit,
        "semester": semester,
        "scores": scores == null
            ? []
            : List<dynamic>.from(scores!.map((x) => x.toJson())),
      };
}

class Score {
  final String? module;
  final double? score;

  Score({
    this.module,
    this.score,
  });

  factory Score.fromJson(Map<String, dynamic> json) => Score(
        module: json["module"],
        score: json["score"],
      );

  Map<String, dynamic> toJson() => {
        "module": module,
        "score": score,
      };
}

Map<String, List<String>> sessionFromJson(String str) =>
    Map.from(json.decode(str)).map((k, v) =>
        MapEntry<String, List<String>>(k, List<String>.from(v.map((x) => x))));

String sessionToJson(Map<String, List<String>> data) =>
    json.encode(Map.from(data).map((k, v) =>
        MapEntry<String, dynamic>(k, List<dynamic>.from(v.map((x) => x)))));

Future<Map<String, List<String>>> getStudentSemester(String session) async {
  try {
    final response = await client
        .get(
            Uri.parse("$baseUrl/results/getSemester/$loginId?session=$session"),
            headers: header)
        .timeout(
          const Duration(seconds: timeout),
        );

    if (response.statusCode == 200) {
      if (response.body.isNotEmpty) {
        return sessionFromJson(response.body);
      } else {
        return sessionFromJson("");
      }
    } else {
      return sessionFromJson("");
    }
  } on SocketException {
    return throw Exception();
  } on HttpException {
    return throw Exception();
  } on FormatException {
    return throw Exception();
  }
}

Future<Map<String, List<String>>> getStudentSession() async {
  try {
    final response = await client
        .get(
          Uri.parse("$baseUrl/results/getSession/$loginId"),
          headers: header,
        )
        .timeout(
          const Duration(seconds: timeout),
        );

    if (response.statusCode == 200) {
      if (response.body.isNotEmpty) {
        return sessionFromJson(response.body);
      } else {
        return sessionFromJson("");
      }
    } else {
      return sessionFromJson("");
    }
  } on SocketException {
    return throw Exception();
  } on HttpException {
    return throw Exception();
  } on FormatException {
    return throw Exception();
  }
}

Future<Result> getStudentResult(String session, String semester) async {
  try {
    final response = await client
        .get(
          Uri.parse(
              "$baseUrl/results/list/$loginId?session=$session&semester=$semester"),
          headers: header,
        )
        .timeout(
          const Duration(seconds: timeout),
        );

    if (response.statusCode == 200) {
      if (response.body.isNotEmpty) {
        return resultFromJson(response.body);
      } else {
        return resultFromJson("");
      }
    } else {
      return resultFromJson("");
    }
  } on SocketException {
    return throw Exception();
  } on HttpException {
    return throw Exception();
  } on FormatException {
    return throw Exception();
  }
}
