module api_modules.classroom_compliance.model;

import ddbc : DataSetReader;
import handy_httpd.components.optional;
import std.json;
import std.datetime;
import std.string : split;

struct ClassroomComplianceClass {
    ulong id;
    ushort number;
    string schoolYear;
    bool archived;
    ulong userId;
    string scoreExpression;
    string scorePeriod;

    static ClassroomComplianceClass parse(DataSetReader r) {
        return ClassroomComplianceClass(
            r.getUlong(1),
            r.getUshort(2),
            r.getString(3),
            r.getBoolean(7),
            r.getUlong(4),
            r.getString(5),
            r.getString(6)
        );
    }
}

struct ClassroomComplianceStudent {
    ulong id;
    string name;
    ulong classId;
    ushort deskNumber;
    bool removed;

    static ClassroomComplianceStudent parse(DataSetReader r) {
        return ClassroomComplianceStudent(
            r.getUlong(1),
            r.getString(2),
            r.getUlong(3),
            r.getUshort(4),
            r.getBoolean(5)
        );
    }
}

struct ClassroomComplianceEntry {
    ulong id;
    ulong classId;
    ulong studentId;
    Date date;
    ulong createdAt;
    bool absent;
    string comment;
    string[] checklistItems;
    Optional!bool phoneCompliant;
    Optional!bool classroomReadiness;
    Optional!ubyte behaviorRating;

    static ClassroomComplianceEntry parse(DataSetReader r) {
        ClassroomComplianceEntry entry;
        entry.id = r.getUlong(1);
        entry.classId = r.getUlong(2);
        entry.studentId = r.getUlong(3);
        entry.date = r.getDate(4);
        entry.createdAt = r.getUlong(5);
        entry.absent = r.getBoolean(6);
        entry.comment = r.getString(7);
        entry.checklistItems = r.getString(8).split("|||");
        entry.phoneCompliant = r.isNull(9) ? Optional!bool.empty : Optional!bool.of(r.getBoolean(9));
        entry.classroomReadiness = r.isNull(10) ? Optional!bool.empty : Optional!bool.of(r.getBoolean(10));
        entry.behaviorRating = r.isNull(11) ? Optional!ubyte.empty : Optional!ubyte.of(r.getUbyte(11));
        return entry;
    }

    JSONValue toJsonObj() const {
        JSONValue obj = JSONValue.emptyObject;
        obj.object["id"] = JSONValue(id);
        obj.object["classId"] = JSONValue(classId);
        obj.object["studentId"] = JSONValue(studentId);
        obj.object["date"] = JSONValue(date.toISOExtString());
        obj.object["createdAt"] = JSONValue(createdAt);
        obj.object["absent"] = JSONValue(absent);
        obj.object["comment"] = JSONValue(comment);
        obj.object["checklistItems"] = JSONValue.emptyArray;
        foreach (item; checklistItems) {
            obj.object["checklistItems"].array ~= JSONValue(item);
        }
        obj.object["phoneCompliant"] = phoneCompliant.isNull ? JSONValue(null) : JSONValue(phoneCompliant.value);
        obj.object["classroomReadiness"] = classroomReadiness.isNull ? JSONValue(null) : JSONValue(classroomReadiness.value);
        obj.object["behaviorRating"] = behaviorRating.isNull ? JSONValue(null) : JSONValue(behaviorRating.value);
        return obj;
    }
}

struct ClassroomComplianceClassNote {
    ulong id;
    ulong classId;
    ulong createdAt;
    string content;

    static ClassroomComplianceClassNote parse(DataSetReader r) {
        return ClassroomComplianceClassNote(
            r.getUlong(1),
            r.getUlong(2),
            r.getUlong(3),
            r.getString(4)
        );
    }
}
