import sys
import ui
import app
import math
import time

def FindModuleByAttributes(attributes, fallback_name=None):
    for mod_name, mod in sys.modules.items():
        if mod is None:
            continue
        if all(hasattr(mod, attr) for attr in attributes):
            return mod
    if fallback_name:
        try: return __import__(fallback_name)
        except: pass
    return None

GLHelper = FindModuleByAttributes(['GetTime', 'AppendChat'], 'GLHelper')
player_mod = FindModuleByAttributes(['GetItemIndex', 'INVENTORY_PAGE_SIZE'])
net_mod = FindModuleByAttributes(['SendItemMovePacket'])
GLPythonPlayer = FindModuleByAttributes(['GetItemNameByVNUM'])

def Log(msg):
    try: GLHelper.AppendChat(7, "|cff00FFFF[Auto-Split] - |cffffffff" + str(msg))
    except: pass

class OtoItemSplitter(ui.BoardWithTitleBar):
    def __init__(self):
        ui.BoardWithTitleBar.__init__(self)
        self.AddFlag("movable")
        self.AddFlag("float")
        self.SetPosition(200, 200)
        self.SetSize(340, 390)
        self.SetTitleName("Item Splitter - Powered by GLBot++")
        self.SetCloseEvent(self.Close)

        self.IsRunning = False
        self.SplitTick = 0
        self.InventoryItems = []
        self.LoopModeStatus = False

        self.ItemTitle = ui.TextLine()
        self.ItemTitle.SetParent(self)
        self.ItemTitle.SetPosition(20, 35)
        self.ItemTitle.SetText("Item VNUM")
        self.ItemTitle.SetPackedFontColor(0xfffcc419)
        self.ItemTitle.Show()

        self.ItemSlot = ui.SlotBar()
        self.ItemSlot.SetParent(self)
        self.ItemSlot.SetPosition(20, 55)
        self.ItemSlot.SetSize(130, 18)
        self.ItemSlot.Show()

        self.ItemEdit = ui.EditLine()
        self.ItemEdit.SetParent(self.ItemSlot)
        self.ItemEdit.SetPosition(4, 2)
        self.ItemEdit.SetSize(122, 18)
        self.ItemEdit.SetMax(6)
        self.ItemEdit.SetNumberMode()
        self.ItemEdit.SetText("50637")
        self.ItemEdit.Show()

        self.AmountTitle = ui.TextLine()
        self.AmountTitle.SetParent(self)
        self.AmountTitle.SetPosition(190, 35)
        self.AmountTitle.SetText("Split Amount")
        self.AmountTitle.SetPackedFontColor(0xfffcc419)
        self.AmountTitle.Show()

        self.AmountSlot = ui.SlotBar()
        self.AmountSlot.SetParent(self)
        self.AmountSlot.SetPosition(190, 55)
        self.AmountSlot.SetSize(130, 18)
        self.AmountSlot.Show()

        self.AmountEdit = ui.EditLine()
        self.AmountEdit.SetParent(self.AmountSlot)
        self.AmountEdit.SetPosition(4, 2)
        self.AmountEdit.SetSize(122, 18)
        self.AmountEdit.SetMax(4)
        self.AmountEdit.SetNumberMode()
        self.AmountEdit.SetText("1")
        self.AmountEdit.Show()

        self.ListTitle = ui.TextLine()
        self.ListTitle.SetParent(self)
        self.ListTitle.SetPosition(20, 85)
        self.ListTitle.SetText("Inventory Items (Click to select)")
        self.ListTitle.SetPackedFontColor(0xfffcc419)
        self.ListTitle.Show()

        self.BtnYenile = ui.Button()
        self.BtnYenile.SetParent(self)
        self.BtnYenile.SetPosition(245, 83)
        self.BtnYenile.SetUpVisual("d:/ymir work/ui/public/middle_Button_01.sub")
        self.BtnYenile.SetOverVisual("d:/ymir work/ui/public/middle_Button_02.sub")
        self.BtnYenile.SetDownVisual("d:/ymir work/ui/public/middle_Button_03.sub")
        self.BtnYenile.SetText("Refresh")
        self.BtnYenile.SetEvent(self.RefreshInventoryList)
        self.BtnYenile.Show()

        self.ListBar = ui.Bar()
        self.ListBar.SetParent(self)
        self.ListBar.SetPosition(20, 105)
        self.ListBar.SetSize(300, 120)
        self.ListBar.SetColor(0xaa000000)
        self.ListBar.Show()

        self.ListBox = ui.ListBoxEx()
        self.ListBox.SetParent(self.ListBar)
        self.ListBox.SetPosition(5, 5)
        self.ListBox.SetSize(290, 110)
        self.ListBox.SetViewItemCount(5)
        self.ListBox.SetSelectEvent(self.OnSelectInventoryItem)
        self.ListBox.Show()

        self.ListScroll = ui.ScrollBar()
        self.ListScroll.SetParent(self.ListBar)
        self.ListScroll.SetPosition(285, 5)
        self.ListScroll.SetScrollBarSize(110)
        self.ListScroll.Show()
        self.ListBox.SetScrollBar(self.ListScroll)

        self.ModeTitle = ui.TextLine()
        self.ModeTitle.SetParent(self)
        self.ModeTitle.SetPosition(20, 235)
        self.ModeTitle.SetText("Continuous Split (Loop Mode)")
        self.ModeTitle.SetPackedFontColor(0xfffcc419)
        self.ModeTitle.Show()

        self.LoopModeButton = ui.ToggleButton()
        self.LoopModeButton.SetParent(self)
        self.LoopModeButton.SetPosition(20, 255)
        self.LoopModeButton.SetUpVisual("d:/ymir work/ui/public/middle_button_01.sub")
        self.LoopModeButton.SetOverVisual("d:/ymir work/ui/public/middle_button_02.sub")
        self.LoopModeButton.SetDownVisual("d:/ymir work/ui/public/middle_button_03.sub")
        self.LoopModeButton.SetText("Loop: OFF")
        self.LoopModeButton.SetToggleUpEvent(self.ToggleLoopModeUp)
        self.LoopModeButton.SetToggleDownEvent(self.ToggleLoopModeDown)
        self.LoopModeButton.Show()

        self.BtnTekSefer = ui.Button()
        self.BtnTekSefer.SetParent(self)
        self.BtnTekSefer.SetPosition(190, 255)
        self.BtnTekSefer.SetUpVisual("d:/ymir work/ui/public/Big_Button_01.sub")
        self.BtnTekSefer.SetOverVisual("d:/ymir work/ui/public/Big_Button_02.sub")
        self.BtnTekSefer.SetDownVisual("d:/ymir work/ui/public/Big_Button_03.sub")
        self.BtnTekSefer.SetText("Split Once")
        self.BtnTekSefer.SetEvent(self.ExecuteSingleSplit)
        self.BtnTekSefer.Show()

        self.StatusText = ui.TextLine()
        self.StatusText.SetParent(self)
        self.StatusText.SetPosition(20, 295)
        self.StatusText.SetText("Status: Waiting...")
        self.StatusText.Show()

        self.BtnAction = ui.Button()
        self.BtnAction.SetParent(self)
        self.BtnAction.SetPosition(20, 320)
        self.BtnAction.SetUpVisual("d:/ymir work/ui/public/large_Button_01.sub")
        self.BtnAction.SetOverVisual("d:/ymir work/ui/public/large_Button_02.sub")
        self.BtnAction.SetDownVisual("d:/ymir work/ui/public/large_Button_03.sub")
        self.BtnAction.SetText("Start Process")
        self.BtnAction.SetEvent(self.ToggleLoopAction)
        self.BtnAction.Show()

        self.RefreshInventoryList()
        self.Show()

    def Close(self):
        self.IsRunning = False
        self.Hide()

    def ToggleLoopModeUp(self):
        self.LoopModeStatus = False
        self.LoopModeButton.SetText("Loop: OFF")

    def ToggleLoopModeDown(self):
        self.LoopModeStatus = True
        self.LoopModeButton.SetText("Loop: ON")

    def ToggleLoopAction(self):
        if self.IsRunning:
            self.IsRunning = False
            self.BtnAction.SetText("Start Process")
            self.StatusText.SetText("Status: Stopped")
            Log("Auto-split process stopped.")
        else:
            self.IsRunning = True
            self.BtnAction.SetText("Stop Process")
            self.StatusText.SetText("Status: Processing...")
            self.SplitTick = GLHelper.GetTime() if GLHelper else 0
            Log("Auto-split process started.")

    def ExecuteSingleSplit(self):
        if self.IsRunning:
            return
        self.StatusText.SetText("Status: Single split executed")
        self.ProcessSplit()
        self.RefreshInventoryList()

    def RefreshInventoryList(self):
        self.ListBox.RemoveAllItems()
        self.InventoryItems = []
        if not player_mod:
            return

        page_size = getattr(player_mod, 'INVENTORY_PAGE_SIZE', 45)
        total_slots = page_size * 4
        added_vnums = []

        for slot in range(total_slots):
            vnum = player_mod.GetItemIndex(slot)
            if vnum > 0 and vnum not in added_vnums:
                try: count = player_mod.GetItemCount(slot)
                except: count = 1

                if count > 1:
                    try: name = GLPythonPlayer.GetItemNameByVNUM(vnum) if GLPythonPlayer else "Item-" + str(vnum)
                    except: name = "Item-" + str(vnum)

                    added_vnums.append(vnum)
                    self.InventoryItems.append(vnum)

                    txt = ui.TextLine()
                    txt.SetText("%d | %s (x%d)" % (vnum, name, count))
                    self.ListBox.AppendItem(txt)

    def OnSelectInventoryItem(self, index):
        if index >= 0 and index < len(self.InventoryItems):
            selected_vnum = self.InventoryItems[index]
            self.ItemEdit.SetText(str(selected_vnum))

    def ProcessSplit(self):
        if not player_mod or not net_mod:
            Log("ERROR: Required game modules not found!")
            return False

        try:
            target_vnum = int(self.ItemEdit.GetText())
            amount = int(self.AmountEdit.GetText())
        except:
            Log("ERROR: Invalid VNUM or Amount!")
            return False

        page_size = getattr(player_mod, 'INVENTORY_PAGE_SIZE', 45)
        total_slots = page_size * 4

        source_slots = [x for x in range(total_slots) if player_mod.GetItemIndex(x) == target_vnum and player_mod.GetItemCount(x) > amount]
        empty_slots = [x for x in range(total_slots) if player_mod.GetItemIndex(x) == 0]

        if len(source_slots) > 0 and len(empty_slots) > 0:
            source_slot = source_slots[0]
            target_slot = empty_slots[0]
            net_mod.SendItemMovePacket(source_slot, target_slot, amount)
            return True
        else:
            if len(source_slots) == 0:
                self.StatusText.SetText("Status: No eligible items left")
            elif len(empty_slots) == 0:
                self.StatusText.SetText("Status: Inventory full!")
            return False

    def OnUpdate(self):
        if not self.IsRunning:
            return
        if not GLHelper:
            return

        current_time = GLHelper.GetTime()
        if current_time - self.SplitTick < 300:
            return
        self.SplitTick = current_time

        success = self.ProcessSplit()

        if not success or not self.LoopModeStatus:
            if not self.LoopModeStatus or (not success and self.StatusText.GetText() == "Status: Inventory full!"):
                self.IsRunning = False
                self.BtnAction.SetText("Start Process")
            self.RefreshInventoryList()

try: itemSplitter.Close()
except: pass
itemSplitter = OtoItemSplitter()
