/*
 *   This file is a part of the SteamWar software.
 *
 *   Copyright (C) 2025 SteamWar.de-Serverteam
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package de.steamwar.sql;

import de.steamwar.sql.internal.Field;
import de.steamwar.sql.internal.SelectStatement;
import de.steamwar.sql.internal.Statement;
import de.steamwar.sql.internal.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.sql.Timestamp;
import java.time.Instant;
import java.util.List;

@AllArgsConstructor
public class Event {

    static {
        SchematicType.Normal.name(); // Ensure SchematicType is loaded.
    }

    private static final Table<Event> table = new Table<>(Event.class);

    private static final SelectStatement<Event> byCurrent = new SelectStatement<>(table, "SELECT * FROM Event WHERE Start < now() AND End > now()");
    private static final SelectStatement<Event> byId = table.select(Table.PRIMARY);
    private static final SelectStatement<Event> byName = table.select("eventName");
    private static final SelectStatement<Event> byComing = new SelectStatement<>(table, "SELECT * FROM Event WHERE Start > now()");
    private static final SelectStatement<Event> all = new SelectStatement<>(table, "SELECT * FROM Event");

    private static final Statement create = table.insertFields(true, "eventName", "deadline", "start", "end", "maximumTeamMembers", "publicSchemsOnly");
    private static final Statement update = table.update(Table.PRIMARY, "eventName", "deadline", "start", "end", "schemType", "maximumTeamMembers", "publicSchemsOnly");
    private static final Statement delete = table.delete(Table.PRIMARY);

    private static Event current = null;

    public static Event get(){
        if(current != null && current.now())
            return current;

        current = byCurrent.select();
        return current;
    }

    public static List<Event> getAll(){
        return all.listSelect();
    }

    public static Event create(String eventName, Timestamp start, Timestamp end){
        return get(create.insertGetKey(eventName, start, start, end, 5, false));
    }

    public static Event get(int eventID){
        return byId.select(eventID);
    }

    public static Event get(String eventName) {
        return byName.select(eventName);
    }

    public static List<Event> getComing() {
        return byComing.listSelect();
    }

    @Getter
    @Field(keys = {Table.PRIMARY}, autoincrement = true)
    private final int eventID;
    @Getter
    @Field(keys = {"eventName"})
    private final String eventName;
    @Getter
    @Field
    private final Timestamp deadline;
    @Getter
    @Field
    private final Timestamp start;
    @Getter
    @Field
    private final Timestamp end;
    @Getter
    @Field
    private final int maximumTeamMembers;
    @Field(nullable = true)
    private final SchematicType schemType;
    @Field
    private final boolean publicSchemsOnly;

    public boolean publicSchemsOnly() {
        return publicSchemsOnly;
    }

    public SchematicType getSchematicType() {
        return schemType;
    }

    private boolean now() {
        Instant now = Instant.now();
        return now.isAfter(start.toInstant()) && now.isBefore(end.toInstant());
    }

    public void update(String eventName, Timestamp deadline, Timestamp start, Timestamp end, SchematicType schemType, int maximumTeamMembers, boolean publicSchemsOnly) {
        update.update(eventName, deadline, start, end, schemType, maximumTeamMembers, publicSchemsOnly, eventID);
    }

    public void delete() {
        delete.update(eventID);
    }
}
