import pytest

from tests.conftest import add_scheduled_post, login


@pytest.fixture
def fresh_token(monkeypatch):
    monkeypatch.setattr("app.routes.account_routes.ensure_fresh_token", lambda a: "tok")
    monkeypatch.setattr("app.routes.post_routes.ensure_fresh_token", lambda a: "tok")
    monkeypatch.setattr("app.routes.insights_routes.ensure_fresh_token", lambda a: "tok")


def test_login_page_renders(client):
    r = client.get("/login")
    assert r.status_code == 200
    assert "Continue with TikTok" in r.get_data(as_text=True)


def test_gui_requires_login(client, account):
    r = client.get("/dashboard")
    assert r.status_code == 302
    assert "/login" in r.headers["Location"]


def test_dashboard_renders(client, account, fresh_token, monkeypatch):
    monkeypatch.setattr("app.routes.account_routes.get_user_info", lambda token: {"display_name": "Test Account", "follower_count": 1000})
    monkeypatch.setattr(
        "app.routes.account_routes.list_videos",
        lambda token, max_count=5: {"videos": [{"id": "v1", "title": "hello", "view_count": 4, "like_count": 1}], "cursor": 0, "has_more": False},
    )
    login(client, account)
    r = client.get("/dashboard")
    assert r.status_code == 200
    text = r.get_data(as_text=True)
    assert "Test Account" in text
    assert "hello" in text


def test_posts_page_renders(client, account, fresh_token, monkeypatch):
    monkeypatch.setattr(
        "app.routes.post_routes.list_videos",
        lambda token, max_count=20, cursor=0: {"videos": [{"id": "v1", "title": "a video", "view_count": 9, "like_count": 2, "comment_count": 0, "share_count": 1, "create_time": 1700000000, "video_duration": 15}], "cursor": 0, "has_more": False},
    )
    login(client, account)
    r = client.get("/posts")
    assert r.status_code == 200
    assert "a video" in r.get_data(as_text=True)


def test_new_post_publishes_now(client, account, fresh_token, monkeypatch):
    calls = []
    monkeypatch.setattr("app.services.posts.init_video_pull", lambda token, url, title=None, privacy_level=None, mode=None: calls.append(url) or {"publish_id": "pub_1"})
    monkeypatch.setattr("app.services.posts.wait_for_publish", lambda token, pid: {"publish_status": "PUBLISH_COMPLETE", "video_id": "v_1"})
    login(client, account)
    r = client.post("/posts/new", data={"video_url": "https://x/v.mp4", "title": "ui post"}, follow_redirects=True)
    assert r.status_code == 200
    assert calls == ["https://x/v.mp4"]
    assert "Draft sent to TikTok" in r.get_data(as_text=True)


def test_new_post_direct_mode(client, account, fresh_token, monkeypatch):
    calls = []
    monkeypatch.setattr("app.services.posts.init_video_pull", lambda token, url, title=None, privacy_level=None, mode=None: calls.append(mode) or {"publish_id": "pub_1"})
    monkeypatch.setattr("app.services.posts.wait_for_publish", lambda token, pid: {"publish_status": "PUBLISH_COMPLETE", "video_id": "v_1"})
    login(client, account)
    r = client.post("/posts/new", data={"video_url": "https://x/v.mp4", "mode": "direct", "privacy_level": "SELF_ONLY"}, follow_redirects=True)
    assert calls == ["direct"]
    assert "Post sent to TikTok" in r.get_data(as_text=True)


def test_new_post_form_offers_draft_first(client, account):
    login(client, account)
    text = client.get("/posts/new").get_data(as_text=True)
    assert text.index('value="draft"') < text.index('value="direct"')
    assert "tap the inbox notification" in text


def test_new_post_schedules(client, account, fresh_token):
    from datetime import datetime, timedelta, timezone
    login(client, account)
    scheduled_at = (datetime.now(timezone.utc) + timedelta(hours=2)).isoformat()
    r = client.post("/posts/new", data={"video_url": "https://x/v.mp4", "scheduled_at": scheduled_at}, follow_redirects=True)
    assert r.status_code == 200
    assert "Scheduled" in r.get_data(as_text=True)


def test_new_post_flashes_validation_error(client, account, fresh_token):
    login(client, account)
    r = client.post("/posts/new", data={}, follow_redirects=True)
    assert r.status_code == 200
    assert "a post needs a video_url or a video file" in r.get_data(as_text=True)


def test_scheduled_page_renders(client, app, account):
    from datetime import datetime, timedelta, timezone
    add_scheduled_post(app, account, scheduled_at=datetime.now(timezone.utc) + timedelta(hours=1))
    login(client, account)
    r = client.get("/posts/scheduled")
    assert r.status_code == 200
    text = r.get_data(as_text=True)
    assert "scheduled title" in text
    assert "Pending" in text


def test_delete_scheduled_route(client, app, account):
    from datetime import datetime, timedelta, timezone
    post_id = add_scheduled_post(app, account, scheduled_at=datetime.now(timezone.utc) + timedelta(hours=1))
    login(client, account)
    r = client.post("/scheduled/%s/delete" % post_id, follow_redirects=True)
    assert r.status_code == 200
    assert "Scheduled post deleted." in r.get_data(as_text=True)


def test_insights_page(client, account, fresh_token, monkeypatch):
    monkeypatch.setattr("app.routes.insights_routes.get_user_info", lambda token: {"follower_count": 1000, "likes_count": 5000})
    monkeypatch.setattr(
        "app.routes.insights_routes.list_videos",
        lambda token, max_count=50, cursor=0: {"videos": [{"id": "v1", "title": "top video", "view_count": 99, "like_count": 9, "comment_count": 1, "share_count": 2, "create_time": 1700000000}], "cursor": 0, "has_more": False},
    )
    login(client, account)
    r = client.get("/insights")
    assert r.status_code == 200
    text = r.get_data(as_text=True)
    assert "top video" in text
    assert "Top Videos by Views" in text
