package postInit.machines

import gregtech.api.GTValues
import gregtech.api.capability.IRotorHolder
import gregtech.api.capability.impl.FluidTankList
import gregtech.api.capability.impl.MultiblockFuelRecipeLogic
import gregtech.api.metatileentity.ITieredMetaTileEntity
import gregtech.api.metatileentity.MetaTileEntity
import gregtech.api.metatileentity.interfaces.IGregTechTileEntity
import gregtech.api.pattern.BlockPattern
import gregtech.api.pattern.FactoryBlockPattern
import gregtech.api.pattern.PatternMatchContext
import gregtech.api.recipes.RecipeMap
import gregtech.client.renderer.ICubeRenderer

import net.minecraft.block.state.IBlockState
import net.minecraft.client.resources.I18n
import net.minecraft.item.ItemStack
import net.minecraft.util.text.TextFormatting
import net.minecraft.world.World
import net.minecraftforge.fluids.capability.IFluidHandler
import net.minecraftforge.fml.relauncher.Side
import net.minecraftforge.fml.relauncher.SideOnly

import java.util.List
import java.util.function.UnaryOperator

public class MetaTileEntityNuclearTurbine extends FuelMultiblockController implements ITieredMetaTileEntity {

    final int tier
    final IBlockState casingState
    final IBlockState gearboxState
    final ICubeRenderer casingRenderer
    final boolean hasMufflerHatch
    final ICubeRenderer frontOverlay

    static final int MIN_DURABILITY_TO_WARN = 10
    IFluidHandler exportFluidHandler

    MetaTileEntityNuclearTurbine(ResourceLocation metaTileEntityId, RecipeMap recipeMap, int tier,
                                 IBlockState casingState, IBlockState gearboxState, ICubeRenderer casingRenderer,
                                 boolean hasMufflerHatch, ICubeRenderer frontOverlay) {
        super(metaTileEntityId, recipeMap, tier)
        this.tier = tier
        this.casingState = casingState
        this.gearboxState = gearboxState
        this.casingRenderer = casingRenderer
        this.hasMufflerHatch = hasMufflerHatch
        this.frontOverlay = frontOverlay
        
        this.recipeMapWorkable = new MultiblockFuelRecipeLogic(this)
    }

    @Override
    MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) {
        return new MetaTileEntityNuclearTurbine(
                "nuclear_turbine",
                NUCLEAR_TURBINE_RECIPES,
                blockstate('gregtech:turbine_casing', 'variant=titanium_turbine_casing'),
                blockstate('gregtech:turbine_casing', 'variant=titanium_gearbox'),
                Textures.STABLE_TITANIUM_CASING,
                true,
                Textures.LARGE_STEAM_TURBINE_OVERLAY
        )
    }

    IRotorHolder getRotorHolder() {
        def abilities = getAbilities(MultiblockAbility.ROTOR_HOLDER)
        return abilities.isEmpty() ? null : abilities.get(0)
    }

    @Override
    void invalidateStructure() {
        super.invalidateStructure()
        this.exportFluidHandler = null
    }

    boolean isRotorFaceFree() {
        def rotorHolder = getRotorHolder()
        return rotorHolder != null && isStructureFormed() && rotorHolder.isFrontFaceFree()
    }

    @Override
    protected void formStructure(PatternMatchContext context) {
        super.formStructure(context)
        this.exportFluidHandler = new FluidTankList(true, getAbilities(MultiblockAbility.EXPORT_FLUIDS))
    }

    @Override
    protected long getMaxVoltage() {
        long maxProduction = recipeMapWorkable.getMaxVoltage()
        return (isActive() && maxProduction > 0) ? maxProduction : 0L
    }

    @Override
    void addInformation(ItemStack stack, World player, List<String> tooltip, boolean advanced) {
        super.addInformation(stack, player, tooltip, advanced)
        tooltip.add(I18n.format("gregtech.universal.tooltip.base_production_eut", GTValues.V[tier] * 2))
        tooltip.add(I18n.format("gregtech.multiblock.turbine.efficiency_tooltip", GTValues.VNF[tier]))
    }

    @Override
    protected BlockPattern createStructurePattern() {
        FactoryBlockPattern.start()
                .aisle("CCCC", "CHHC", "CCCC")
                .aisle("CHHC", "RGGR", "CHHC")
                .aisle("CCCC", "CSHC", "CCCC")
                .where('S' as char, selfPredicate())
                .where('G' as char, states(blockstate('gregtech:turbine_casing', 'variant=titanium_gearbox')))
                .where('C' as char, states(blockstate('gregtech:turbine_casing', 'variant=titanium_turbine_casing')))
                .where('R' as char, metaTileEntities(MultiblockAbility.ROTOR_HOLDER))
                .where('H' as char, states(getCasingState()).or(autoAbilities(false,true,false,false,true,true,true)))
                .build()
    }

    IBlockState getCasingState() { casingState }
    IBlockState getGearBoxState() { gearboxState }

    boolean hasMufflerMechanics() { hasMufflerHatch }
    boolean isStructureObstructed() { super.isStructureObstructed() || !isRotorFaceFree() }
    int getTier() { tier }
}