import subprocess
import os
import re
import json
import time
import requests
from playwright.sync_api import sync_playwright

def get_credentials():
    """1Password からクレデンシャルを取得する（ログイン直前で呼び出す）"""
    print("🔑 クレデンシャル取得中…")

    vault_name = os.getenv("VAULT_NAME")
    item_name = os.getenv("ITEM_NAME")

    if not vault_name or not item_name:
        print("⚠️ VAULT_NAME または ITEM_NAME が設定されていません！")
        exit(1)

    print(f"🗄️ Vault: {vault_name}, 🔍 Item: {item_name}")

    result = subprocess.run(
        ["op", "item", "get", item_name, "--vault", vault_name, "--format", "json"],
        capture_output=True, text=True
    )

    if result.returncode == 0:
        print("✅ クレデンシャル取得成功！")
        json_data = json.loads(result.stdout)
        print(json.dumps(json_data, indent=4))
        return json_data
    else:
        print(f"⚠️ クレデンシャル取得失敗！\n{result.stderr}")
        exit(1)

def heroku_billing():
    """Heroku の請求情報を取得"""
    print("🟢 heroku_billing() が呼ばれた")

    # 仮想ディスプレイ起動
    print("🖥️ 仮想ディスプレイ起動中…")
    xvfb_process = subprocess.Popen(["Xvfb", ":99", "-screen", "0", "1920x1080x24"])
    os.environ["DISPLAY"] = ":99"

    print("🚀 Playwright 起動開始")
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()

        print("🌍 Heroku ログインページに遷移開始")
        try:
            page.goto("https://id.heroku.com/login")
            print("🖥️ ページ読み込み完了")
            print(f"📄 現在のページタイトル: {page.title()}")
        except Exception as e:
            print(f"❌ ページ遷移失敗！エラー: {e}")
            browser.close()
            xvfb_process.kill()
            exit(1)

        # **ログイン直前でクレデンシャルを取得**
        print("🔑 ログイン情報を取得中…")
        credentials = get_credentials()

        username = credentials["fields"][0]["value"]
        password = credentials["fields"][1]["value"]
        otp = None

        # OTP（ワンタイムパスワード）を抽出
        for field in credentials["fields"]:
            if field["type"] == "OTP":
                otp = field["totp"]
                break

        print(f"📝 取得したクレデンシャル: {username} / {password[:3]}*** / OTP: {otp}")

        # **Heroku ログイン**
        page.wait_for_selector('text="Email address"', state='visible')
        try:
            print("✍️ メールアドレス入力…")
            page.get_by_role("textbox", name="Email address").fill(username)

            print("🔒 パスワード入力…")
            page.get_by_role("textbox", name="Password").fill(password)

            print("🔘 ログインボタンをクリック")
            page.get_by_role("button", name="Log In").click()
        except Exception as e:
            print(f"❌ ログイン失敗！エラー: {e}")
            browser.close()
            xvfb_process.kill()
            exit(1)

        page.wait_for_selector("button:has-text('Choose Another Verification Method')")
        page.get_by_role("button", name="Choose Another Verification Method").click()

        page.wait_for_selector('use[href="/static/icons.svg#number_input"]', state='visible')
        page.locator('use[href="/static/icons.svg#number_input"]').click()

        # OTP 入力直前に最新のOTPを再取得
        credentials = get_credentials()
        otp = None
        for field in credentials["fields"]:
            if field["type"] == "OTP":
                otp = field["totp"]
                break

        print(f"🔢 OTP入力: {otp}")
        page.get_by_role("textbox", name="Verification Code").fill(otp)
        page.get_by_role("button", name="Verify", exact=True).click()

        time.sleep(5)

        # ✅ 認証後、Billingページへ直接遷移！
        page.goto("https://dashboard.heroku.com/teams/jubilee-works/billing")
        
        # テーブルが表示されるのを待つ
        try:
            print("⏳ 請求テーブルの読み込みを待機中...")
            page.wait_for_selector("table.table tbody", state="visible")
            
            print("📄 最新の請求リンクをクリック（新規タブを待機）")
            
            # テーブルの最初の行からすべての送信ボタンを取得
            first_row_buttons = page.locator('table.table tbody tr:first-child input[type="submit"]').all()
            month_button = None
            
            for button in first_row_buttons:
                value = button.get_attribute("value")
                # 4桁の年（20XX）を含むボタンを検出
                if re.search(r'\b20\d\d\b', value):
                    month_button = button
                    print(f"📅 月のボタンを検出: {value}")
                    break
            
            if month_button:
                # メモ: page.expect_popup()を使用
                with page.expect_popup() as new_page_info:
                    month_button.click()
                    print("🖱️ 月ボタンをクリックしました")
                
                print("⏳ 新しいタブが開くのを待機中...")
                invoice_page = new_page_info.value
                
                # loadイベントだけを待機（networidleは待たない）
                print("⏳ 請求詳細ページの基本読み込みを待機中...")
                invoice_page.wait_for_load_state("load", timeout=60000)
                
                # 少し待機して安定させる
                print("⏰ ページの安定化のため5秒待機...")
                time.sleep(5)
                
                # 新しいタブの情報を出力して確認
                print(f"🔗 新しいタブのURL: {invoice_page.url}")
                
                try:
                    print(f"📄 新しいタブのタイトル: {invoice_page.title()}")
                except:
                    print("⚠️ タイトル取得に失敗")
                
                # PDFの保存と操作は新しいタブのページオブジェクトに対して行う
                print("📑 請求詳細ページをPDFとして保存中...")
                try:
                    invoice_page.pdf(path="/app/screenshots/heroku_billing.pdf", timeout=60000)
                    print("✅ PDF保存成功")
                except Exception as pdf_error:
                    print(f"⚠️ PDF生成エラー: {pdf_error}")
                    # エラーが発生しても続行
                
                # PDFの保存と操作は新しいタブのページオブジェクトに対して行う
                print("📑 請求詳細ページをPDFとして保存中...")
                try:
                    # timeout引数を削除
                    invoice_page.pdf(path="/app/screenshots/heroku_billing.pdf")
                    print("✅ PDF保存成功")
                except Exception as pdf_error:
                    print(f"⚠️ PDF生成エラー: {pdf_error}")
                
                print("✅ 最新の請求ページの処理完了")
            else:
                print("❌ 月名を含むボタンが見つかりませんでした")
            
        except Exception as e:
            print(f"❌ 請求ページへの遷移失敗！エラー: {e}")
            # スタックトレースを出力
            import traceback
            print(traceback.format_exc())

        # BillingページのPDFを保存
        pdf_path = "/app/screenshots/heroku_billing.pdf"
        # page.pdf(path=pdf_path, format="A4")
        # print(f"📄 BillingページをPDFとして保存: {pdf_path}")

        # req
        zapier_webhook_url = "https://hooks.zapier.com/hooks/catch/15128763/2legq88/"  # ここにZapierのWebhook URLを入れる

        # PDFファイルをZapierへ送信
        with open(pdf_path, "rb") as pdf_file:
            response = requests.post(
                zapier_webhook_url,
                files={"file": ("heroku_billing.pdf", pdf_file, "application/pdf")},
            )

        # 成功したか確認
        if response.status_code == 200:
            print("✅ ZapierへPDFを送信成功！")
        else:
            print(f"❌ Zapier送信失敗！ステータスコード: {response.status_code}\nレスポンス: {response.text}")

        # 📷 スクリーンショットを撮る（ログイン後の状態）
        # try:
        #     print("⏳ 10秒待機中…")
        #     time.sleep(10)
        #     screenshot_path = "/app/screenshots/heroku_after_login.png"
        #     page.screenshot(path=screenshot_path, full_page=True)  # ← full_page=True を追加！
        #     print(f"✅ スクリーンショット撮影成功: {screenshot_path}")
        # except Exception as e:
        #     print(f"❌ スクリーンショット撮影失敗！エラー: {e}")

        browser.close()

    xvfb_process.kill()
    print("✅ Heroku 請求情報取得完了！")

if __name__ == "__main__":
    print("🚀 Heroku Exporter 起動！")

    heroku_billing()
    print("✅ Playwright Runner 完了！")
