# test the initial startup state, before any shifter has been added
# Derek Fujimoto
# Aug 2026

from fixtures import *
from test_adduser import open_addshifter, submit_addshifter, wait_submitted
import time, os
import pandas as pd

MESSAGE = 'Add user to begin scheduling'

def get_database(client):
    current_state = client.odb_get("/Shifts/Variables/stateid")
    path = os.path.dirname(os.path.abspath(__file__))
    path = os.path.join(path, '..', 'data', str(current_state), 'notes_database.csv')
    return pd.read_csv(path)

# check both tables show the message when no shifters are in the ODB
def test_message_present(page):

    @try_again
    def check():

        for table in ('schedule', 'avail'):
            cell = by_id(page, f'{table}_add_user_msg')
            assert cell.is_visible(), \
                f"Expected the '{table}' table to show the add user message when no shifters exist, " \
                f"but it was not displayed"
            assert cell.inner_text() == MESSAGE, \
                f"Expected the '{table}' add user message to read '{MESSAGE}', got '{cell.inner_text()}'"
    check()

# check the message fills the shift rows, so the table is not left ragged
def test_message_spans_table(page):

    @try_again
    def check():

        for table in ('schedule', 'avail'):
            rows = page.locator(f'#{table}_body tr').all()

            # row 0 holds the date headers, the first of which is the shift label column
            ndate_cols = rows[0].locator('td').count() - 1

            # rows 0 and 1 are the date headers and the notes, the rest are shifts
            nshift_rows = len(rows) - 2

            cell = by_id(page, f'{table}_add_user_msg')

            colspan = int(cell.get_attribute('colspan'))
            assert colspan == ndate_cols, \
                f"Expected the '{table}' add user message to span all {ndate_cols} date columns, " \
                f"got colspan={colspan}"

            rowspan = int(cell.get_attribute('rowspan'))
            assert rowspan == nshift_rows, \
                f"Expected the '{table}' add user message to span all {nshift_rows} shift rows, " \
                f"got rowspan={rowspan}"
    check()

# check no assignable or draggable cells are drawn, since there is no one to assign
def test_no_shift_cells(page):

    @try_again
    def check():

        # the message must be drawn first, else the table simply hasn't loaded yet
        assert by_id(page, 'schedule_add_user_msg').count() > 0, \
            f"Expected the add user message to be drawn before checking for shift cells, " \
            f"but the schedule table has not loaded"

        for classname in ('schedule_cell', 'availcell', 'dropopt'):
            count = page.locator(f'.{classname}').count()
            assert count == 0, \
                f"Expected no '{classname}' elements when no shifters exist, got {count}"
    check()

# check the notes row still works, since it is unaffected by the message
def test_notes_still_work(page, client):

    # different columns: the two tables share the note for a given column
    write_note(page, 1, 'schedule', 'schedule note')
    write_note(page, 2, 'avail', 'avail note')

    @try_again
    def check():
        df = get_database(client)
        notes = df.note.tolist()

        assert 'schedule note' in notes, \
            f"Expected 'schedule note' in the notes database when no shifters exist, got {notes}"
        assert 'avail note' in notes, \
            f"Expected 'avail note' in the notes database when no shifters exist, got {notes}"
    check()

# check the message is shown when ContactInfo exists but is empty, which is what
# deleting the last shifter from the ODB leaves behind
def test_message_present_when_contactinfo_empty(page, client):

    # make a shifter then delete it, leaving the empty parent key
    client.odb_set('/Shifts/ContactInfo/tmp/email', 'tmp@test.ca')
    client.odb_delete('/Shifts/ContactInfo/tmp')

    assert client.odb_exists('/Shifts/ContactInfo'), \
        f"Expected /Shifts/ContactInfo to still exist after deleting the only shifter, it does not"

    # redraw: nothing on the page regenerates the table on an ODB change
    page.reload()

    @try_again
    def check():

        for table in ('schedule', 'avail'):
            cell = by_id(page, f'{table}_add_user_msg')
            assert cell.is_visible(), \
                f"Expected the '{table}' table to show the add user message when ContactInfo is " \
                f"empty, but it was not displayed"
    check()

# check the message is replaced by a working table when the first shifter is added
def test_message_cleared_after_adduser(page):

    open_addshifter(page)
    submit_addshifter(page, name='alice', email='alice@test.ca',
                      phone='1 111-111-1111', affiliation='university')

    # add_shifter makes eight sequential rpc calls before it closes the dialog, which a
    # fixed sleep does not reliably cover
    wait_submitted(page)

    @try_again
    def check():

        # the usual cells are drawn, with alice in the dropdown menu
        for element_id in ('cell_1_1', 'availcell_1_1', 'alice_1_1_.'):
            assert by_id(page, element_id).count() > 0, \
                f"Expected element with id='{element_id}' to be drawn after adding a shifter, " \
                f"but it was not found"

        # therefore the message must be gone
        for table in ('schedule', 'avail'):
            count = by_id(page, f'{table}_add_user_msg').count()
            assert count == 0, \
                f"Expected no add user message in the '{table}' table after adding a shifter, got {count}"
    check()
