/*
 * Copyright © 2004-2021 L2J Server
 * 
 * This file is part of L2J Server.
 * 
 * L2J Server is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * L2J Server 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
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package com.l2jserver.gameserver.model.entity.clanhall;

import java.util.logging.Level;
import java.util.logging.Logger;

import com.l2jserver.commons.database.ConnectionFactory;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.data.sql.impl.ClanTable;
import com.l2jserver.gameserver.instancemanager.AuctionManager;
import com.l2jserver.gameserver.instancemanager.ClanHallManager;
import com.l2jserver.gameserver.model.L2Clan;
import com.l2jserver.gameserver.model.StatsSet;
import com.l2jserver.gameserver.model.entity.ClanHall;
import com.l2jserver.gameserver.model.itemcontainer.Inventory;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;

public final class AuctionableHall extends ClanHall {
	
	private long _paidUntil;
	
	private final int _grade;
	
	private boolean _paid;
	
	private final int _lease;
	
	private final int _chRate = 604800000;
	
	public AuctionableHall(StatsSet set) {
		super(set);
		_paidUntil = set.getLong("paidUntil");
		_grade = set.getInt("grade");
		_paid = set.getBoolean("paid");
		_lease = set.getInt("lease");
		
		if (getOwnerId() != 0) {
			_isFree = false;
			initializeTask(false);
			loadFunctions();
		}
	}
	
	/**
	 * @return if clanHall is paid or not
	 */
	public boolean getPaid() {
		return _paid;
	}
	
	/** Return lease */
	@Override
	public int getLease() {
		return _lease;
	}
	
	/** Return PaidUntil */
	@Override
	public long getPaidUntil() {
		return _paidUntil;
	}
	
	/** Return Grade */
	@Override
	public int getGrade() {
		return _grade;
	}
	
	@Override
	public void free() {
		super.free();
		_paidUntil = 0;
		_paid = false;
	}
	
	@Override
	public void setOwner(L2Clan clan) {
		super.setOwner(clan);
		_paidUntil = System.currentTimeMillis();
		initializeTask(true);
	}
	
	/**
	 * Initialize Fee Task
	 * @param forced
	 */
	private void initializeTask(boolean forced) {
		long currentTime = System.currentTimeMillis();
		if (_paidUntil > currentTime) {
			ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), _paidUntil - currentTime);
		} else if (!_paid && !forced) {
			if ((System.currentTimeMillis() + (3600000 * 24)) <= (_paidUntil + _chRate)) {
				ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), System.currentTimeMillis() + (3600000 * 24));
			} else {
				ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), (_paidUntil + _chRate) - System.currentTimeMillis());
			}
		} else {
			ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), 0);
		}
	}
	
	/** Fee Task */
	protected class FeeTask implements Runnable {
		private final Logger _log = Logger.getLogger(FeeTask.class.getName());
		
		@Override
		public void run() {
			try {
				long _time = System.currentTimeMillis();
				
				if (isFree()) {
					return;
				}
				
				if (_paidUntil > _time) {
					ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), _paidUntil - _time);
					return;
				}
				
				L2Clan Clan = ClanTable.getInstance().getClan(getOwnerId());
				if (ClanTable.getInstance().getClan(getOwnerId()).getWarehouse().getAdena() >= getLease()) {
					if (_paidUntil != 0) {
						while (_paidUntil <= _time) {
							_paidUntil += _chRate;
						}
					} else {
						_paidUntil = _time + _chRate;
					}
					ClanTable.getInstance().getClan(getOwnerId()).getWarehouse().destroyItemByItemId("CH_rental_fee", Inventory.ADENA_ID, getLease(), null, null);
					ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), _paidUntil - _time);
					_paid = true;
					updateDb();
				} else {
					_paid = false;
					if (_time > (_paidUntil + _chRate)) {
						if (ClanHallManager.getInstance().loaded()) {
							AuctionManager.getInstance().initNPC(getId());
							ClanHallManager.getInstance().setFree(getId());
							Clan.broadcastToOnlineMembers(SystemMessage.getSystemMessage(SystemMessageId.THE_CLAN_HALL_FEE_IS_ONE_WEEK_OVERDUE_THEREFORE_THE_CLAN_HALL_OWNERSHIP_HAS_BEEN_REVOKED));
						} else {
							ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), 3000);
						}
					} else {
						updateDb();
						SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.PAYMENT_FOR_YOUR_CLAN_HALL_HAS_NOT_BEEN_MADE_PLEASE_MAKE_PAYMENT_TO_YOUR_CLAN_WAREHOUSE_BY_S1_TOMORROW);
						sm.addInt(getLease());
						Clan.broadcastToOnlineMembers(sm);
						if ((_time + (3600000 * 24)) <= (_paidUntil + _chRate)) {
							ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), _time + (3600000 * 24));
						} else {
							ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), (_paidUntil + _chRate) - _time);
						}
						
					}
				}
			} catch (Exception e) {
				_log.log(Level.SEVERE, "", e);
			}
		}
	}
	
	@Override
	public void updateDb() {
		try (var con = ConnectionFactory.getInstance().getConnection();
			var ps = con.prepareStatement("UPDATE clanhall SET ownerId=?, paidUntil=?, paid=? WHERE id=?")) {
			ps.setInt(1, getOwnerId());
			ps.setLong(2, getPaidUntil());
			ps.setInt(3, (getPaid()) ? 1 : 0);
			ps.setInt(4, getId());
			ps.execute();
		} catch (Exception e) {
			_log.log(Level.WARNING, "Exception: updateOwnerInDB(L2Clan clan): " + e.getMessage(), e);
		}
	}
}
