"""
Wizard Service for Time Tracking Module
========================================

Step-by-step approval flow for time entries.
Brugeren godkender én tidsregistrering ad gangen.
"""

import logging
from typing import Optional, List, Dict, Any
from decimal import Decimal
from datetime import datetime

from fastapi import HTTPException
from app.core.database import execute_query, execute_update, execute_query_single
from app.timetracking.backend.models import (
    TModuleTimeWithContext,
    TModuleTimeApproval,
    TModuleWizardProgress,
    TModuleWizardNextEntry,
    TModuleApprovalStats
)
from app.timetracking.backend.audit import audit

logger = logging.getLogger(__name__)


class WizardService:
    """Service for managing wizard-based approval flow"""
    
    @staticmethod
    def get_customer_stats(customer_id: int) -> Optional[TModuleApprovalStats]:
        """Hent approval statistics for en kunde"""
        try:
            query = """
                SELECT * FROM tmodule_approval_stats 
                WHERE customer_id = %s
            """
            result = execute_query_single(query, (customer_id,))
            
            if not result:
                return None
            
            return TModuleApprovalStats(**result)
        
        except Exception as e:
            logger.error(f"❌ Error getting customer stats: {e}")
            return None
    
    @staticmethod
    def get_all_customers_stats() -> list[TModuleApprovalStats]:
        """Hent approval statistics for alle kunder (inkl. Hub Worklogs)"""
        try:
            # 1. Get base stats from module view
            query = """
                SELECT s.*, c.hub_customer_id 
                FROM tmodule_approval_stats s
                LEFT JOIN tmodule_customers c ON s.customer_id = c.id
                ORDER BY s.customer_name
            """
            results = execute_query(query)
            stats_map = {row['customer_id']: dict(row) for row in results}
            
            # 2. Get pending count from Hub Worklogs
            # Filter logic: status='draft' in Hub = 'pending' in Wizard
            hub_query = """
                SELECT 
                    mc.id as tmodule_customer_id, 
                    mc.name as customer_name,
                    mc.vtiger_id as customer_vtiger_id,
                    mc.uses_time_card,
                    mc.hub_customer_id,
                    count(*) as pending_count, 
                    sum(w.hours) as pending_hours
                FROM tticket_worklog w
                JOIN tticket_tickets t ON w.ticket_id = t.id
                JOIN tmodule_customers mc ON mc.hub_customer_id = t.customer_id
                WHERE w.status = 'draft'
                GROUP BY mc.id, mc.name, mc.vtiger_id, mc.uses_time_card, mc.hub_customer_id
            """
            hub_results = execute_query(hub_query)
            
            # 3. Merge stats
            for row in hub_results:
                tm_id = row['tmodule_customer_id']
                
                if tm_id in stats_map:
                    # Update existing
                    stats_map[tm_id]['pending_count'] += row['pending_count']
                    stats_map[tm_id]['total_entries'] += row['pending_count']
                    # Optional: Add to total_original_hours if desired
                else:
                    # New entry for customer only present in Hub worklogs
                    stats_map[tm_id] = {
                        "customer_id": tm_id,
                        "hub_customer_id": row['hub_customer_id'],
                        "customer_name": row['customer_name'],
                        "customer_vtiger_id": row['customer_vtiger_id'] or '',
                        "uses_time_card": row['uses_time_card'],
                        "total_entries": row['pending_count'],
                        "pending_count": row['pending_count'],
                        "approved_count": 0,
                        "rejected_count": 0,
                        "billed_count": 0,
                        "total_original_hours": 0, # Could use row['pending_hours']
                        "total_approved_hours": 0,
                        "latest_work_date": None,
                        "last_sync": None
                    }
            
            return [TModuleApprovalStats(**s) for s in sorted(stats_map.values(), key=lambda x: x['customer_name'])]
        
        except Exception as e:
            logger.error(f"❌ Error getting all customer stats: {e}")
            return []
        
        except Exception as e:
            logger.error(f"❌ Error getting all customer stats: {e}")
            return []
    
    @staticmethod
    def get_next_pending_entry(
        customer_id: Optional[int] = None,
        exclude_time_card: bool = True
    ) -> TModuleWizardNextEntry:
        """
        Hent næste pending tidsregistrering til godkendelse.
        
        Args:
            customer_id: Valgfri - filtrer til specifik kunde
            exclude_time_card: Ekskluder klippekort-kunder (default: true)
            
        Returns:
            TModuleWizardNextEntry med has_next=True hvis der er flere
        """
        try:
            if customer_id:
                # Hent næste for specifik kunde
                query = """
                    SELECT * FROM tmodule_next_pending 
                    WHERE customer_id = %s
                    LIMIT 1
                """
                result = execute_query_single(query, (customer_id,))
            else:
                # Hent næste generelt
                if exclude_time_card:
                    query = """
                        SELECT np.* FROM tmodule_next_pending np
                        JOIN tmodule_customers c ON np.customer_id = c.id
                        WHERE c.uses_time_card = false
                        LIMIT 1
                    """
                else:
                    query = "SELECT * FROM tmodule_next_pending LIMIT 1"
                    
                result = execute_query_single(query)
            
            if not result:
                # Ingen flere entries
                return TModuleWizardNextEntry(
                    has_next=False,
                    time_entry=None,
                    progress=None
                )
            
            # Build entry with context
            entry = TModuleTimeWithContext(**result)
            
            # Get progress if customer_id known
            progress = None
            cust_id = customer_id or entry.customer_id
            if cust_id:
                stats = WizardService.get_customer_stats(cust_id)
                if stats:
                    progress = TModuleWizardProgress(
                        customer_id=stats.customer_id,
                        customer_name=stats.customer_name,
                        total_entries=stats.total_entries,
                        approved_entries=stats.approved_count,
                        pending_entries=stats.pending_count,
                        rejected_entries=stats.rejected_count,
                        current_case_id=entry.case_id,
                        current_case_title=entry.case_title
                    )
            
            return TModuleWizardNextEntry(
                has_next=True,
                time_entry=entry,
                progress=progress
            )
        
        except Exception as e:
            logger.error(f"❌ Error getting next entry: {e}")
            raise HTTPException(status_code=500, detail=str(e))
    
    @staticmethod
    def approve_time_entry(
        approval: TModuleTimeApproval,
        user_id: Optional[int] = None
    ) -> TModuleTimeWithContext:
        """
        Godkend en tidsregistrering.
        
        Args:
            approval: Approval data med time_id og approved_hours
            user_id: ID på brugeren der godkender
            
        Returns:
            Opdateret tidsregistrering
        """
        try:
            # Hent original entry
            query = """
                SELECT t.*, c.title as case_title, c.status as case_status,
                       cust.name as customer_name, cust.hourly_rate as customer_rate
                FROM tmodule_times t
                JOIN tmodule_cases c ON t.case_id = c.id
                JOIN tmodule_customers cust ON t.customer_id = cust.id
                WHERE t.id = %s
            """
            entry = execute_query_single(query, (approval.time_id,))
            
            if not entry:
                raise HTTPException(status_code=404, detail="Time entry not found")
            
            if entry['status'] != 'pending':
                raise HTTPException(
                    status_code=400,
                    detail=f"Time entry already {entry['status']}"
                )
            
            # Check if already billed
            if entry.get('billed_via_thehub_id') is not None:
                raise HTTPException(
                    status_code=400,
                    detail="Cannot approve time entry that has already been billed"
                )
            
            # Update entry
            logger.info(f"🔄 Updating time entry {approval.time_id} in database")
            update_query = """
                UPDATE tmodule_times
                SET status = 'approved',
                    approved_hours = %s,
                    rounded_to = %s,
                    approval_note = %s,
                    billable = %s,
                    is_travel = %s,
                    approved_at = CURRENT_TIMESTAMP,
                    approved_by = %s
                WHERE id = %s
                AND billed_via_thehub_id IS NULL
            """
            
            execute_update(
                update_query,
                (
                    approval.approved_hours,
                    approval.rounded_to,
                    approval.approval_note,
                    approval.billable,
                    approval.is_travel,
                    user_id,
                    approval.time_id
                )
            )
            
            logger.info(f"✅ Database update successful for time entry {approval.time_id}")
            
            # Log approval
            audit.log_approval(
                time_id=approval.time_id,
                original_hours=float(entry['original_hours']),
                approved_hours=float(approval.approved_hours),
                rounded_to=float(approval.rounded_to) if approval.rounded_to else None,
                note=approval.approval_note,
                user_id=user_id
            )
            
            logger.info(
                f"✅ Approved time entry {approval.time_id}: "
                f"{entry['original_hours']}h → {approval.approved_hours}h"
            )
            
            # Return updated entry
            updated = execute_query_single(query, (approval.time_id,))
            return TModuleTimeWithContext(**updated)
        
        except HTTPException:
            raise
        except Exception as e:
            logger.error(f"❌ Error approving time entry: {e}")
            raise HTTPException(status_code=500, detail=str(e))
    
    @staticmethod
    def reject_time_entry(
        time_id: int,
        reason: Optional[str] = None,
        user_id: Optional[int] = None
    ) -> TModuleTimeWithContext:
        """
        Afvis en tidsregistrering.
        
        Args:
            time_id: ID på tidsregistreringen
            reason: Årsag til afvisning
            user_id: ID på brugeren der afviser
            
        Returns:
            Opdateret tidsregistrering
        """
        try:
            # Check exists
            query = """
                SELECT t.*, c.title as case_title, c.status as case_status,
                       cust.name as customer_name, cust.hourly_rate as customer_rate
                FROM tmodule_times t
                JOIN tmodule_cases c ON t.case_id = c.id
                JOIN tmodule_customers cust ON t.customer_id = cust.id
                WHERE t.id = %s
            """
            entry = execute_query_single(query, (time_id,))
            
            if not entry:
                raise HTTPException(status_code=404, detail="Time entry not found")
            
            if entry['status'] != 'pending':
                raise HTTPException(
                    status_code=400,
                    detail=f"Time entry already {entry['status']}"
                )
            
            # Check if already billed
            if entry.get('billed_via_thehub_id') is not None:
                raise HTTPException(
                    status_code=400,
                    detail="Cannot reject time entry that has already been billed"
                )
            
            # Update to rejected
            update_query = """
                UPDATE tmodule_times
                SET status = 'rejected',
                    approval_note = %s,
                    billable = false,
                    approved_at = CURRENT_TIMESTAMP,
                    approved_by = %s
                WHERE id = %s
                AND billed_via_thehub_id IS NULL
            """
            
            execute_update(update_query, (reason, user_id, time_id))
            
            # Log rejection
            audit.log_rejection(
                time_id=time_id,
                reason=reason,
                user_id=user_id
            )
            
            logger.info(f"❌ Rejected time entry {time_id}: {reason}")
            
            # Return updated
            updated = execute_query_single(query, (time_id,))
            return TModuleTimeWithContext(**updated)
        
        except HTTPException:
            raise
        except Exception as e:
            logger.error(f"❌ Error rejecting time entry: {e}")
            raise HTTPException(status_code=500, detail=str(e))
    
    @staticmethod
    def reset_to_pending(
        time_id: int,
        reason: Optional[str] = None,
        user_id: Optional[int] = None
    ) -> TModuleTimeWithContext:
        """
        Nulstil en godkendt/afvist tidsregistrering tilbage til pending.
        
        Args:
            time_id: ID på tidsregistreringen
            reason: Årsag til nulstilling
            user_id: ID på brugeren der nulstiller
            
        Returns:
            Opdateret tidsregistrering
        """
        try:
            # Check exists
            query = """
                SELECT t.*, c.title as case_title, c.status as case_status,
                       cust.name as customer_name, cust.hourly_rate as customer_rate
                FROM tmodule_times t
                JOIN tmodule_cases c ON t.case_id = c.id
                JOIN tmodule_customers cust ON t.customer_id = cust.id
                WHERE t.id = %s
            """
            entry = execute_query_single(query, (time_id,))
            
            if not entry:
                raise HTTPException(status_code=404, detail="Time entry not found")
            
            if entry['status'] == 'pending':
                raise HTTPException(
                    status_code=400,
                    detail="Time entry is already pending"
                )
            
            if entry['status'] == 'billed':
                raise HTTPException(
                    status_code=400,
                    detail="Cannot reset billed entries"
                )
            
            # Check if already billed via Hub order
            if entry.get('billed_via_thehub_id') is not None:
                raise HTTPException(
                    status_code=400,
                    detail="Cannot reset time entry that has been billed through Hub order"
                )
            
            # Reset to pending - clear all approval data
            update_query = """
                UPDATE tmodule_times
                SET status = 'pending',
                    approved_hours = NULL,
                    rounded_to = NULL,
                    approval_note = %s,
                    billable = true,
                    approved_at = NULL,
                    approved_by = NULL
                WHERE id = %s
                AND billed_via_thehub_id IS NULL
            """
            
            execute_update(update_query, (reason, time_id))
            
            # Log reset
            audit.log_event(
                event_type="reset_to_pending",
                entity_type="time_entry",
                entity_id=time_id,
                user_id=user_id,
                details={
                    "reason": reason or "Reset to pending",
                    "timestamp": datetime.now().isoformat()
                }
            )
            
            logger.info(f"🔄 Reset time entry {time_id} to pending: {reason}")
            
            # Return updated
            updated = execute_query_single(query, (time_id,))
            return TModuleTimeWithContext(**updated)
        
        except HTTPException:
            raise
        except Exception as e:
            logger.error(f"❌ Error resetting time entry: {e}")
            raise HTTPException(status_code=500, detail=str(e))
    
    @staticmethod
    def approve_case_entries(
        case_id: int,
        user_id: Optional[int] = None,
        exclude_time_card: bool = True
    ) -> Dict[str, Any]:
        """
        Bulk-godkend alle pending tidsregistreringer for en case.
        
        Args:
            case_id: Case ID
            user_id: ID på brugeren der godkender
            exclude_time_card: Ekskluder klippekort-kunder
            
        Returns:
            Dict med statistik: approved_count, total_hours, etc.
        """
        try:
            # Hent alle pending entries for case
            entries = WizardService.get_case_entries(case_id, exclude_time_card)
            
            if not entries:
                return {
                    "approved_count": 0,
                    "total_hours": 0.0,
                    "case_id": case_id,
                    "entries": []
                }
            
            approved_entries = []
            total_hours = 0.0
            
            for entry in entries:
                # Auto-approve med samme timer som original (eller afrundet hvis enabled)
                from app.core.config import settings
                from decimal import Decimal
                
                approved_hours = Decimal(str(entry.original_hours))
                
                # Afrund hvis enabled
                if settings.TIMETRACKING_AUTO_ROUND:
                    increment = Decimal(str(settings.TIMETRACKING_ROUND_INCREMENT))
                    
                    if settings.TIMETRACKING_ROUND_METHOD == "up":
                        # Afrund op
                        approved_hours = (approved_hours / increment).quantize(Decimal('1'), rounding='ROUND_UP') * increment
                    elif settings.TIMETRACKING_ROUND_METHOD == "down":
                        # Afrund ned  
                        approved_hours = (approved_hours / increment).quantize(Decimal('1'), rounding='ROUND_DOWN') * increment
                    else:
                        # Nærmeste
                        approved_hours = (approved_hours / increment).quantize(Decimal('1'), rounding='ROUND_HALF_UP') * increment
                
                # Godkend entry
                approval = TModuleTimeApproval(
                    time_id=entry.id,
                    approved_hours=float(approved_hours)
                )
                
                approved = WizardService.approve_time_entry(approval, user_id)
                approved_entries.append({
                    "id": approved.id,
                    "original_hours": float(approved.original_hours),
                    "approved_hours": float(approved.approved_hours)
                })
                total_hours += float(approved.approved_hours)
            
            # Log bulk approval
            audit.log_event(
                entity_type="case",
                entity_id=str(case_id),
                event_type="bulk_approval",
                details={
                    "approved_count": len(approved_entries),
                    "total_hours": total_hours
                },
                user_id=user_id
            )
            
            return {
                "approved_count": len(approved_entries),
                "total_hours": total_hours,
                "case_id": case_id,
                "entries": approved_entries
            }
            
        except HTTPException:
            raise
        except Exception as e:
            logger.error(f"❌ Error bulk approving case: {e}")
            raise HTTPException(status_code=500, detail=str(e))
    
    @staticmethod
    def get_customer_progress(customer_id: int) -> TModuleWizardProgress:
        """Hent wizard progress for en kunde"""
        try:
            stats = WizardService.get_customer_stats(customer_id)
            
            if not stats:
                raise HTTPException(status_code=404, detail="Customer not found")
            
            # Get current case if any pending entries
            current_case_id = None
            current_case_title = None
            
            if stats.pending_count > 0:
                query = """
                    SELECT c.id, c.title
                    FROM tmodule_times t
                    JOIN tmodule_cases c ON t.case_id = c.id
                    WHERE t.customer_id = %s 
                    AND t.status = 'pending'
                    AND t.billed_via_thehub_id IS NULL
                    ORDER BY t.worked_date
                    LIMIT 1
                """
                case = execute_query_single(query, (customer_id,))
                if case:
                    current_case_id = case['id']
                    current_case_title = case['title']
            
            return TModuleWizardProgress(
                customer_id=stats.customer_id,
                customer_name=stats.customer_name,
                total_entries=stats.total_entries,
                approved_entries=stats.approved_count,
                pending_entries=stats.pending_count,
                rejected_entries=stats.rejected_count,
                current_case_id=current_case_id,
                current_case_title=current_case_title
            )
        
        except HTTPException:
            raise
        except Exception as e:
            logger.error(f"❌ Error getting customer progress: {e}")
            raise HTTPException(status_code=500, detail=str(e))
    
    @staticmethod
    def get_case_entries(
        case_id: int,
        exclude_time_card: bool = True
    ) -> List[TModuleTimeWithContext]:
        """
        Hent alle pending tidsregistreringer for en specifik case.
        
        Bruges til at vise alle timelogs i samme case samtidig.
        
        Args:
            case_id: Case ID
            exclude_time_card: Ekskluder klippekort-kunder
            
        Returns:
            Liste af tidsregistreringer for casen
        """
        try:
            if exclude_time_card:
                query = """
                    SELECT t.id, t.vtiger_id, t.case_id, t.customer_id, t.description,
                           t.original_hours, t.worked_date, t.user_name, t.status,
                           t.approved_hours, t.rounded_to, t.approval_note, t.billable,
                           t.approved_at, t.approved_by, t.vtiger_data, t.sync_hash,
                           t.created_at, t.updated_at, t.last_synced_at,
                           COALESCE(NULLIF(TRIM(c.title), ''), c.vtiger_data->>'title', 'Ingen titel')::VARCHAR(500) AS case_title,
                           c.description AS case_description,
                           c.status AS case_status,
                           c.vtiger_id AS case_vtiger_id,
                           cust.name AS customer_name,
                           cust.hourly_rate AS customer_rate,
                           CONCAT(cont.first_name, ' ', cont.last_name) AS contact_name,
                           cont.user_company AS contact_company,
                           c.vtiger_data AS case_vtiger_data
                    FROM tmodule_times t
                    JOIN tmodule_cases c ON t.case_id = c.id
                    JOIN tmodule_customers cust ON t.customer_id = cust.id
                    LEFT JOIN contacts cont ON cont.vtiger_id = c.vtiger_data->>'contact_id'
                    WHERE t.case_id = %s 
                      AND t.status = 'pending'
                      AND t.billable = true
                      AND t.vtiger_data->>'cf_timelog_invoiced' = '0'
                      AND t.billed_via_thehub_id IS NULL
                      AND (t.vtiger_data->>'cf_timelog_rounduptimespent' IS NULL 
                           OR t.vtiger_data->>'cf_timelog_rounduptimespent' = '0'
                           OR t.vtiger_data->>'cf_timelog_rounduptimespent' = '')
                      AND (t.vtiger_data->>'cf_timelog_billedviathehubid' IS NULL 
                           OR t.vtiger_data->>'cf_timelog_billedviathehubid' = '0'
                           OR t.vtiger_data->>'cf_timelog_billedviathehubid' = '')
                      AND cust.uses_time_card = false
                    ORDER BY t.worked_date, t.id
                """
            else:
                query = """
                    SELECT t.id, t.vtiger_id, t.case_id, t.customer_id, t.description,
                           t.original_hours, t.worked_date, t.user_name, t.status,
                           t.approved_hours, t.rounded_to, t.approval_note, t.billable,
                           t.approved_at, t.approved_by, t.vtiger_data, t.sync_hash,
                           t.created_at, t.updated_at, t.last_synced_at,
                           COALESCE(NULLIF(TRIM(c.title), ''), c.vtiger_data->>'title', 'Ingen titel')::VARCHAR(500) AS case_title,
                           c.description AS case_description,
                           c.status AS case_status,
                           c.vtiger_id AS case_vtiger_id,
                           cust.name AS customer_name,
                           cust.hourly_rate AS customer_rate,
                           CONCAT(cont.first_name, ' ', cont.last_name) AS contact_name,
                           cont.user_company AS contact_company,
                           c.vtiger_data AS case_vtiger_data
                    FROM tmodule_times t
                    JOIN tmodule_cases c ON t.case_id = c.id
                    JOIN tmodule_customers cust ON t.customer_id = cust.id
                    LEFT JOIN contacts cont ON cont.vtiger_id = c.vtiger_data->>'contact_id'
                    WHERE t.case_id = %s 
                      AND t.status = 'pending'
                      AND t.billable = true
                      AND t.vtiger_data->>'cf_timelog_invoiced' = '0'
                      AND t.billed_via_thehub_id IS NULL
                      AND (t.vtiger_data->>'cf_timelog_rounduptimespent' IS NULL 
                           OR t.vtiger_data->>'cf_timelog_rounduptimespent' = '0'
                           OR t.vtiger_data->>'cf_timelog_rounduptimespent' = '')
                      AND (t.vtiger_data->>'cf_timelog_billedviathehubid' IS NULL 
                           OR t.vtiger_data->>'cf_timelog_billedviathehubid' = '0'
                           OR t.vtiger_data->>'cf_timelog_billedviathehubid' = '')
                    ORDER BY t.worked_date, t.id
                """
            
            results = execute_query(query, (case_id,))
            return [TModuleTimeWithContext(**row) for row in results]
            
        except Exception as e:
            logger.error(f"❌ Error getting case entries: {e}")
            raise HTTPException(status_code=500, detail=str(e))
    
    @staticmethod
    def get_case_details(case_id: int) -> Dict[str, Any]:
        """
        Hent komplet case information inkl. alle timelogs og kommentarer.
        
        Returns:
            Dict med case info, timelogs (alle statuses), og kommentarer fra vtiger_data
        """
        try:
            # Hent case info
            case_query = """
                SELECT id, vtiger_id, title, description, status, 
                       vtiger_data, customer_id
                FROM tmodule_cases 
                WHERE id = %s
            """
            case = execute_query_single(case_query, (case_id,))
            
            if not case:
                raise HTTPException(status_code=404, detail="Case not found")
            
            # Hent ALLE timelogs for casen (ikke kun pending)
            timelogs_query = """
                SELECT t.*,
                       COALESCE(NULLIF(TRIM(c.title), ''), c.vtiger_data->>'title', 'Ingen titel')::VARCHAR(500) AS case_title,
                       c.status AS case_status,
                       c.vtiger_id AS case_vtiger_id,
                       cust.name AS customer_name,
                       cust.hourly_rate AS customer_rate
                FROM tmodule_times t
                JOIN tmodule_cases c ON t.case_id = c.id
                JOIN tmodule_customers cust ON t.customer_id = cust.id
                WHERE t.case_id = %s
                ORDER BY t.worked_date DESC, t.created_at DESC
            """
            timelogs = execute_query(timelogs_query, (case_id,))
            
            # Parse case comments from vtiger_data JSON
            case_comments = []
            if case.get('vtiger_data'):
                vtiger_data = case['vtiger_data']
                # vTiger gemmer comments som en array i JSON
                if isinstance(vtiger_data, dict):
                    raw_comments = vtiger_data.get('comments', []) or vtiger_data.get('modcomments', [])
                    
                    for comment in raw_comments:
                        if isinstance(comment, dict):
                            case_comments.append({
                                'id': comment.get('modcommentsid', comment.get('id')),
                                'comment_text': comment.get('commentcontent', comment.get('comment', '')),
                                'creator_name': comment.get('assigned_user_id', comment.get('creator', 'Unknown')),
                                'created_at': comment.get('createdtime', comment.get('created_at', ''))
                            })
            
            return {
                'case_id': case['id'],
                'case_vtiger_id': case['vtiger_id'],
                'case_title': case['title'],
                'case_description': case['description'],
                'case_status': case['status'],
                'timelogs': [TModuleTimeWithContext(**t) for t in timelogs],
                'case_comments': case_comments
            }
            
        except HTTPException:
            raise
        except Exception as e:
            logger.error(f"❌ Error getting case details: {e}")
            raise HTTPException(status_code=500, detail=str(e))


# Singleton instance
wizard = WizardService()
