import { describe, it, expect } from 'vitest';
import { render, screen } from '@testing-library/react';
import { GoalProgressBar } from '@/components/goals/GoalProgressBar';

describe('GoalProgressBar', () => {
  describe('progress calculation', () => {
    it('should render correct percentage', () => {
      render(<GoalProgressBar currentValue={50} targetValue={100} />);

      expect(screen.getByText('50.0%')).toBeInTheDocument();
    });

    it('should calculate percentage correctly', () => {
      render(<GoalProgressBar currentValue={75} targetValue={100} />);

      expect(screen.getByText('75.0%')).toBeInTheDocument();
    });

    it('should cap percentage at 100%', () => {
      render(<GoalProgressBar currentValue={150} targetValue={100} />);

      expect(screen.getByText('100.0%')).toBeInTheDocument();
    });

    it('should handle zero target value', () => {
      render(<GoalProgressBar currentValue={50} targetValue={0} />);

      expect(screen.getByText('0.0%')).toBeInTheDocument();
    });

    it('should handle zero current value', () => {
      render(<GoalProgressBar currentValue={0} targetValue={100} />);

      expect(screen.getByText('0.0%')).toBeInTheDocument();
    });
  });

  describe('value display', () => {
    it('should display current and target values', () => {
      render(<GoalProgressBar currentValue={50} targetValue={100} />);

      expect(screen.getByText(/50.*\/.*100/)).toBeInTheDocument();
    });

    it('should display unit when provided', () => {
      render(<GoalProgressBar currentValue={5000} targetValue={10000} unit="USD" />);

      expect(screen.getByText(/5,000.*\/.*10,000 USD/)).toBeInTheDocument();
    });

    it('should hide values when showValue is false', () => {
      render(<GoalProgressBar currentValue={50} targetValue={100} showValue={false} />);

      expect(screen.queryByText(/50.*\/.*100/)).not.toBeInTheDocument();
    });

    it('should hide percentage when showPercentage is false', () => {
      render(<GoalProgressBar currentValue={50} targetValue={100} showPercentage={false} />);

      expect(screen.queryByText('50.0%')).not.toBeInTheDocument();
    });

    it('should format large numbers with locale', () => {
      render(<GoalProgressBar currentValue={1000000} targetValue={2000000} />);

      expect(screen.getByText(/1,000,000.*\/.*2,000,000/)).toBeInTheDocument();
    });
  });

  describe('color logic', () => {
    it('should show green color when progress >= 100%', () => {
      const { container } = render(<GoalProgressBar currentValue={100} targetValue={100} />);

      const progressFill = container.querySelector('.bg-green-500');
      expect(progressFill).toBeInTheDocument();
    });

    it('should show green-400 color when progress >= 80%', () => {
      const { container } = render(<GoalProgressBar currentValue={85} targetValue={100} />);

      const progressFill = container.querySelector('.bg-green-400');
      expect(progressFill).toBeInTheDocument();
    });

    it('should show yellow color when progress >= 50%', () => {
      const { container } = render(<GoalProgressBar currentValue={60} targetValue={100} />);

      const progressFill = container.querySelector('.bg-yellow-500');
      expect(progressFill).toBeInTheDocument();
    });

    it('should show orange color when progress >= 25%', () => {
      const { container } = render(<GoalProgressBar currentValue={30} targetValue={100} />);

      const progressFill = container.querySelector('.bg-orange-500');
      expect(progressFill).toBeInTheDocument();
    });

    it('should show red color when progress < 25%', () => {
      const { container } = render(<GoalProgressBar currentValue={10} targetValue={100} />);

      const progressFill = container.querySelector('.bg-red-500');
      expect(progressFill).toBeInTheDocument();
    });
  });

  describe('size variants', () => {
    it('should render small size', () => {
      const { container } = render(
        <GoalProgressBar currentValue={50} targetValue={100} size="sm" />
      );

      const progressBar = container.querySelector('.h-2');
      expect(progressBar).toBeInTheDocument();
    });

    it('should render medium size (default)', () => {
      const { container } = render(
        <GoalProgressBar currentValue={50} targetValue={100} size="md" />
      );

      const progressBar = container.querySelector('.h-3');
      expect(progressBar).toBeInTheDocument();
    });

    it('should render large size', () => {
      const { container } = render(
        <GoalProgressBar currentValue={50} targetValue={100} size="lg" />
      );

      const progressBar = container.querySelector('.h-4');
      expect(progressBar).toBeInTheDocument();
    });
  });

  describe('milestones', () => {
    it('should render milestones when provided', () => {
      const milestones = [
        { percentage: 25 },
        { percentage: 50 },
        { percentage: 75 },
      ];

      const { container } = render(
        <GoalProgressBar
          currentValue={60}
          targetValue={100}
          milestones={milestones}
        />
      );

      // Should have milestone markers
      const milestoneMarkers = container.querySelectorAll('.rounded-full.border-2');
      expect(milestoneMarkers.length).toBeGreaterThanOrEqual(3);
    });

    it('should mark achieved milestones as green', () => {
      const milestones = [
        { percentage: 25 },
        { percentage: 50 },
        { percentage: 75 },
      ];

      const { container } = render(
        <GoalProgressBar
          currentValue={60}
          targetValue={100}
          milestones={milestones}
        />
      );

      // 25% and 50% milestones should be achieved (green)
      const achievedMilestones = container.querySelectorAll('.bg-green-500.border-green-600');
      expect(achievedMilestones.length).toBe(2);
    });

    it('should show milestone labels for large size', () => {
      const milestones = [
        { percentage: 25 },
        { percentage: 50 },
        { percentage: 75 },
      ];

      render(
        <GoalProgressBar
          currentValue={60}
          targetValue={100}
          milestones={milestones}
          size="lg"
        />
      );

      expect(screen.getByText('25%')).toBeInTheDocument();
      expect(screen.getByText('50%')).toBeInTheDocument();
      expect(screen.getByText('75%')).toBeInTheDocument();
    });

    it('should not show milestone labels for non-large sizes', () => {
      const milestones = [
        { percentage: 50 },
      ];

      render(
        <GoalProgressBar
          currentValue={60}
          targetValue={100}
          milestones={milestones}
          size="sm"
        />
      );

      // The percentage label in the stats row is different from milestone labels
      // Milestone labels are only shown for size="lg"
      const allText = screen.queryAllByText('50%');
      // Should not have additional milestone label for small size
      expect(allText.length).toBe(0);
    });
  });

  describe('custom className', () => {
    it('should apply custom className', () => {
      const { container } = render(
        <GoalProgressBar
          currentValue={50}
          targetValue={100}
          className="my-custom-class"
        />
      );

      const wrapper = container.firstChild;
      expect(wrapper).toHaveClass('my-custom-class');
    });
  });

  describe('edge cases', () => {
    it('should handle decimal values', () => {
      render(<GoalProgressBar currentValue={33.33} targetValue={100} />);

      expect(screen.getByText('33.3%')).toBeInTheDocument();
    });

    it('should handle very small progress', () => {
      render(<GoalProgressBar currentValue={1} targetValue={1000} />);

      expect(screen.getByText('0.1%')).toBeInTheDocument();
    });

    it('should handle exact boundary at 80%', () => {
      const { container } = render(<GoalProgressBar currentValue={80} targetValue={100} />);

      const progressFill = container.querySelector('.bg-green-400');
      expect(progressFill).toBeInTheDocument();
    });

    it('should handle exact boundary at 50%', () => {
      const { container } = render(<GoalProgressBar currentValue={50} targetValue={100} />);

      const progressFill = container.querySelector('.bg-yellow-500');
      expect(progressFill).toBeInTheDocument();
    });

    it('should handle exact boundary at 25%', () => {
      const { container } = render(<GoalProgressBar currentValue={25} targetValue={100} />);

      const progressFill = container.querySelector('.bg-orange-500');
      expect(progressFill).toBeInTheDocument();
    });
  });
});
