import re
import json


def extract_final_answer(pred: str) -> str:
    """
    Extract the final answer table from the prediction text.
    
    Args:
        pred (str): Prediction text containing markdown tables
        
    Returns:
        str: The last table found in the text, or None if no table found
    """
    tables = re.findall(r'(\|[^\n]+\|(?:\n\s*\|[^\n]+\|)*)', pred)
    if not tables:
        return None
    return tables[-1]


def convert_text_to_clean_lines(text: str) -> list:
    """
    Convert text to a list of clean lines.
    
    Args:
        text (str): Input text
        
    Returns:
        list: List of cleaned lines
    """
    lines = text.strip().lower().split("\n")
    return [re.sub(r'\s+', ' ', line) for line in lines]


def convert_text_to_grid(text: str) -> list:
    """
    Convert markdown table text to a 2D grid.
    
    Args:
        text (str): Markdown table text
        
    Returns:
        list: 2D grid of cleaned cell contents
    """
    lines = text.strip().lower().split("\n")
    grid_lines = [line.split("|")[1:-1] for line in lines]
    clean_grid_lines = [[re.sub(r'\s+', ' ', grid.strip()) for grid in line] for line in grid_lines]
    return clean_grid_lines
            

def verify(pred: str, answer: str, meta: dict) -> int:
    """
    Verify if the predicted solution matches the ground truth answer.
    
    Args:
        pred (str): Predicted solution
        answer (str): Ground truth answer
        meta (dict): Metadata containing additional information
        
    Returns:
        int: 1 if solution matches, 0 otherwise
    """
    if isinstance(answer, str):
        try:
            answer = json.loads(answer)
        except json.JSONDecodeError:
            pass
    
    if isinstance(meta, str):
        meta = json.loads(meta)
    elif not isinstance(meta, dict):
        raise ValueError('meta should be dict or str')

    # Extract the final answer from the prediction
    final_answer = extract_final_answer(pred)
    
    if final_answer is None:
        return 0  # No valid answer found
    
    final_answer_grid_lines = convert_text_to_grid(final_answer)
    label_grid_lines = convert_text_to_grid(answer)

    for line in label_grid_lines:
        if line not in final_answer_grid_lines:
            return 0  # Line does not match

    return 1  # All lines match
