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

// To parse this JSON data, do
//
//     final student = studentFromJson(jsonString);

Student studentFromJson(String str) => Student.fromJson(json.decode(str));

String studentToJson(Student data) => json.encode(data.toJson());

class Student {
  final String? studentid;
  final String? title;
  final String? firstname;
  final String? lastname;
  final String? schoolemail;
  final DateTime? dateofbirth;
  final String? currentyear;
  final String? currentsession;
  final String? homeaddress;
  final String? mobilenumber;
  final String? emailaddress;
  final List<Nextofkindetail>? nextofkindetails;
  final List<Guardiandetail>? guardiandetails;
  final List<Medicaldetail>? medicaldetails;
  final List<Coursedetail>? coursedetails;
  final String? gender;
  final Map<String, List<String>>? sessiondetails;
  final Map<String, List<ModuleDetail>>? moduledetails;

  Student({
    this.studentid,
    this.title,
    this.firstname,
    this.lastname,
    this.schoolemail,
    this.dateofbirth,
    this.currentyear,
    this.currentsession,
    this.homeaddress,
    this.mobilenumber,
    this.emailaddress,
    this.nextofkindetails,
    this.guardiandetails,
    this.medicaldetails,
    this.coursedetails,
    this.gender,
    this.sessiondetails,
    this.moduledetails,
  });

  factory Student.fromJson(Map<String, dynamic> json) => Student(
        studentid: json["studentid"],
        title: json["title"],
        firstname: json["firstname"],
        lastname: json["lastname"],
        schoolemail: json["schoolemail"],
        dateofbirth: json["dateofbirth"] == null
            ? null
            : DateTime.parse(json["dateofbirth"]),
        currentyear: json["currentyear"],
        currentsession: json["currentsession"],
        homeaddress: json["homeaddress"],
        mobilenumber: json["mobilenumber"],
        emailaddress: json["emailaddress"],
        nextofkindetails: json["nextofkindetails"] == null
            ? []
            : List<Nextofkindetail>.from(json["nextofkindetails"]!
                .map((x) => Nextofkindetail.fromJson(x))),
        guardiandetails: json["guardiandetails"] == null
            ? []
            : List<Guardiandetail>.from(json["guardiandetails"]!
                .map((x) => Guardiandetail.fromJson(x))),
        medicaldetails: json["medicaldetails"] == null
            ? []
            : List<Medicaldetail>.from(
                json["medicaldetails"]!.map((x) => Medicaldetail.fromJson(x))),
        coursedetails: json["coursedetails"] == null
            ? []
            : List<Coursedetail>.from(
                json["coursedetails"]!.map((x) => Coursedetail.fromJson(x))),
        gender: json["gender"],
        sessiondetails: Map.from(json["sessiondetails"]!).map((k, v) =>
            MapEntry<String, List<String>>(
                k, List<String>.from(v.map((x) => x)))),
        moduledetails: Map.from(json["moduledetails"]!).map((k, v) => MapEntry<
                String, List<ModuleDetail>>(k,
            List<ModuleDetail>.from(v.map((x) => ModuleDetail.fromJson(x))))),
      );

  Map<String, dynamic> toJson() => {
        "studentid": studentid,
        "title": title,
        "firstname": firstname,
        "lastname": lastname,
        "schoolemail": schoolemail,
        "dateofbirth":
            "${dateofbirth!.year.toString().padLeft(4, '0')}-${dateofbirth!.month.toString().padLeft(2, '0')}-${dateofbirth!.day.toString().padLeft(2, '0')}",
        "currentyear": currentyear,
        "currentsession": currentsession,
        "homeaddress": homeaddress,
        "mobilenumber": mobilenumber,
        "emailaddress": emailaddress,
        "nextofkindetails": nextofkindetails == null
            ? []
            : List<dynamic>.from(nextofkindetails!.map((x) => x.toJson())),
        "guardiandetails": guardiandetails == null
            ? []
            : List<dynamic>.from(guardiandetails!.map((x) => x.toJson())),
        "medicaldetails": medicaldetails == null
            ? []
            : List<dynamic>.from(medicaldetails!.map((x) => x.toJson())),
        "coursedetails": coursedetails == null
            ? []
            : List<dynamic>.from(coursedetails!.map((x) => x.toJson())),
        "gender": gender,
        "sessiondetails": Map.from(sessiondetails!).map((k, v) =>
            MapEntry<String, dynamic>(k, List<dynamic>.from(v.map((x) => x)))),
        "moduledetails": Map.from(moduledetails!).map((k, v) =>
            MapEntry<String, dynamic>(
                k, List<dynamic>.from(v.map((x) => x.toJson())))),
      };
}

class Coursedetail {
  final String? courseofstudy;
  final String? coursetype;
  final String? coursequalification;
  final String? coursemode;

  Coursedetail({
    this.courseofstudy,
    this.coursetype,
    this.coursequalification,
    this.coursemode,
  });

  factory Coursedetail.fromJson(Map<String, dynamic> json) => Coursedetail(
        courseofstudy: json["courseofstudy"],
        coursetype: json["coursetype"],
        coursequalification: json["coursequalification"],
        coursemode: json["coursemode"],
      );

  Map<String, dynamic> toJson() => {
        "courseofstudy": courseofstudy,
        "coursetype": coursetype,
        "coursequalification": coursequalification,
        "coursemode": coursemode,
      };
}

class Guardiandetail {
  final String? guardianname;
  final String? guardiancontact;
  final String? guardianaddress;
  final String? guardianrelationship;

  Guardiandetail({
    this.guardianname,
    this.guardiancontact,
    this.guardianaddress,
    this.guardianrelationship,
  });

  factory Guardiandetail.fromJson(Map<String, dynamic> json) => Guardiandetail(
        guardianname: json["guardianname"],
        guardiancontact: json["guardiancontact"],
        guardianaddress: json["guardianaddress"],
        guardianrelationship: json["guardianrelationship"],
      );

  Map<String, dynamic> toJson() => {
        "guardianname": guardianname,
        "guardiancontact": guardiancontact,
        "guardianaddress": guardianaddress,
        "guardianrelationship": guardianrelationship,
      };
}

class Medicaldetail {
  final String? weight;
  final String? height;
  final String? genotype;
  final String? bloodgroup;
  final String? medicalcondition;
  final String? allergies;
  final bool? dnr;
  final String? emergencycontactname;
  final String? emergencycontactnumber;
  final String? emergencycontractrelationship;

  Medicaldetail({
    this.weight,
    this.height,
    this.genotype,
    this.bloodgroup,
    this.medicalcondition,
    this.allergies,
    this.dnr,
    this.emergencycontactname,
    this.emergencycontactnumber,
    this.emergencycontractrelationship,
  });

  factory Medicaldetail.fromJson(Map<String, dynamic> json) => Medicaldetail(
        weight: json["weight"],
        height: json["height"],
        genotype: json["genotype"],
        bloodgroup: json["bloodgroup"],
        medicalcondition: json["medicalcondition"],
        allergies: json["allergies"],
        dnr: json["dnr"],
        emergencycontactname: json["emergencycontactname"],
        emergencycontactnumber: json["emergencycontactnumber"],
        emergencycontractrelationship: json["emergencycontractrelationship"],
      );

  Map<String, dynamic> toJson() => {
        "weight": weight,
        "height": height,
        "genotype": genotype,
        "bloodgroup": bloodgroup,
        "medicalcondition": medicalcondition,
        "allergies": allergies,
        "dnr": dnr,
        "emergencycontactname": emergencycontactname,
        "emergencycontactnumber": emergencycontactnumber,
        "emergencycontractrelationship": emergencycontractrelationship,
      };
}

class ModuleDetail {
  final String? modulecode;
  final String? modulename;

  ModuleDetail({
    this.modulecode,
    this.modulename,
  });

  factory ModuleDetail.fromJson(Map<String, dynamic> json) => ModuleDetail(
        modulecode: json["modulecode"],
        modulename: json["modulename"],
      );

  Map<String, dynamic> toJson() => {
        "modulecode": modulecode,
        "modulename": modulename,
      };
}

class Nextofkindetail {
  final String? nextofkinname;
  final String? nextofkincontact;
  final String? nextofkinaddress;
  final String? nextofkinrelationship;

  Nextofkindetail({
    this.nextofkinname,
    this.nextofkincontact,
    this.nextofkinaddress,
    this.nextofkinrelationship,
  });

  factory Nextofkindetail.fromJson(Map<String, dynamic> json) =>
      Nextofkindetail(
        nextofkinname: json["nextofkinname"],
        nextofkincontact: json["nextofkincontact"],
        nextofkinaddress: json["nextofkinaddress"],
        nextofkinrelationship: json["nextofkinrelationship"],
      );

  Map<String, dynamic> toJson() => {
        "nextofkinname": nextofkinname,
        "nextofkincontact": nextofkincontact,
        "nextofkinaddress": nextofkinaddress,
        "nextofkinrelationship": nextofkinrelationship,
      };
}

Future<Student> getStudentDetail(String studentId) async {
  try {
    final response = await client
        .get(
          Uri.parse("$baseUrl/student/$studentId"),
          headers: header,
        )
        .timeout(
          const Duration(seconds: timeout),
        );

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