import { createMachine, createActor } from 'xstate';

// 数据状态定义
export type DataState = 'raw' | 'validating' | 'valid' | 'invalid' | 'processing' | 'processed' | 'error';

// 数据状态事件
export type DataEvent = 
  | { type: 'VALIDATE' }
  | { type: 'VALID' }
  | { type: 'INVALID' }
  | { type: 'PROCESS' }
  | { type: 'PROCESS_SUCCESS' }
  | { type: 'PROCESS_ERROR' }
  | { type: 'RETRY' };

// 数据状态上下文
export interface DataContext {
  dataId: string;
  tenantId: string;
  shopId: string;
  taskId: string;
  traceId: string;
  businessType: 'TOC' | 'TOB';
  lastUpdated: string;
  updatedBy: string;
  dataType: string;
  source: string;
}

// 数据状态机
export const dataStateMachine = createMachine({
  id: 'data',
  initial: 'raw',
  context: {} as DataContext,
  states: {
    raw: {
      on: {
        VALIDATE: 'validating'
      }
    },
    validating: {
      on: {
        VALID: 'valid',
        INVALID: 'invalid'
      }
    },
    valid: {
      on: {
        PROCESS: 'processing'
      }
    },
    invalid: {
      on: {
        VALIDATE: 'validating'
      }
    },
    processing: {
      on: {
        PROCESS_SUCCESS: 'processed',
        PROCESS_ERROR: 'error'
      }
    },
    processed: {
      type: 'final'
    },
    error: {
      on: {
        RETRY: 'processing'
      }
    }
  }
});

// 状态变更服务
export class DataStateMachineService {
  private static instance: DataStateMachineService;

  static getInstance(): DataStateMachineService {
    if (!DataStateMachineService.instance) {
      DataStateMachineService.instance = new DataStateMachineService();
    }
    return DataStateMachineService.instance;
  }

  async transition(
    currentState: DataState,
    event: DataEvent,
    context: DataContext
  ): Promise<{
    newState: DataState;
    context: DataContext;
  }> {
    const actor = createActor(dataStateMachine);
    actor.start();
    
    const snapshot = actor.getSnapshot();
    const newState = this.getNextState(currentState, event);
    
    const updatedContext = {
      ...context,
      lastUpdated: new Date().toISOString(),
    };

    this.logStateChange(updatedContext, currentState, newState);
    actor.stop();

    return {
      newState,
      context: updatedContext
    };
  }

  private getNextState(currentState: DataState, event: DataEvent): DataState {
    const transitions: Record<DataState, Partial<Record<DataEvent['type'], DataState>>> = {
      raw: { VALIDATE: 'validating' },
      validating: { VALID: 'valid', INVALID: 'invalid' },
      valid: { PROCESS: 'processing' },
      invalid: { VALIDATE: 'validating' },
      processing: { PROCESS_SUCCESS: 'processed', PROCESS_ERROR: 'error' },
      processed: {},
      error: { RETRY: 'processing' }
    };
    
    return transitions[currentState]?.[event.type] || currentState;
  }

  private logStateChange(
    context: DataContext,
    fromState: DataState,
    toState: DataState
  ): void {
    console.log(`[DataStateMachine] Data ${context.dataId} transitioned from ${fromState} to ${toState}`, {
      ...context,
      fromState,
      toState,
      timestamp: new Date().toISOString()
    });
  }

  isValidTransition(fromState: DataState, event: DataEvent): boolean {
    const newState = this.getNextState(fromState, event);
    return newState !== fromState;
  }

  getAvailableEvents(state: DataState): DataEvent['type'][] {
    const events: Record<DataState, DataEvent['type'][]> = {
      raw: ['VALIDATE'],
      validating: ['VALID', 'INVALID'],
      valid: ['PROCESS'],
      invalid: ['VALIDATE'],
      processing: ['PROCESS_SUCCESS', 'PROCESS_ERROR'],
      processed: [],
      error: ['RETRY']
    };
    return events[state] || [];
  }
}
