import { describe, it, expect } from 'vitest';
import { CheckoutState, CheckoutStateEnum } from './CheckoutState';


/**
 * CheckoutState Value Object - GREEN PHASE
 *
 * Tests for checkout button state detection.
 */

describe('CheckoutState Value Object', () => {
  describe('READY state', () => {
    it('should create READY state from btn-success class', () => {
      const state = CheckoutState.fromButtonClasses('btn btn-success');
      expect(state.getValue()).toBe(CheckoutStateEnum.READY);
    });

    it('should detect ready state correctly', () => {
      const state = CheckoutState.fromButtonClasses('btn btn-success');
      expect(state.isReady()).toBe(true);
      expect(state.hasInsufficientFunds()).toBe(false);
    });

    it('should handle additional classes with btn-success', () => {
      const state = CheckoutState.fromButtonClasses('btn btn-lg btn-success pull-right');
      expect(state.getValue()).toBe(CheckoutStateEnum.READY);
    });

    it('should be case-insensitive for btn-success', () => {
      const state = CheckoutState.fromButtonClasses('btn BTN-SUCCESS');
      expect(state.getValue()).toBe(CheckoutStateEnum.READY);
    });
  });

  describe('INSUFFICIENT_FUNDS state', () => {
    it('should create INSUFFICIENT_FUNDS from btn-default without btn-success', () => {
      const state = CheckoutState.fromButtonClasses('btn btn-default');
      expect(state.getValue()).toBe(CheckoutStateEnum.INSUFFICIENT_FUNDS);
    });

    it('should detect insufficient funds correctly', () => {
      const state = CheckoutState.fromButtonClasses('btn btn-default');
      expect(state.isReady()).toBe(false);
      expect(state.hasInsufficientFunds()).toBe(true);
    });

    it('should handle btn-primary as insufficient funds', () => {
      const state = CheckoutState.fromButtonClasses('btn btn-primary');
      expect(state.getValue()).toBe(CheckoutStateEnum.INSUFFICIENT_FUNDS);
    });

    it('should handle btn-warning as insufficient funds', () => {
      const state = CheckoutState.fromButtonClasses('btn btn-warning');
      expect(state.getValue()).toBe(CheckoutStateEnum.INSUFFICIENT_FUNDS);
    });

    it('should handle disabled button as insufficient funds', () => {
      const state = CheckoutState.fromButtonClasses('btn btn-default disabled');
      expect(state.getValue()).toBe(CheckoutStateEnum.INSUFFICIENT_FUNDS);
    });
  });

  describe('UNKNOWN state', () => {
    it('should create UNKNOWN when no btn class exists', () => {
      const state = CheckoutState.fromButtonClasses('some-other-class');
      expect(state.getValue()).toBe(CheckoutStateEnum.UNKNOWN);
    });

    it('should create UNKNOWN from empty string', () => {
      const state = CheckoutState.fromButtonClasses('');
      expect(state.getValue()).toBe(CheckoutStateEnum.UNKNOWN);
    });

    it('should detect unknown state correctly', () => {
      const state = CheckoutState.fromButtonClasses('');
      expect(state.isReady()).toBe(false);
      expect(state.hasInsufficientFunds()).toBe(false);
    });
  });

  describe('Edge Cases', () => {
    it('should handle whitespace in class names', () => {
      const state = CheckoutState.fromButtonClasses('  btn   btn-success  ');
      expect(state.getValue()).toBe(CheckoutStateEnum.READY);
    });

    it('should handle multiple spaces between classes', () => {
      const state = CheckoutState.fromButtonClasses('btn    btn-success');
      expect(state.getValue()).toBe(CheckoutStateEnum.READY);
    });

    it('should be immutable after creation', () => {
      const state = CheckoutState.fromButtonClasses('btn btn-success');
      const originalState = state.getValue();
      expect(originalState).toBe(CheckoutStateEnum.READY);
      // Verify no setters exist
      const mutableState = state as unknown as { setState?: unknown };
      expect(typeof mutableState.setState).toBe('undefined');
    });
  });

  describe('BDD Scenarios', () => {
    it('Given button with btn-success, When checking state, Then state is READY', () => {
      const state = CheckoutState.fromButtonClasses('btn btn-success');
      expect(state.getValue()).toBe(CheckoutStateEnum.READY);
    });

    it('Given button without btn-success, When checking state, Then state is INSUFFICIENT_FUNDS', () => {
      const state = CheckoutState.fromButtonClasses('btn btn-default');
      expect(state.getValue()).toBe(CheckoutStateEnum.INSUFFICIENT_FUNDS);
    });

    it('Given no button classes, When checking state, Then state is UNKNOWN', () => {
      const state = CheckoutState.fromButtonClasses('');
      expect(state.getValue()).toBe(CheckoutStateEnum.UNKNOWN);
    });

    it('Given READY state, When checking isReady, Then returns true', () => {
      const state = CheckoutState.fromButtonClasses('btn btn-success');
      expect(state.isReady()).toBe(true);
    });

    it('Given INSUFFICIENT_FUNDS state, When checking hasInsufficientFunds, Then returns true', () => {
      const state = CheckoutState.fromButtonClasses('btn btn-default');
      expect(state.hasInsufficientFunds()).toBe(true);
    });
  });
});