/* © SRSoftware 2025 */
package de.srsoftware.umbrella.core.model;

import static  de.srsoftware.umbrella.core.constants.Module.COMPANY;
import static de.srsoftware.umbrella.core.ModuleRegistry.companyService;
import static de.srsoftware.umbrella.core.ModuleRegistry.userService;
import static de.srsoftware.umbrella.core.constants.Field.*;
import static de.srsoftware.umbrella.core.constants.Module.USER;
import static de.srsoftware.umbrella.core.constants.Text.INVALID_DB_CODE;
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*;

import de.srsoftware.umbrella.core.api.Owner;
import de.srsoftware.umbrella.core.constants.Field;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

public class OwnerRef implements Owner {

	private final String type;
	private final long id;

	public OwnerRef(String dbCode){
		var parts = dbCode.split(":");
		if (parts.length != 2) throw unprocessable(INVALID_DB_CODE, Field.CODE,dbCode);
		type = parts[0];
		try {
			id = Long.parseLong(parts[1]);
		} catch (NumberFormatException e) {
			throw unprocessable(INVALID_DB_CODE, Field.CODE,dbCode);
		}
	}

	public OwnerRef(String type, long id){
		this.type = type;
		this.id   = id;
	}

	public static Owner of(ResultSet rs) throws SQLException {
		return new OwnerRef(rs.getString(OWNER));
	}

	public String dbCode(){
		return type+SEPARATOR+id;
	}

	public long id(){
		return id;
	}

	public String type(){
		// TODO: is this needed?
		return type;
	}

	/**
	 * returns the actual owner object
	 * @return the actual owner object
	 */
	public Owner resolve(){
		return switch (type){
			case COMPANY -> companyService().get(id());
			case USER    -> userService().loadUser(id());
			case null, default -> throw unprocessable("Encountered invalid owner type: {type}", TYPE,type);
		};
	}

	@Override
	public Map<String, Object> toMap() {
		var map = new HashMap<String,Object>();
		map.put(TYPE,type);
		map.put(ID, id);
		return map;
	}
}
