import asyncio
import os
import ctypes
import time
from playwright.async_api import async_playwright

# ================== ẨN CỬA SỔ CMD ==================
def hide_console():
try:
hwnd = ctypes.windll.kernel32.GetConsoleWindow()
if hwnd:
ctypes.windll.user32.ShowWindow(hwnd, 0) # 0 = SW_HIDE
except Exception:
pass

# Gọi hàm ẩn cửa sổ ngay lập tức khi khởi chạy
hide_console()
# ===================================================
# CẤU HÌNH
# -------------------------------------------------------------
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
ACCOUNTS_FILE = os.path.join(BASE_DIR, "accounts.txt")
INTERVAL_SECONDS = 6 * 60 * 60 # 6 giờ
TOTAL_CAGES = 3 # Số chuồng hiện tại
HEADLESS = True
# -------------------------------------------------------------

def load_accounts(file_path):
accounts = []
if not os.path.exists(file_path):
print(f"[-] File {file_path} không tồn tại!")
return accounts
with open(file_path, "r", encoding="utf-8") as f:
for line in f:
line = line.strip()
if not line or line.startswith("#"):
continue
if "|" in line:
user, pwd = line.split("|", 1)
elif ":" in line:
user, pwd = line.split(":", 1)
else:
continue
accounts.append((user.strip(), pwd.strip()))
return accounts


async def safe_goto(page, url, retries=3):
for attempt in range(1, retries + 1):
try:
await page.goto(url, wait_until="domcontentloaded", timeout=60000)
return True
except Exception as e:
print(f" [!] Lỗi tải trang ({attempt}/{retries}): {e}")
if attempt < retries:
await asyncio.sleep(2)
else:
raise e


async def get_csrf(page):
token = await page.evaluate("""() => {
const input = document.querySelector('input[name="farm_csrf"]');
if (input && input.value) return input.value;

const els = Array.from(document.querySelectorAll('[onclick*="farm_csrf"], a[href*="farm_csrf"]'));
for (const el of els) {
const text = el.getAttribute('onclick') || el.getAttribute('href') || '';
const match = text.match(/farm_csrf=([a-f0-9]+)/i);
if (match) return match[1];
}
return null;
}""")
return token


async def run_vatnuoi():
accounts = load_accounts(ACCOUNTS_FILE)
if not accounts:
print("[-] Danh sách tài khoản trống!")
return

async with async_playwright() as p:
browser = await p.chromium.launch(headless=HEADLESS)

for username, password in accounts:
print("\n==========================================")
print(f"[*] Đang xử lý tài khoản: {username}")
context = await browser.new_context()
page = await context.new_page()
page.on("dialog", lambda dialog: dialog.accept()) # Tự bấm OK confirm
page.set_default_timeout(60000)
page.set_default_navigation_timeout(60000)

try:
# 1. Đăng nhập
print("[1] Đăng nhập...")
await safe_goto(page, "https://1900.fun/login.php")
await page.fill("input[name='username']", username)
await page.fill("input[name='password']", password)
async with page.expect_navigation(wait_until="domcontentloaded"):
await page.click("button[type='submit']")
await page.wait_for_timeout(1500)

# 2. Vào trang Vật Nuôi
print("[2] Vào trang Vật Nuôi...")
await safe_goto(page, "https://1900.fun/nongtrai/vatnuoi.php")
await page.wait_for_timeout(1800)

csrf = await get_csrf(page)
if csrf:
print(f" → CSRF: {csrf[:16]}...")
else:
print(" [!] Không lấy được CSRF")

# 3. Thu hoạch từng chuồng (cách chắc chắn nhất)
print("[3] Thu hoạch vật nuôi...")
for cage_idx in range(TOTAL_CAGES):
if csrf:
harvest_url = f"https://1900.fun/nongtrai/vatnuoi.php?harvest={cage_idx}&farm_csrf={csrf}"
else:
harvest_url = f"https://1900.fun/nongtrai/vatnuoi.php?harvest={cage_idx}"

print(f" → Thử thu hoạch chuồng {cage_idx + 1}...")
await safe_goto(page, harvest_url)
await page.wait_for_timeout(1600)

# Reload lại để lấy trạng thái mới nhất
await safe_goto(page, "https://1900.fun/nongtrai/vatnuoi.php")
await page.wait_for_timeout(1500)

# 4. Kiểm tra chuồng trống + mua
print("[4] Kiểm tra chuồng trống & mua vật nuôi...")

info = await page.evaluate("""() => {
const result = {
animals: typeof animals !== 'undefined' ? animals : [],
userLevel: typeof userLevel !== 'undefined' ? userLevel : 1,
userMoney: typeof userMoney !== 'undefined' ? userMoney : 0,
emptyCages: [],
cageStatus: []
};

const cages = document.querySelectorAll('.cage');
cages.forEach((cage, index) => {
const hasAnimalName = !!cage.querySelector('.animal-name');
const hasTimeLeft = !!cage.querySelector('.time-left');
const hasHarvestBtn = !!cage.querySelector('.harvest-btn, a[href*="harvest="]');
const text = cage.innerText || '';

const isEmpty = cage.classList.contains('empty') ||
(!hasAnimalName && !hasTimeLeft) ||
text.includes('Trống') ||
text.includes('Mua') ||
text.includes('Nuôi');

result.cageStatus.push({
index,
isEmpty,
hasAnimalName,
hasTimeLeft,
text: text.substring(0, 50)
});

if (isEmpty) {
result.emptyCages.push(index);
}
});

return result;
}""")

print(f" → Trạng thái chuồng:")
for st in info.get("cageStatus", []):
status = "TRỐNG" if st["isEmpty"] else "CÓ VẬT NUÔI"
print(f" Chuồng {st['index']+1}: {status} | {st['text']}")

empty_cages = info.get("emptyCages", [])
print(f" → Số chuồng trống: {len(empty_cages)}")

if empty_cages and info.get("animals"):
available = [
a for a in info["animals"]
if a.get("level_required", 1) <= info["userLevel"]
and a.get("price", 0) <= info["userMoney"]
]

if available:
available.sort(key=lambda x: (x.get("level_required", 1), x.get("price", 0)), reverse=True)
best = available[0]
print(f" → Chọn: {best['name']} (Cấp {best['level_required']}) - Giá {best['price']:,} Xu")

for cage_index in empty_cages:
print(f" → Mua vào chuồng {cage_index + 1}...")
await page.evaluate(f"""() => {{
const cageEl = document.getElementById('buyCageIndex');
const animalEl = document.getElementById('buyAnimalId');
if (cageEl) cageEl.value = '{cage_index}';
if (animalEl) animalEl.value = '{best["id"]}';
}}""")

try:
async with page.expect_navigation(wait_until="domcontentloaded", timeout=15000):
await page.eval_on_selector("#buyForm", "form => form.submit()")
print(f" ✓ Đã mua thành công chuồng {cage_index + 1}")
except Exception as e:
print(f" [!] Lỗi mua chuồng {cage_index + 1}: {e}")

await page.wait_for_timeout(1600)

# Trừ tạm tiền để không mua vượt quá
info["userMoney"] -= best["price"]
if info["userMoney"] < best["price"]:
print(" → Hết tiền, dừng mua thêm.")
break
else:
print(" → Không có vật nuôi nào đủ cấp / đủ tiền.")
else:
if not empty_cages:
print(" → Không có chuồng trống (có thể vật nuôi chưa chín hoặc harvest chưa thành công).")
else:
print(" → Không lấy được danh sách animals.")

# 5. Đăng xuất
print("[5] Đăng xuất...")
await safe_goto(page, "https://1900.fun/logout.php")
await page.wait_for_timeout(1000)
print(f"[+] Hoàn tất: {username}")

except Exception as e:
print(f"[-] Lỗi với {username}: {e}")
finally:
await context.close()
await asyncio.sleep(2)

await browser.close()


if __name__ == "__main__":
while True:
try:
print(f"\n==================== [ BẮT ĐẦU VÒNG LẶP VẬT NUÔI ] ====================")
asyncio.run(run_vatnuoi())
except Exception as err:
print(f"[!] Lỗi ngoài: {err}")

hours = INTERVAL_SECONDS // 3600
print(f"\n[⏳] Hoàn thành. Chờ {hours} giờ để chạy tiếp...")
time.sleep(INTERVAL_SECONDS)