import os
from dataclasses import dataclass

import pytest
from fasthtml.fastapp import fast_app

import myfasthtml.auth.utils
from myfasthtml.auth.routes import setup_auth_routes
from myfasthtml.auth.utils import create_auth_beforeware, register_user
from myfasthtml.test.testclient import MyTestClient


@dataclass
class DummyUser:
  email: str
  username: str
  password: str


@pytest.fixture()
def registered_user():
  user = DummyUser("user@email.com", "user", "#Passw0rd")
  register_user(user.email, user.username, user.password)
  return user


@pytest.fixture()
def app():
  beforeware = create_auth_beforeware()
  test_app, test_rt = fast_app(before=beforeware)
  setup_auth_routes(test_app, test_rt, mount_auth_app=True, sqlite_db_path="TestUsers.db")
  
  @test_rt('/')
  def index(): return "You are now logged in !"
  
  return test_app


@pytest.fixture()
def rt(app):
  return app.route


@pytest.fixture()
def user(app):
  user = MyTestClient(app)
  previous = myfasthtml.auth.utils.http_client
  myfasthtml.auth.utils.http_client = user.client
  
  yield user
  
  myfasthtml.auth.utils.http_client = previous


@pytest.fixture(autouse=True)
def cleanup():
  if os.path.exists("TestUsers.db"):
    os.remove("TestUsers.db")


def test_i_can_see_login_page(user):
  user.open("/login")
  user.should_see("Sign In")
  user.should_see("Register here")
  user.find_form(fields=["Email", "Password"])


def test_i_cannot_login_with_wrong_credentials(user):
  user.open("/login")
  form = user.find_form(fields=["Email", "Password"])
  form.fill(Email="user@email.com", Password="#Passw0rd")
  form.submit()
  user.should_see("Invalid email or password. Please try again.")


def test_i_can_login_with_correct_credentials(user, registered_user):
  user.open("/login")
  form = user.find_form(fields=["Email", "Password"])
  form.fill(Email=registered_user.email, Password=registered_user.password)
  form.submit()
  user.should_see("You are now logged in !")


def test_i_can_can_navigate_once_logged_in(user, registered_user):
  user.open("/welcome")  # not logged in, redirects to login
  user.should_see("Sign In")
  
  form = user.find_form(fields=["Email", "Password"])
  form.fill(Email=registered_user.email, Password=registered_user.password)
  form.submit()
  
  user.open("/welcome")  # once logged in, welcome page is accessible
  user.should_see("Welcome back, user@email.com!")  # welcome page is predefined


def test_i_can_register(user):
  user.open("/register")
  form = user.find_form(fields=["Email", "Username", "Password"])
  form.fill(Email="user@email.com", Username="username", Password="#Passw0rd", confirm_password="#Passw0rd")
  form.submit()
  
  user.should_see("You are now logged in !")


def test_i_can_logout(user, registered_user):
  user.open("/login")
  form = user.find_form(fields=["Email", "Password"])
  form.fill(Email=registered_user.email, Password=registered_user.password)
  form.submit()
  
  user.open("/logout")
  user.should_see("Sign In")
  
  user.open("/welcome")
  user.should_see("Sign In")
