/*
 *   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.SqlTypeMapper;
import lombok.Getter;

import java.util.*;

public class SchematicType {

	public static final SchematicType Normal = new SchematicType("Normal", "", Type.NORMAL, null, "STONE_BUTTON", false);

	private static final Map<String, SchematicType> fromDB;
	private static final List<SchematicType> types;

	static {
		List<SchematicType> tmpTypes = new LinkedList<>();
		Map<String, SchematicType> tmpFromDB = new HashMap<>();

		tmpTypes.add(Normal);
		tmpFromDB.put(Normal.name().toLowerCase(), Normal);

		SQLWrapper.impl.loadSchemTypes(tmpTypes, tmpFromDB);

		fromDB = Collections.unmodifiableMap(tmpFromDB);
		types = Collections.unmodifiableList(tmpTypes);
	}

	static {
		new SqlTypeMapper<>(SchematicType.class, "VARCHAR(16)", (rs, identifier) -> {
			String t = rs.getString(identifier);
			return t != null ? fromDB.get(t) : null;
		}, (st, index, value) -> st.setString(index, value.toDB()));
	}

	private final String name;
	@Getter
	private final String kuerzel;
	private final Type type;
	private final SchematicType checkType;
	@Getter
	private final String material;
	@Getter
	private final Date deadline;
    @Getter
    private final boolean manualCheck;

	SchematicType(String name, String kuerzel, Type type, SchematicType checkType, String material, boolean manualCheck){
		this(name, kuerzel, type, checkType, material, null, manualCheck);
	}

	SchematicType(String name, String kuerzel, Type type, SchematicType checkType, String material, Date deadline, boolean manualCheck){
		this.name = name;
		this.kuerzel = kuerzel;
		this.type = type;
		this.checkType = checkType;
		this.material = material;
		this.deadline = deadline;
        this.manualCheck = manualCheck;
	}

	public boolean isAssignable(){
		return type == Type.NORMAL || (type == Type.FIGHT_TYPE && checkType != null) || !manualCheck;
	}

	public SchematicType checkType(){
        if (!manualCheck) {
            return this;
        }
		return checkType;
	}

	public boolean check(){
		return type == Type.CHECK_TYPE;
	}

	public boolean fightType(){
		return type == Type.FIGHT_TYPE;
	}

	public boolean writeable(){
		return type == Type.NORMAL;
	}

	public String name(){
		return name;
	}

	public String toDB(){
		return name.toLowerCase();
	}

	public static SchematicType fromDB(String input) {
		return fromDB.get(input.toLowerCase());
	}

	public static List<SchematicType> values(){
		return types;
	}

	enum Type{
		NORMAL,
		CHECK_TYPE,
		FIGHT_TYPE
	}
}
