use tail_fin_common::page::navigate_and_eval;
use tail_fin_common::parse_action_result;
use tail_fin_common::BrowserSession;
use tail_fin_common::TailFinError;

use crate::types::ActionResult;

pub(crate) async fn browser_upvote(
    session: &BrowserSession,
    post_id: &str,
) -> Result<ActionResult, TailFinError> {
    let id = post_id.trim_start_matches("t3_");
    let url = format!("https://www.reddit.com/comments/{}", id);

    let js = r#"(async () => {
        try {
            for (let i = 0; i < 20; i++) {
                const btn = document.querySelector('[aria-label="upvote"]') ||
                            document.querySelector('button[id*="upvote-button"]');
                if (btn) {
                    const isUpvoted = btn.getAttribute('aria-pressed') === 'true';
                    if (isUpvoted) return JSON.stringify({ status: "success", message: "Already upvoted." });
                    btn.click();
                    await new Promise(r => setTimeout(r, 1000));
                    return JSON.stringify({ status: "success", message: "Post upvoted." });
                }
                await new Promise(r => setTimeout(r, 500));
            }
            return JSON.stringify({ status: "failed", message: "Upvote button not found." });
        } catch (e) { return JSON.stringify({ status: "failed", message: e.toString() }); }
    })()"#;

    parse_action_result(navigate_and_eval(session, &url, 2, js).await?)
}

pub(crate) async fn browser_save(
    session: &BrowserSession,
    post_id: &str,
) -> Result<ActionResult, TailFinError> {
    let id = post_id.trim_start_matches("t3_");
    let url = format!("https://www.reddit.com/comments/{}", id);

    let js = r#"(async () => {
        try {
            for (let i = 0; i < 20; i++) {
                const btns = Array.from(document.querySelectorAll('button'));
                const saveBtn = btns.find(b => {
                    const text = (b.textContent || '').trim().toLowerCase();
                    return text === 'save' || text === 'unsave';
                });
                if (saveBtn) {
                    const text = (saveBtn.textContent || '').trim().toLowerCase();
                    if (text === 'unsave') return JSON.stringify({ status: "success", message: "Already saved." });
                    saveBtn.click();
                    await new Promise(r => setTimeout(r, 1000));
                    return JSON.stringify({ status: "success", message: "Post saved." });
                }
                await new Promise(r => setTimeout(r, 500));
            }
            return JSON.stringify({ status: "failed", message: "Save button not found." });
        } catch (e) { return JSON.stringify({ status: "failed", message: e.toString() }); }
    })()"#;

    parse_action_result(navigate_and_eval(session, &url, 2, js).await?)
}

pub(crate) async fn browser_comment(
    session: &BrowserSession,
    post_id: &str,
    text: &str,
) -> Result<ActionResult, TailFinError> {
    let id = post_id.trim_start_matches("t3_");
    session
        .navigate(&format!("https://www.reddit.com/comments/{}", id))
        .await?;
    let _ = session.wait_for_network_idle(15000, 1000).await;
    tokio::time::sleep(std::time::Duration::from_secs(3)).await;

    let escaped = tail_fin_common::js::escape_js_string(text);

    let js = format!(
        r#"(async () => {{
            try {{
                const box = document.querySelector('[data-testid="comment-composer-text-input"]') ||
                            document.querySelector('div[contenteditable="true"][role="textbox"]') ||
                            document.querySelector('.public-DraftEditor-content');
                if (!box) return JSON.stringify({{ status: "failed", message: "Comment box not found." }});
                box.focus();
                const dt = new DataTransfer();
                dt.setData('text/plain', "{escaped}");
                box.dispatchEvent(new ClipboardEvent('paste', {{ clipboardData: dt, bubbles: true, cancelable: true }}));
                await new Promise(r => setTimeout(r, 1000));
                const btns = Array.from(document.querySelectorAll('button'));
                const submitBtn = btns.find(b => {{
                    const t = (b.textContent || '').trim().toLowerCase();
                    return t === 'comment' && !b.disabled;
                }});
                if (submitBtn) {{
                    submitBtn.click();
                    await new Promise(r => setTimeout(r, 1500));
                    return JSON.stringify({{ status: "success", message: "Comment posted." }});
                }}
                return JSON.stringify({{ status: "failed", message: "Submit button not found or disabled." }});
            }} catch (e) {{ return JSON.stringify({{ status: "failed", message: e.toString() }}); }}
        }})()"#
    );

    parse_action_result(session.eval(&js).await?)
}

pub(crate) async fn browser_subscribe(
    session: &BrowserSession,
    subreddit: &str,
) -> Result<ActionResult, TailFinError> {
    let sub = subreddit.trim_start_matches("r/");
    let url = format!("https://www.reddit.com/r/{}", sub);

    let js = r#"(async () => {
        try {
            for (let i = 0; i < 20; i++) {
                const btns = Array.from(document.querySelectorAll('button'));
                const joinBtn = btns.find(b => {
                    const t = (b.textContent || '').trim().toLowerCase();
                    return t === 'join' || t === 'joined';
                });
                if (joinBtn) {
                    const text = (joinBtn.textContent || '').trim().toLowerCase();
                    if (text === 'joined') return JSON.stringify({ status: "success", message: "Already subscribed." });
                    joinBtn.click();
                    await new Promise(r => setTimeout(r, 1000));
                    return JSON.stringify({ status: "success", message: "Subscribed to subreddit." });
                }
                await new Promise(r => setTimeout(r, 500));
            }
            return JSON.stringify({ status: "failed", message: "Join button not found." });
        } catch (e) { return JSON.stringify({ status: "failed", message: e.toString() }); }
    })()"#;

    parse_action_result(navigate_and_eval(session, &url, 2, js).await?)
}
