import { AdminTrustReasonCode } from './AdminTrustReasonCode';
import { IdentityDomainValidationError } from '../errors/IdentityDomainError';

describe('AdminTrustReasonCode', () => {
  describe('create', () => {
    it('should create valid reason codes', () => {
      const validCodes = [
        'ADMIN_VOTE_OUTCOME_POSITIVE',
        'ADMIN_VOTE_OUTCOME_NEGATIVE',
        'ADMIN_ACTION_SLA_BONUS',
        'ADMIN_ACTION_REVERSAL_PENALTY',
        'ADMIN_ACTION_RULE_CLARITY_BONUS',
        'ADMIN_ACTION_ABUSE_REPORT_PENALTY',
      ];

      validCodes.forEach(code => {
        const reasonCode = AdminTrustReasonCode.create(code);
        expect(reasonCode.value).toBe(code);
      });
    });

    it('should throw error for empty string', () => {
      expect(() => AdminTrustReasonCode.create('')).toThrow(IdentityDomainValidationError);
      expect(() => AdminTrustReasonCode.create('   ')).toThrow(IdentityDomainValidationError);
    });

    it('should throw error for invalid reason code', () => {
      expect(() => AdminTrustReasonCode.create('INVALID_CODE')).toThrow(IdentityDomainValidationError);
      expect(() => AdminTrustReasonCode.create('admin_vote')).toThrow(IdentityDomainValidationError);
    });

    it('should trim whitespace from valid codes', () => {
      const reasonCode = AdminTrustReasonCode.create('  ADMIN_VOTE_OUTCOME_POSITIVE  ');
      expect(reasonCode.value).toBe('ADMIN_VOTE_OUTCOME_POSITIVE');
    });
  });

  describe('fromValue', () => {
    it('should create from value without validation', () => {
      const reasonCode = AdminTrustReasonCode.fromValue('ADMIN_VOTE_OUTCOME_POSITIVE');
      expect(reasonCode.value).toBe('ADMIN_VOTE_OUTCOME_POSITIVE');
    });
  });

  describe('equals', () => {
    it('should return true for equal codes', () => {
      const code1 = AdminTrustReasonCode.create('ADMIN_VOTE_OUTCOME_POSITIVE');
      const code2 = AdminTrustReasonCode.create('ADMIN_VOTE_OUTCOME_POSITIVE');
      expect(code1.equals(code2)).toBe(true);
    });

    it('should return false for different codes', () => {
      const code1 = AdminTrustReasonCode.create('ADMIN_VOTE_OUTCOME_POSITIVE');
      const code2 = AdminTrustReasonCode.create('ADMIN_VOTE_OUTCOME_NEGATIVE');
      expect(code1.equals(code2)).toBe(false);
    });
  });

  describe('toString', () => {
    it('should return the string value', () => {
      const code = AdminTrustReasonCode.create('ADMIN_VOTE_OUTCOME_POSITIVE');
      expect(code.toString()).toBe('ADMIN_VOTE_OUTCOME_POSITIVE');
    });
  });

  describe('category methods', () => {
    describe('isVoteOutcome', () => {
      it('should return true for vote outcome codes', () => {
        const voteCodes = [
          'ADMIN_VOTE_OUTCOME_POSITIVE',
          'ADMIN_VOTE_OUTCOME_NEGATIVE',
        ];
        voteCodes.forEach(codeStr => {
          const code = AdminTrustReasonCode.fromValue(codeStr as any);
          expect(code.isVoteOutcome()).toBe(true);
        });
      });

      it('should return false for non-vote outcome codes', () => {
        const nonVoteCodes = [
          'ADMIN_ACTION_SLA_BONUS',
          'ADMIN_ACTION_REVERSAL_PENALTY',
        ];
        nonVoteCodes.forEach(codeStr => {
          const code = AdminTrustReasonCode.fromValue(codeStr as any);
          expect(code.isVoteOutcome()).toBe(false);
        });
      });
    });

    describe('isSystemSignal', () => {
      it('should return true for system signal codes', () => {
        const systemCodes = [
          'ADMIN_ACTION_SLA_BONUS',
          'ADMIN_ACTION_REVERSAL_PENALTY',
          'ADMIN_ACTION_RULE_CLARITY_BONUS',
          'ADMIN_ACTION_ABUSE_REPORT_PENALTY',
        ];
        systemCodes.forEach(codeStr => {
          const code = AdminTrustReasonCode.fromValue(codeStr as any);
          expect(code.isSystemSignal()).toBe(true);
        });
      });

      it('should return false for non-system signal codes', () => {
        const nonSystemCodes = [
          'ADMIN_VOTE_OUTCOME_POSITIVE',
          'ADMIN_VOTE_OUTCOME_NEGATIVE',
        ];
        nonSystemCodes.forEach(codeStr => {
          const code = AdminTrustReasonCode.fromValue(codeStr as any);
          expect(code.isSystemSignal()).toBe(false);
        });
      });
    });

    describe('isPositive', () => {
      it('should return true for positive impact codes', () => {
        const positiveCodes = [
          'ADMIN_VOTE_OUTCOME_POSITIVE',
          'ADMIN_ACTION_SLA_BONUS',
          'ADMIN_ACTION_RULE_CLARITY_BONUS',
        ];
        positiveCodes.forEach(codeStr => {
          const code = AdminTrustReasonCode.fromValue(codeStr as any);
          expect(code.isPositive()).toBe(true);
        });
      });

      it('should return false for non-positive codes', () => {
        const nonPositiveCodes = [
          'ADMIN_VOTE_OUTCOME_NEGATIVE',
          'ADMIN_ACTION_REVERSAL_PENALTY',
          'ADMIN_ACTION_ABUSE_REPORT_PENALTY',
        ];
        nonPositiveCodes.forEach(codeStr => {
          const code = AdminTrustReasonCode.fromValue(codeStr as any);
          expect(code.isPositive()).toBe(false);
        });
      });
    });

    describe('isNegative', () => {
      it('should return true for negative impact codes', () => {
        const negativeCodes = [
          'ADMIN_VOTE_OUTCOME_NEGATIVE',
          'ADMIN_ACTION_REVERSAL_PENALTY',
          'ADMIN_ACTION_ABUSE_REPORT_PENALTY',
        ];
        negativeCodes.forEach(codeStr => {
          const code = AdminTrustReasonCode.fromValue(codeStr as any);
          expect(code.isNegative()).toBe(true);
        });
      });

      it('should return false for non-negative codes', () => {
        const nonNegativeCodes = [
          'ADMIN_VOTE_OUTCOME_POSITIVE',
          'ADMIN_ACTION_SLA_BONUS',
          'ADMIN_ACTION_RULE_CLARITY_BONUS',
        ];
        nonNegativeCodes.forEach(codeStr => {
          const code = AdminTrustReasonCode.fromValue(codeStr as any);
          expect(code.isNegative()).toBe(false);
        });
      });
    });
  });
});
