from typing import Any

from .base_workflow import BaseWorkflow, WorkflowStatus, WorkflowStep

from common_logging import get_logger

logger = get_logger(__name__)


class InvoiceWorkflow(BaseWorkflow):

    def __init__(self, workflow_id: str, tenant_id: int, user_id: int):
        super().__init__(workflow_id, tenant_id, user_id)
        self._init_steps()

    def _init_steps(self):
        self.add_step(WorkflowStep('issuance', '开票'))
        self.add_step(WorkflowStep('verification', '验证'))
        self.add_step(WorkflowStep('accounting', '入账'))
        self.add_step(WorkflowStep('archiving', '归档'))

    def execute_step(self, step_name: str, data: dict[str, Any]) -> dict[str, Any]:
        step = next((s for s in self.steps if s.name == step_name), None)
        if not step:
            raise ValueError(f'Step {step_name} not found')
        step.status = WorkflowStatus.IN_PROGRESS
        try:
            if step_name == 'issuance':
                result = self._issue_invoice(data)
            elif step_name == 'verification':
                result = self._verify_invoice(data)
            elif step_name == 'accounting':
                result = self._account_invoice(data)
            elif step_name == 'archiving':
                result = self._archive_invoice(data)
            else:
                raise ValueError(f'Unknown step: {step_name}')
            step.status = WorkflowStatus.COMPLETED
            step.result = result
            return result
        except Exception as e:
            step.status = WorkflowStatus.FAILED
            step.error = str(e)
            logger.error(f'Step {step_name} failed: {e}')
            raise

    def _issue_invoice(self, data: dict[str, Any]) -> dict[str, Any]:
        return {'status': 'issued', 'invoice_id': 'inv_001'}

    def _verify_invoice(self, data: dict[str, Any]) -> dict[str, Any]:
        return {'status': 'verified', 'valid': True}

    def _account_invoice(self, data: dict[str, Any]) -> dict[str, Any]:
        return {'status': 'accounted', 'entry_id': 'entry_001'}

    def _archive_invoice(self, data: dict[str, Any]) -> dict[str, Any]:
        return {'status': 'archived', 'archive_id': 'arch_001'}
