/*
 *
 * ChatMsg
 *
 * Helpful utility for pretty printing in chat in the game with different supported functions and levels
 *
*/

package jesse.keeblarcraft.ChatStuff;

import java.util.ArrayList;
import java.util.List;

import jesse.keeblarcraft.ChatStuff.ChatFormatting.COLOR_CODE;
import net.minecraft.text.ClickEvent;
import net.minecraft.text.HoverEvent;
import net.minecraft.text.MutableText;
import net.minecraft.text.Style;
import net.minecraft.text.Text;

public class ChatMsg {
    // May be null; store last message of each type so class can be referenced as object
    MutableText mutableText;
    Text regularText;
    /////////////////////////////////////////////////////////////////////////////
    /// @fn         MakeCopyableTxt
    ///
    /// @param[in]  terminalTxt is the text to be seen on screen
    ///
    /// @param[in]  hoverTxt is the desired text to be seen in a new hover event
    ///
    /// @param[in]  copyInt is an integer argument that can be copied when the
    ///             player clicks on the chat message
    ///
    /// @brief      Creates a copyable text block for the player
    ///
    /// @return     MutableText of text intended to be used to send to player
    /////////////////////////////////////////////////////////////////////////////
    public MutableText MakeCopyableTxt(String terminalTxt, String hoverTxt, Integer copyInt) {
        return MakeCopyableTxt(terminalTxt, hoverTxt, Integer.toString(copyInt));
    }

    /////////////////////////////////////////////////////////////////////////////
    /// @fn         MakeCopyableTxt
    ///
    /// @param[in]  terminalTxt is the text to be seen on screen
    ///
    /// @param[in]  hoverTxt is the desired text to be seen in a new hover event
    ///
    /// @param[in]  expandedList takes in a list of strings that can be copied
    ///             when the player clicks on a chat message
    ///
    /// @brief      Creates a copyable text block for the player
    ///
    /// @return     MutableText of text intended to be used to send to player
    /////////////////////////////////////////////////////////////////////////////
    public MutableText MakeCopyableTxt(String terminalTxt, String hoverTxt, List<String> expandedList) {
        String expanded = "[";
        int index = 0;
        for (String str : expandedList) {
            expanded += str;

            // Add delimiter if next index is not at size
            if (++index < expandedList.size()) {
                expanded += ",";
            }
        }

        expanded += "]";

        return MakeCopyableTxt(terminalTxt, hoverTxt, expanded);
    }

    /////////////////////////////////////////////////////////////////////////////
    /// @fn         MakeCopyableTxt
    ///
    /// @param[in]  terminalTxt is the text to be seen on screen
    ///
    /// @param[in]  hoverTxt is the desired text to be seen in a new hover event
    ///
    /// @param[in]  copyStr is a regular string that can be copied when the player
    ///             clicks on a chat message
    ///
    /// @brief      Creates a copyable text block for the player
    ///
    /// @return     MutableText of text intended to be used to send to player
    /////////////////////////////////////////////////////////////////////////////
    public MutableText MakeCopyableTxt(String terminalTxt, String hoverTxt, String copyStr) {
        Text copyableText = Text.of(terminalTxt);
        MutableText testTxt = (MutableText) copyableText;
        System.out.println("Making hoverable stuff");
        testTxt.setStyle(Style.EMPTY.withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, copyStr))
        .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.of(hoverTxt))));
        System.out.println("Done making hoverable stuff");

        System.out.println("Value of copyAbleText: " + copyableText.getString());
        System.out.println("Value of testTxt: " + testTxt.getString());

        mutableText = testTxt;

        return testTxt;
    }

    /////////////////////////////////////////////////////////////////////////////
    /// @fn         ColorMsg
    ///
    /// @param[in]  msg is an integer message that is desired to be colored
    ///
    /// @param[in]  color is the color option
    ///
    /// @brief      Creates a formatted string that will be colored at the
    ///             specification of the developer
    ///
    /// @return     Formatted string of colored text
    /////////////////////////////////////////////////////////////////////////////
    public String ColorMsg(Integer msg, COLOR_CODE color) {
        return ChatFormatting.GetColor(color) + msg + ChatFormatting.COLOR_END;
    }

    /////////////////////////////////////////////////////////////////////////////
    /// @fn         ColorMsg
    ///
    /// @param[in]  msg is an Text object
    ///
    /// @param[in]  color is the color option
    ///
    /// @brief      Creates a formatted string that will be colored at the
    ///             specification of the developer
    ///
    /// @return     Text object but with the minecraft color injected around
    ///             string
    ///
    /// @note       THIS WILL REMOVE FORMATTING ON THE TEXT. If you need to keep
    ///             formatting/other specialties, format a string with the color
    ///             first with functions inside this class.
    /////////////////////////////////////////////////////////////////////////////
    public Text ColorMsg(Text msg, COLOR_CODE color) {
        regularText = Text.of(ChatFormatting.GetColor(color) + msg.getString() + ChatFormatting.COLOR_END);
        return regularText;
    }

    /////////////////////////////////////////////////////////////////////////////
    /// @fn         ColorMsg
    ///
    /// @param[in]  msg is a list of strings that is desired to all be colored
    ///             the same
    ///
    /// @param[in]  color is the color option
    ///
    /// @brief      Creates a formatted list of strings that will be colored
    ///             at the specification of the developer and will be returned as
    ///             a list
    ///
    /// @return     Formatted list of strings
    /////////////////////////////////////////////////////////////////////////////
    public List<String> ColorMsg(List<String> msg, COLOR_CODE color) {
        List<String> retList = new ArrayList<String>();

        for (String str : msg) {
            retList.add(ChatFormatting.GetColor(color) + str + ChatFormatting.COLOR_END);
        }

        return retList;
    }

    /////////////////////////////////////////////////////////////////////////////
    /// @fn         ColorMsg
    ///
    /// @param[in]  msg to be formatted
    ///
    /// @param[in]  color is the color option
    ///
    /// @brief      Creates a formatted string that will be colored at the
    ///             specification of the developer
    ///
    /// @return     Formatted string of colored text
    /////////////////////////////////////////////////////////////////////////////
    public String ColorMsg(String msg, COLOR_CODE color) {
        return ChatFormatting.GetColor(color) + msg + ChatFormatting.COLOR_END;
    }

    // Parses a help command and color codes it. assume everything up to first '.' is the
    // help cmd usage and color it with primaryColor. secondaryColor applied to rest
    /////////////////////////////////////////////////////////////////////////////
    /// @fn         FormatMsg
    ///
    /// @param[in]  helpCmd is outsourced as an intentional help message. The
    ///             string expects the initial format to stop with a '.'
    ///             delimiter.
    ///
    /// @param[in]  primaryColor is the color of the string up to the delimiter
    ///
    /// @param[in]  secondaryColor is the color after the delimiter
    ///
    /// @brief      Creates a formatted string
    ///
    /// @return     Formatted string of colored text
    /////////////////////////////////////////////////////////////////////////////
    public String FormatMsg(String helpCmd, COLOR_CODE primaryColor, COLOR_CODE secondaryColor) {
        String coloredStr = ChatFormatting.GetColor(primaryColor);
        List<String> splitStr = List.of(helpCmd.split("\\."));

        Boolean isFirst = true;
        for (String str : splitStr) {
            if (isFirst) {
                coloredStr += str;
                isFirst = false;
                coloredStr += ChatFormatting.GetColor(secondaryColor);
            } else {
                coloredStr += str;
            }
        }

        return coloredStr + ChatFormatting.COLOR_END;
    }
}