using System;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Custom.InnRooms;
using Server.Multis;
using System.Collections.Generic;
using Server.ContextMenus;

namespace Server.Custom.InnRooms
{
    public class InnDoor : Item
    {
        private Mobile m_Renter;
        private InnRoomHouse m_House;
        private DateTime m_RentExpires;
        private Point3D m_RoomLocation;
        private Map m_RoomMap;
        
        // --- NEW VARIABLES ---
        private bool m_AutoRenew;
        private int m_RentCost = 5000; 
        private TimeSpan m_RentDuration = TimeSpan.FromDays(7); 

        // --- PUBLIC PROPERTIES EXPOSED FOR THE GUMP ---
        [CommandProperty(AccessLevel.GameMaster)]
        public bool AutoRenew { get { return m_AutoRenew; } set { m_AutoRenew = value; } }

        public DateTime RentExpires { get { return m_RentExpires; } set { m_RentExpires = value; } }
        public int RentCost { get { return m_RentCost; } }
        public TimeSpan RentDuration { get { return m_RentDuration; } }
        public InnRoomHouse House { get { return m_House; } }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool ForceEviction { get { return false; } set { if (value == true) { EvictTenant(); } } }

        [CommandProperty(AccessLevel.GameMaster)]
        public Mobile Renter { get { return m_Renter; } set { m_Renter = value; InvalidateProperties(); } }

        [CommandProperty(AccessLevel.GameMaster)]
        public Point3D RoomLocation { get { return m_RoomLocation; } set { m_RoomLocation = value; } }

        [CommandProperty(AccessLevel.GameMaster)]
        public Map RoomMap { get { return m_RoomMap; } set { m_RoomMap = value; } }

        [Constructable]
        public InnDoor() : this(0x6E5) 
        {
        }

        [Constructable]
        public InnDoor(int itemID) : base(itemID) 
        {
            Movable = false;
            Name = "A Vacant Inn Room";
        }

        public InnDoor(Serial serial) : base(serial)
        {
        }

        public override void OnDoubleClick(Mobile from)
        {
            if (!from.InRange(GetWorldLocation(), 2))
            {
                from.LocalOverheadMessage(Server.Network.MessageType.Regular, 0x3B2, 1019045); 
                return;
            }

            // SCENARIO A: The room is VACANT
            if (m_Renter == null)
            {
                if (RoomLocation == Point3D.Zero || RoomMap == null)
                {
                    from.SendMessage(33, "This door is out of order (No Room Linked).");
                    return;
                }

                // Swapped to Banker.Withdraw to support AccountGold out of the gate
                if (Banker.Withdraw(from, m_RentCost))
                {
                    m_Renter = from;
                    m_RentExpires = DateTime.UtcNow + m_RentDuration;
                    m_AutoRenew = true; // Automatically turn it on for new renters!
                    Name = from.Name + "'s Inn Room";

                    m_House = new InnRoomHouse(from);
                    Point3D buriedLocation = new Point3D(RoomLocation.X, RoomLocation.Y, RoomLocation.Z - 20);
                    m_House.MoveToWorld(buriedLocation, RoomMap);

                    from.PlaySound(0x249);
                    from.SendMessage(68, $"You have rented this room for {m_RentDuration.Days} days.");
                    TeleportToRoom(from);
                }
                else
                {
                    from.SendMessage(33, $"You need {m_RentCost} gold in your bank to rent this room.");
                }
            }
            // SCENARIO B: The room is RENTED
            else
            {
                // Check if the rent has expired
                if (DateTime.UtcNow > m_RentExpires)
                {
                    // MAGIC AUTO-RENEW CHECK
                    if (m_AutoRenew && m_Renter != null && Banker.Withdraw(m_Renter, m_RentCost))
                    {
                        m_RentExpires += m_RentDuration;
                        InvalidateProperties();
                        
                        // Let them know it silently renewed behind the scenes
                        if (from == m_Renter)
                            from.SendMessage(68, $"Your auto-renew just processed {m_RentCost} gold from your bank!");
                    }
                    else
                    {
                        EvictTenant();
                        from.SendMessage(33, "The rent expired and the room has been cleared. It is now vacant.");
                        return;
                    }
                }

                if (m_House != null && (m_House.IsOwner(from) || m_House.IsFriend(from) || m_House.HasAccess(from)))
                {
                    TeleportToRoom(from);
                }
                else
                {
                    from.SendMessage(33, "The door is locked and you do not have permission to enter.");
                }
            }
        }

        private void TeleportToRoom(Mobile m)
        {
            m.PlaySound(0x1EA);
            m.MoveToWorld(RoomLocation, RoomMap);
            m.SendMessage(0x3B2, "You enter the inn room.");
        }

        public void EvictTenant()
        {
            if (m_Renter != null && m_House != null && !m_House.Deleted)
            {
                BankBox bank = m_Renter.BankBox;

                if (bank != null)
                {
                    InnEvictionCrate crate = new InnEvictionCrate();

                    for (int i = m_House.Secures.Count - 1; i >= 0; --i)
                    {
                        SecureInfo info = m_House.Secures[i] as SecureInfo;
                        if (info != null && info.Item != null)
                        {
                            Container secureContainer = info.Item;
                            secureContainer.IsSecure = false;
                            secureContainer.IsLockedDown = false;
                            secureContainer.Movable = true;
                            crate.DropItem(secureContainer);
                        }
                    }
                    m_House.Secures.Clear();

                    for (int i = m_House.LockDowns.Count - 1; i >= 0; --i)
                    {
                        Item item = m_House.LockDowns[i] as Item;
                        if (item != null)
                        {
                            item.IsLockedDown = false;
                            item.Movable = true;
                            crate.DropItem(item);
                        }
                    }
                    m_House.LockDowns.Clear();

                    if (crate.Items.Count > 0)
                    {
                        bank.DropItem(crate);
                        m_Renter.SendMessage(33, "Your inn room rent has expired. Your belongings have been packed into a crate and placed in your bank box.");
                    }
                    else
                    {
                        crate.Delete(); 
                    }
                }

                m_House.Delete();
            }

            m_Renter = null;
            m_House = null;
            m_AutoRenew = false;
            Name = "A Vacant Inn Room";
        }

        public override void GetProperties(ObjectPropertyList list)
        {
            base.GetProperties(list);

            if (m_Renter != null)
            {
                list.Add(1060658, "Rent Cost\tPaid"); 
                list.Add(1060659, "Expires\t{0}", m_RentExpires.ToString("g")); 
            }
            else
            {
                list.Add(1060658, "Rent Cost\t{0} Gold", m_RentCost); 
            }
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);
            // Bumped to version 1 to safely save the AutoRenew toggle!
            writer.Write((int)1); 

            writer.Write(m_AutoRenew);

            writer.Write(m_Renter);
            writer.WriteItem(m_House);
            writer.Write(m_RentExpires);
            writer.Write(m_RoomLocation);
            writer.Write(m_RoomMap);
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);
            int version = reader.ReadInt();

            if (version >= 1)
            {
                m_AutoRenew = reader.ReadBool();
            }

            m_Renter = reader.ReadMobile();
            m_House = reader.ReadItem() as InnRoomHouse;
            m_RentExpires = reader.ReadDateTime();
            m_RoomLocation = reader.ReadPoint3D();
            m_RoomMap = reader.ReadMap();
        }

        // --- NEW CONTEXT MENU FOR THE GUMP ---
        public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
        {
            base.GetContextMenuEntries(from, list);

            if (from.Alive && m_Renter == from)
            {
                // Cliloc 1063490 is "Manage"
                list.Add(new ManageRoomEntry(from, this));
            }
        }

        private class ManageRoomEntry : ContextMenuEntry
        {
            private Mobile m_From;
            private InnDoor m_Door;

            public ManageRoomEntry(Mobile from, InnDoor door) : base(1063490, 2) 
            {
                m_From = from;
                m_Door = door;
            }

            public override void OnClick()
            {
                if (m_Door.Deleted || m_Door.Renter != m_From)
                    return;

                m_From.SendGump(new InnRoomManagementGump((PlayerMobile)m_From, m_Door));
            }
        }

        // --- BONUS: DRAG AND DROP RENEWAL ---
        public override bool OnDragDrop(Mobile from, Item dropped)
        {
            if (from == m_Renter && dropped is Gold)
            {
                if (dropped.Amount == m_RentCost)
                {
                    dropped.Delete(); 
                    m_RentExpires += m_RentDuration;
                    
                    from.PlaySound(0x249);
                    from.SendMessage(68, $"You hand the gold to the landlord and extend your rent.");
                    from.SendMessage(68, $"Your room is now paid until: {m_RentExpires.ToString("g")}");
                    InvalidateProperties();
                    
                    return true;
                }
                else
                {
                    from.SendMessage(33, $"You must drop exactly {m_RentCost} gold on the door to renew it.");
                    return false; 
                }
            }

            return base.OnDragDrop(from, dropped);
        }
    }

    public class InnEvictionCrate : WoodenBox
    {
        public override int DefaultMaxItems { get { return 500; } }
        public override int DefaultMaxWeight { get { return 5000; } }

        [Constructable]
        public InnEvictionCrate()
        {
            Name = "Evicted Inn Room Belongings";
            Hue = 33; 
        }

        public InnEvictionCrate(Serial serial) : base(serial) { }

        public override bool CheckHold(Mobile m, Item item, bool message, bool checkItems, int plusItems, int plusWeight)
        {
            if (m.AccessLevel < AccessLevel.GameMaster)
            {
                if (message)
                    m.SendLocalizedMessage(1061145); 
                
                return false;
            }

            return base.CheckHold(m, item, message, checkItems, plusItems, plusWeight);
        }

        public override void OnItemRemoved(Item item)
        {
            base.OnItemRemoved(item);

            if (this.TotalItems == 0)
            {
                Delete();
            }
        }

        public override void Serialize(GenericWriter writer) { base.Serialize(writer); writer.Write((int)0); }
        public override void Deserialize(GenericReader reader) { base.Deserialize(reader); int version = reader.ReadInt(); }
    }
}
