"""Utility functions for the SQ API."""

import csv
import os
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from .dataclasses import RefinementResult


def validate_task_file(filename: str) -> str:
    """Validate that a task file exists and has correct extension.
    
    Args:
        filename: Task file path (relative or absolute).
        
    Returns:
        Absolute path to the task file.
        
    Raises:
        ValueError: If filename is invalid.
        FileNotFoundError: If file doesn't exist.
    """
    if not filename:
        raise ValueError("Filename cannot be empty")
    
    if not isinstance(filename, str):
        raise ValueError(f"Filename must be a string, got {type(filename).__name__}")
    
    abs_filename = os.path.abspath(filename)
    
    if not os.path.exists(abs_filename):
        raise FileNotFoundError(f"Task file not found: {filename} (resolved to: {abs_filename})")
    
    if not abs_filename.lower().endswith(('.tsk', '.tmk')):
        raise ValueError(f"Invalid task file extension: {filename}. Expected .tsk or .tmk")
    
    return abs_filename


def validate_pattern_file(filename: str) -> str:
    """Validate that a pattern file exists.
    
    Args:
        filename: Pattern file path (relative or absolute).
        
    Returns:
        Absolute path to the pattern file.
        
    Raises:
        ValueError: If filename is invalid.
        FileNotFoundError: If file doesn't exist.
    """
    if not filename:
        raise ValueError("Filename cannot be empty")
    
    if not isinstance(filename, str):
        raise ValueError(f"Filename must be a string, got {type(filename).__name__}")
    
    abs_filename = os.path.abspath(filename)
    
    if not os.path.exists(abs_filename):
        raise FileNotFoundError(f"Pattern file not found: {filename} (resolved to: {abs_filename})")
    
    return abs_filename


def validate_job_handle(job_handle: int) -> None:
    """Validate that a job handle is valid.
    
    Args:
        job_handle: Job handle to validate.
    
    Raises:
        ValueError: If job handle is invalid.
    """
    if not isinstance(job_handle, int):
        raise ValueError(f"Job handle must be an integer, got {type(job_handle).__name__}")
    
    if job_handle < 0:
        raise ValueError(f"Job handle must be non-negative, got {job_handle}")


def validate_lib_dir(path: str) -> str:
    """Validate that a library directory exists.
    
    Args:
        path: Library directory path (relative or absolute).
        
    Returns:
        Absolute path to the library directory.
        
    Raises:
        ValueError: If path is invalid or not a directory.
        FileNotFoundError: If directory doesn't exist.
    """
    if not path:
        raise ValueError("Library directory path cannot be empty")
    
    if not isinstance(path, str):
        raise ValueError(f"Library directory path must be a string, got {type(path).__name__}")
    
    abs_path = os.path.abspath(path)
    
    if not os.path.exists(abs_path):
        raise FileNotFoundError(f"Library directory not found: {path} (resolved to: {abs_path})")
    
    if not os.path.isdir(abs_path):
        raise ValueError(f"Library directory path is not a directory: {path}")
    
    return abs_path


def export_results_to_csv(result: 'RefinementResult', filename: str) -> None:
    """Export refinement results to a CSV file.
    
    Args:
        result: RefinementResult object to export.
        filename: Output CSV file path.
    """
    with open(filename, 'w', newline='', encoding='utf-8') as f:
        writer = csv.writer(f)
        
        writer.writerow(['Refinement Results'])
        writer.writerow(['Chi Squared', result.chi_squared])
        writer.writerow(['R Factor', result.r_factor])
        writer.writerow(['Number of Phases', result.n_phases])
        writer.writerow([])
        
        writer.writerow(['Phase Results'])
        writer.writerow(['Phase ID', 'Phase Name', 'Weight %', 'Error of Fit', 'Order No'])
        
        for phase in result.phases:
            writer.writerow([
                phase.phase_id,
                phase.phase_name,
                phase.weight_pc,
                phase.error_of_fit,
                phase.order_no
            ])


def format_error_message(error_code: int, context: str = "") -> str:
    """Format an error message from error code and context.
    
    Args:
        error_code: Error code from DLL.
        context: Additional context information.
    
    Returns:
        Formatted error message string.
    """
    from .constants import ERROR_MESSAGES
    
    msg = ERROR_MESSAGES.get(error_code, f"Unknown error: {error_code}")
    if context:
        msg = f"{msg} Context: {context}"
    return msg
