import { useMemo } from 'react';

import { ArrowDown } from 'lucide-react';

import { cn } from '@kit/ui/utils';

import { AnalysisResultForDisplay } from './analysis-doctor';

export enum AnalysisResultLevel {
  NORMAL = 'NORMAL',
  WARNING = 'WARNING',
  CRITICAL = 'CRITICAL',
}

const Level = ({
  isActive = false,
  color,
  isFirst = false,
  isLast = false,
  arrowLocation,
  normRangeText,
}: {
  isActive?: boolean;
  color: 'destructive' | 'success' | 'warning' | 'gray-200';
  isFirst?: boolean;
  isLast?: boolean;
  arrowLocation?: number;
  normRangeText?: string | null;
}) => {
  return (
    <div
      className={cn(`bg-${color} relative h-3 flex-1`, {
        'opacity-60': !isActive,
        'rounded-l-lg': isFirst,
        'rounded-r-lg': isLast,
      })}
    >
      {isActive && (
        <div
          className="absolute top-[-14px] left-1/2 -translate-x-1/2 rounded-[10px] bg-white p-[2px]"
          {...(arrowLocation
            ? {
                style: {
                  left: `${arrowLocation}%`,
                  ...(arrowLocation > 92.5 && { left: '92.5%' }),
                  ...(arrowLocation < 7.5 && { left: '7.5%' }),
                },
              }
            : {})}
        >
          <ArrowDown strokeWidth={2} />
        </div>
      )}

      {color === 'success' && typeof normRangeText === 'string' && (
        <p
          className={cn(
            'text-muted-foreground absolute bottom-[-18px] left-3/8 text-xs font-bold whitespace-nowrap',
            {
              'opacity-60': isActive,
            },
          )}
        >
          {normRangeText}
        </p>
      )}
    </div>
  );
};

export const AnalysisLevelBarSkeleton = () => {
  return (
    <div className="mt-4 flex h-3 w-[60%] max-w-[360px] gap-1 sm:mt-0 sm:w-[35%]">
      <Level color="gray-200" isFirst isLast />
    </div>
  );
};

const AnalysisLevelBar = ({
  level,
  results,
  normRangeText,
}: {
  level: AnalysisResultLevel | null;
  results: AnalysisResultForDisplay;
  normRangeText: string | null;
}) => {
  const {
    norm_lower: lower,
    norm_upper: upper,
    response_value: value,
  } = results;

  // Calculate arrow position based on value within normal range
  const arrowLocation = useMemo(() => {
    // If no response value, center the arrow
    if (value === null || value === undefined) {
      return 50;
    }

    // If no normal ranges defined, center the arrow
    if (lower === null && upper === null) {
      return 50;
    }

    // If only upper bound exists
    if (lower === null && upper !== null) {
      if (value <= upper!) {
        return Math.min(75, (value / upper!) * 75); // Show in left 75% of normal range
      }
      return 100; // Beyond upper bound
    }

    // If only lower bound exists
    if (upper === null && lower !== null) {
      if (value >= lower!) {
        // Value is in normal range (above lower bound)
        // Position proportionally in the normal range section
        const normalizedPosition = Math.min(
          (value - lower!) / (lower! * 0.5),
          1,
        ); // Use 50% of lower as scale
        return normalizedPosition * 100;
      }
      // Value is below lower bound - position in the "below normal" section
      const belowPosition = Math.max(0, Math.min(1, value / lower!));
      return belowPosition * 100;
    }

    // Both bounds exist
    if (lower !== null && upper !== null) {
      if (value < lower!) {
        return 0; // Below normal range
      }
      if (value > upper!) {
        return 100; // Above normal range
      }
      // Within normal range
      return ((value - lower!) / (upper! - lower!)) * 100;
    }

    return 50; // Fallback
  }, [value, upper, lower]);

  // Determine level states based on normStatus
  const isNormal = level === AnalysisResultLevel.NORMAL;
  const isWarning = level === AnalysisResultLevel.WARNING;
  const isCritical = level === AnalysisResultLevel.CRITICAL;
  const isPending = level === null;

  // Show appropriate levels based on available norm bounds
  const hasLowerBound = lower !== null;

  // Calculate level configuration (must be called before any returns)
  const [first, second, third] = useMemo(() => {
    const [warning, normal, critical] = [
      {
        isActive: isWarning,
        color: 'warning',
        ...(isWarning ? { arrowLocation } : {}),
      },
      {
        isActive: isNormal,
        color: 'success',
        normRangeText,
        ...(isNormal ? { arrowLocation } : {}),
      },
      {
        isActive: isCritical,
        color: 'destructive',
        isLast: true,
        ...(isCritical ? { arrowLocation } : {}),
      },
    ] as const;

    if (!hasLowerBound) {
      return [{ ...normal, isFirst: true }, warning, critical] as const;
    }

    return [
      { ...warning, isFirst: true },
      normal,
      { ...critical, isLast: true },
    ] as const;
  }, [
    arrowLocation,
    normRangeText,
    isNormal,
    isWarning,
    isCritical,
    hasLowerBound,
  ]);

  // If pending results, show gray bar
  if (isPending) {
    return (
      <div className="w-60% mt-4 flex h-3 max-w-[360px] gap-1 sm:mt-0 sm:w-[35%]">
        <Level color="gray-200" isFirst isLast />
      </div>
    );
  }

  return (
    <div
      className={cn(
        'flex h-3 gap-1',
        'mt-4 sm:mt-0',
        'w-[60%] sm:w-[35%]',
        'min-w-[50vw] sm:min-w-auto',
        'max-w-[360px]',
      )}
    >
      <Level {...first} />
      <Level {...second} />
      <Level {...third} />
    </div>
  );
};

export default AnalysisLevelBar;
