import json
from datetime import datetime
from typing import TYPE_CHECKING

from src.models.users import UsersORM
from src.schemas.users import User

if TYPE_CHECKING:
    from tests.conftest import TestDBManager


async def test_user_crud(db: "TestDBManager"):
    data = {
        "username": "test",
        "hashed_password": "hashed_pass",
        "email": "test@mail.ru",
        "is_active": True,
        "is_superuser": False,
    }
    user = await db.user.create_one(data=data)
    assert user.username == data["username"]
    filtered_user = await db.user.get_filtered(username=data["username"])
    assert filtered_user[0] == user
    new_user = User.model_validate(user)
    new_user.username = "Test2"
    new_user.email = None
    await db.user.update_one(id=new_user.id, data=User.model_dump(new_user))
    updated_user = await db.user.get_one_or_none(id=new_user.id)
    assert updated_user
    assert updated_user.username == new_user.username
    assert not updated_user.email
    await db.user.delete_one(id=updated_user.id)
    delete_user = await db.user.get_one_or_none(id=new_user.id)
    assert not delete_user


async def test_tasks_user(db: "TestDBManager"):
    with open("tests/mock_tasks.json") as jsonfile:
        data = json.load(jsonfile)
    admin_user: UsersORM | None = await db.user.get_one_or_none(id=1)
    assert admin_user
    data = [
        {
            **item,
            "user_id": admin_user.id,
            "due_date": datetime.strptime(item["due_date"], "%Y-%m-%d"),
        }
        for item in data
    ]
    result = await db.task.create_bulk(data)
    await db.commit()
    assert result
    tasks = await db.task.get_filtered(user_id=admin_user.id)
    assert tasks
    user_with_tasks = await db.user.get_one_with_load(user_id=admin_user.id)
    assert user_with_tasks
    assert user_with_tasks.tasks


async def test_tasks_crud(db: "TestDBManager"):
    data = {
        "title": "test_tasks_crud",
        "description": "test",
        "due_date": datetime.now(),
        "status": "open",
        "priority": "medium",
        "user_id": 1,
    }
    task = await db.task.create_one(data)
    assert task
    assert task.title == data["title"]
    assert task.description == data["description"]
    assert task.due_date == data["due_date"].date()
    assert task.status == data["status"]
    assert task.priority == data["priority"]
    assert task.user_id == data["user_id"]
    assert task.created_at is not None
    find_task = await db.task.get_filtered(title=data["title"])
    assert find_task
    assert find_task[0].title == task.title
    data["title"] = "test2"
    task = await db.task.update_one(id=task.id, data=data)
    assert task.title == data["title"]
    await db.task.delete_one(id=task.id)
    task = await db.task.get_one_or_none(id=task.id)
    assert not task
