import React from 'react';
import { Link } from 'react-router-dom';

import type { ISetupProgress } from '../../service/setup-progress/setup-progress.interface';
import type { StepperStep } from '../../service/setup-progress/setup-progress.constants';

import InfoTooltip from './InfoTooltip';

interface SetupProgressStepperProps {
  progress: ISetupProgress | null;
  steps: ReadonlyArray<StepperStep>;
  estimatedMinutesLeft?: number;
}

/**
 * Horizontal stepper rendered on the Dashboard. A step is "effectively
 * complete" only when itself and every earlier step is marked done in
 * setup_progress, so out-of-order completions don't paint later steps
 * green prematurely.
 *
 * @param {SetupProgressStepperProps} props
 * @return {React.ReactElement}
 */
export function SetupProgressStepper({
  progress,
  steps,
  estimatedMinutesLeft,
}: SetupProgressStepperProps) {
  let priorComplete: boolean = true;
  const effectivelyComplete: boolean[] = steps.map(stepDefinition => {
    const stored: boolean =
      progress?.steps?.[stepDefinition.key]?.completed ?? false;
    const isDone: boolean = priorComplete && stored;
    priorComplete = isDone;

    return isDone;
  });

  const completedCount: number = effectivelyComplete.filter(Boolean).length;
  const totalCount: number = steps.length;
  const currentIndex: number = effectivelyComplete.findIndex(done => !done);
  const nextStep: StepperStep | null =
    currentIndex >= 0 ? steps[currentIndex] : null;

  return (
    <div className="rounded-2xl border border-gray-200 bg-white p-5">
      <div className="flex items-start justify-between gap-3">
        <div>
          <h3 className="text-base font-bold text-gray-900">Setup progress</h3>
          <p className="mt-1 text-xs text-gray-500">
            {completedCount} of {totalCount} complete
            {typeof estimatedMinutesLeft === 'number' &&
            estimatedMinutesLeft > 0
              ? ` · ~${estimatedMinutesLeft} min left`
              : ''}
          </p>
        </div>
        {nextStep && (
          <Link
            to={nextStep.to}
            className="inline-flex h-8 cursor-pointer items-center justify-center rounded-full bg-[#B7007C] px-4 text-xs font-semibold text-white shadow-sm transition-colors hover:bg-[#900063]"
          >
            Continue setup →
          </Link>
        )}
      </div>
      <ol className="mt-5 flex flex-wrap items-start gap-y-4 gap-x-2 pb-1">
        {steps.map((stepDefinition, stepIndex) => {
          const done: boolean = effectivelyComplete[stepIndex];
          const isCurrent: boolean = stepIndex === currentIndex;
          const leftConnectorDone: boolean =
            stepIndex > 0 && effectivelyComplete[stepIndex - 1];
          const rightConnectorDone: boolean = done;

          return (
            <li
              key={stepDefinition.key}
              className="flex min-w-[120px] flex-1 flex-col items-center text-center"
            >
              <div className="flex w-full items-center">
                <div
                  className={`h-px flex-1 ${stepIndex === 0 ? 'opacity-0' : leftConnectorDone ? 'bg-emerald-500' : 'bg-gray-200'}`}
                />
                <Link
                  to={stepDefinition.to}
                  className={[
                    'flex h-10 w-10 shrink-0 cursor-pointer items-center justify-center rounded-full border-2 transition-all',
                    done
                      ? 'border-emerald-500 bg-emerald-50 text-emerald-600'
                      : isCurrent
                        ? 'border-[#B7007C] bg-[#ffeef8] text-[#B7007C]'
                        : 'border-gray-200 bg-white text-gray-400',
                  ].join(' ')}
                  aria-label={stepDefinition.label}
                >
                  {done ? (
                    <svg
                      className="h-4 w-4"
                      viewBox="0 0 24 24"
                      fill="none"
                      stroke="currentColor"
                      strokeWidth={3}
                    >
                      <path
                        d="M5 12l5 5L20 7"
                        strokeLinecap="round"
                        strokeLinejoin="round"
                      />
                    </svg>
                  ) : (
                    <span className="text-sm font-semibold">
                      {stepIndex + 1}
                    </span>
                  )}
                </Link>
                <div
                  className={`h-px flex-1 ${stepIndex === steps.length - 1 ? 'opacity-0' : rightConnectorDone ? 'bg-emerald-500' : 'bg-gray-200'}`}
                />
              </div>
              <div className="mt-2 inline-flex items-center gap-1.5">
                <Link
                  to={stepDefinition.to}
                  className={[
                    'cursor-pointer text-xs transition-colors',
                    isCurrent ? 'font-semibold text-gray-900' : 'text-gray-500',
                    'hover:text-[#B7007C]',
                  ].join(' ')}
                >
                  {stepDefinition.label}
                </Link>
                {stepDefinition.tooltip && (
                  <InfoTooltip text={stepDefinition.tooltip} />
                )}
              </div>
            </li>
          );
        })}
      </ol>
    </div>
  );
}
