// ---------------------------------------------------------------------------
// JSON Scenario — полная типизация
// ---------------------------------------------------------------------------

export interface BotScenario {
  id: string;
  version: number;
  name: string;
  startNodeId: string;
  /** Variables available in the scenario with defaults */
  variables: Record<string, ScenarioVariable>;
  /** All nodes keyed by node ID */
  nodes: Record<string, ScenarioNode>;
}

export interface ScenarioVariable {
  type: 'string' | 'number' | 'boolean';
  default: string | number | boolean;
}

// ---------------------------------------------------------------------------
// Node types
// ---------------------------------------------------------------------------

export type ScenarioNode =
  | MessageNode
  | ConditionNode
  | ActionNode
  | InputNode
  | DelayNode
  | ReferralNode;

export type ScenarioNodeType = 'message' | 'condition' | 'action' | 'input' | 'delay' | 'referral';

interface BaseNode {
  id: string;
  type: ScenarioNodeType;
  next?: string | null;
}

// --- Message Node ---

export interface MessageNode extends BaseNode {
  type: 'message';
  data: {
    text: string;
    image?: string | null;
    buttons?: MessageButton[];
    buttonsLayout?: 'inline' | 'reply' | 'remove';
  };
}

export interface MessageButton {
  text: string;
  action: 'goto' | 'url' | 'share_contact';
  target?: string; // nodeId for goto, URL for url
  callbackData?: string; // auto-generated if not set
}

// --- Condition Node ---

export interface ConditionNode extends BaseNode {
  type: 'condition';
  data: {
    rules: ConditionRule[];
    default?: string | null; // fallback nodeId
  };
}

export interface ConditionRule {
  /** Expression like "invited_count >= 2", "selected_club == 'gym1'" */
  condition: string;
  target: string; // nodeId
}

// --- Action Node ---

export interface ActionNode extends BaseNode {
  type: 'action';
  data: {
    actions: ActionItem[];
  };
}

export type ActionItem =
  | SetVariableAction
  | WebhookAction
  | CrmDealAction
  | GrantBonusAction
  | SetConsentAction;

export interface SetVariableAction {
  type: 'set_variable';
  variable: string;
  value: string | number | boolean;
}

export interface WebhookAction {
  type: 'webhook';
  url: string;
  method?: 'POST' | 'GET';
  body?: Record<string, unknown>;
  headers?: Record<string, string>;
}

export interface CrmDealAction {
  type: 'crm_deal';
  pipeline?: string;
  fields: Record<string, string>;
}

export interface GrantBonusAction {
  type: 'grant_bonus';
}

export interface SetConsentAction {
  type: 'set_consent';
  mailingConsent: boolean;
}

// --- Input Node ---

export interface InputNode extends BaseNode {
  type: 'input';
  data: {
    prompt: string;
    inputType: 'text' | 'phone' | 'email' | 'choice';
    saveAs: string; // variable name
    requestContact?: boolean; // Telegram "share contact" button
    validation?: string; // regex pattern
    errorMessage?: string;
    choices?: Array<{ text: string; value: string }>;
  };
}

// --- Delay Node ---

export interface DelayNode extends BaseNode {
  type: 'delay';
  data: {
    duration: string; // "10m", "1h", "24h", "3d"
    cancelOn?: string; // condition expression
    message?: {
      text: string;
      buttons?: MessageButton[];
    };
  };
}

// --- Referral Node ---

export interface ReferralNode extends BaseNode {
  type: 'referral';
  data: {
    generateLink: boolean;
    trackVariable: string; // variable to track count
    targetCount: number;
    onReach: string; // nodeId when target reached
    friendStartNode: string; // nodeId where friend starts
  };
}

// ---------------------------------------------------------------------------
// Engine context — runtime state passed through execution
// ---------------------------------------------------------------------------

export interface EngineContext {
  botId: string;
  botToken: string;
  botUsername: string;
  clubId: string;
  subscriberId: string;
  chatId: string;
  /** Current session variables */
  variables: Record<string, string | number | boolean>;
  /** The scenario being executed */
  scenario: BotScenario;
}
