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

import InfoTooltip from './InfoTooltip';

export type ScoreAction =
  | {
      kind: 'link';
      label: string;
      to: string;
      primary?: boolean;
    }
  | {
      kind: 'button';
      label: string;
      onClick: () => Promise<void> | void;
      busyLabel?: string;
      primary?: boolean;
    };

export interface ScoreRow {
  label: string;
  tag?: string;
  score: number;
  delta?: number;
  context?: string;
  tooltip?: string;
  action: ScoreAction;
}

interface ScoreBreakdownProps {
  rows: ScoreRow[];
}

interface BandTheme {
  bar: string;
  numberText: string;
  deltaBg: string;
  deltaText: string;
}

const bandTheme = (score: number): BandTheme => {
  if (score >= 80)
    return {
      bar: 'bg-emerald-500',
      numberText: 'text-emerald-600',
      deltaBg: 'bg-emerald-50',
      deltaText: 'text-emerald-700',
    };
  if (score >= 65)
    return {
      bar: 'bg-lime-500',
      numberText: 'text-lime-600',
      deltaBg: 'bg-emerald-50',
      deltaText: 'text-emerald-700',
    };
  if (score >= 50)
    return {
      bar: 'bg-amber-400',
      numberText: 'text-amber-600',
      deltaBg: 'bg-emerald-50',
      deltaText: 'text-emerald-700',
    };
  if (score >= 35)
    return {
      bar: 'bg-orange-500',
      numberText: 'text-orange-600',
      deltaBg: 'bg-emerald-50',
      deltaText: 'text-emerald-700',
    };

  return {
    bar: 'bg-red-500',
    numberText: 'text-red-600',
    deltaBg: 'bg-red-50',
    deltaText: 'text-red-600',
  };
};

export function ScoreBreakdown({ rows }: ScoreBreakdownProps) {
  return (
    <div className="space-y-3">
      {rows.map(row => (
        <ScoreBreakdownRow key={row.label} row={row} />
      ))}
    </div>
  );
}

function ScoreBreakdownRow({ row }: { row: ScoreRow }) {
  const theme: BandTheme = bandTheme(row.score);
  const clamped: number = Math.max(0, Math.min(100, Math.round(row.score)));
  const deltaPositive: boolean = (row.delta ?? 0) >= 0;

  return (
    <div className="rounded-2xl border border-gray-200 bg-white p-4 transition-all hover:border-[#B7007C]/30 hover:shadow-sm">
      <div className="flex items-start justify-between gap-3">
        <div className="flex items-center gap-2">
          <span className="text-sm font-semibold text-gray-900">
            {row.label}
          </span>
          {row.tag && (
            <span className="rounded-md bg-gray-100 px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-wider text-gray-600">
              {row.tag}
            </span>
          )}
          {row.tooltip && <InfoTooltip text={row.tooltip} />}
        </div>
        <div className="flex items-baseline gap-1.5">
          <span
            className={`text-3xl font-bold tabular-nums ${theme.numberText}`}
          >
            {clamped}
          </span>
          <span className="text-xs text-gray-500">/100</span>
          {typeof row.delta === 'number' && row.delta !== 0 && (
            <span
              className={`ml-1 inline-flex items-center rounded-md px-1.5 py-0.5 text-[10px] font-semibold ${
                deltaPositive
                  ? `${theme.deltaBg} ${theme.deltaText}`
                  : 'bg-red-50 text-red-600'
              }`}
            >
              {deltaPositive ? '↑' : '↓'}
              {Math.abs(row.delta)}
            </span>
          )}
        </div>
      </div>
      <div className="mt-3 h-1.5 w-full overflow-hidden rounded-full bg-gray-100">
        <div
          className={`h-full rounded-full transition-all duration-500 ${theme.bar}`}
          style={{ width: `${clamped}%` }}
        />
      </div>
      <div className="mt-3 flex items-end justify-between gap-3">
        <p className="text-xs leading-relaxed text-gray-500">
          {row.context ?? ' '}
        </p>
        <ScoreActionButton action={row.action} />
      </div>
    </div>
  );
}

function ScoreActionButton({ action }: { action: ScoreAction }) {
  const [busy, setBusy] = useState<boolean>(false);
  const className: string =
    'shrink-0 cursor-pointer text-xs font-semibold text-[#B7007C] hover:text-[#900063] transition-colors';

  if (action.kind === 'link') {
    return (
      <Link to={action.to} className={className}>
        {action.label} →
      </Link>
    );
  }

  const label: string =
    busy && action.busyLabel ? action.busyLabel : action.label;
  const handleClick = async (): Promise<void> => {
    if (busy) return;
    setBusy(true);
    try {
      await action.onClick();
    } finally {
      setBusy(false);
    }
  };

  return (
    <button
      type="button"
      onClick={handleClick}
      disabled={busy}
      className={`${className} disabled:cursor-not-allowed disabled:opacity-60`}
    >
      {label} →
    </button>
  );
}
