import { CheckCircle2, XCircle, type LucideIcon } from 'lucide-react'
import { toast } from 'sonner'

type ProgressToastStatus = 'running' | 'paused' | 'stopped' | 'success' | 'warning' | 'error'

type ProgressToastInput = {
  id: string
  title: string
  description?: string
  current: number
  total: number
  status?: ProgressToastStatus
  statusLabel?: string
  error?: string
  icon: LucideIcon
  duration?: number
  actionLabel?: string
  actionDisabled?: boolean
  onAction?: () => void
  secondaryActionLabel?: string
  secondaryActionDisabled?: boolean
  onSecondaryAction?: () => void
}

function getProgressPercent(current: number, total: number): number {
  if (total <= 0) {
    return 0
  }

  return Math.min(Math.max((current / total) * 100, current > 0 ? 6 : 0), 100)
}

function renderProgressToastContent(input: ProgressToastInput): React.JSX.Element {
  const {
    title,
    description,
    current,
    total,
    status = 'running',
    statusLabel,
    error,
    icon: Icon,
    actionLabel,
    actionDisabled,
    onAction,
    secondaryActionLabel,
    secondaryActionDisabled,
    onSecondaryAction
  } = input
  const percent = getProgressPercent(current, total)
  const isError = status === 'error'
  const isPaused = status === 'paused'
  const isStopped = status === 'stopped'
  const isSuccess = status === 'success'
  const StatusIcon = isSuccess ? CheckCircle2 : isError ? XCircle : null

  const headerClassName =
    isSuccess || (isError && !description && !error)
      ? 'grid grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-3'
      : 'grid grid-cols-[auto_minmax(0,1fr)_auto] items-start gap-3'

  return (
    <div className="w-[360px] max-w-[calc(100vw-2rem)] rounded-md border bg-popover p-4 text-popover-foreground shadow-lg">
      <div className={headerClassName}>
        <div
          className={
            isSuccess
              ? 'grid size-8 shrink-0 place-items-center rounded-md bg-emerald-100 text-emerald-700'
              : isError
                ? 'grid size-8 shrink-0 place-items-center rounded-md bg-destructive/10 text-destructive'
                : isPaused
                  ? 'grid size-9 shrink-0 place-items-center rounded-md bg-amber-100 text-amber-700'
                  : isStopped
                    ? 'grid size-9 shrink-0 place-items-center rounded-md bg-slate-100 text-slate-700'
                    : 'grid size-9 shrink-0 place-items-center rounded-md bg-primary/10 text-primary'
          }
        >
          {StatusIcon ? <StatusIcon className="size-4" /> : <Icon className="size-4" />}
        </div>
        <div className="min-w-0">
          <p className="truncate text-sm font-medium">{title}</p>
          {description ? (
            <p className="mt-1 truncate text-xs text-muted-foreground">{description}</p>
          ) : null}
        </div>
        <span
          className={
            isSuccess
              ? 'rounded-md bg-emerald-100 px-2 py-1 text-xs font-medium text-emerald-700'
              : isError
                ? 'rounded-md bg-destructive/10 px-2 py-1 text-xs font-medium text-destructive'
                : isPaused
                  ? 'rounded-md bg-amber-100 px-2 py-1 text-xs font-medium text-amber-700'
                  : isStopped
                    ? 'rounded-md bg-slate-100 px-2 py-1 text-xs font-medium text-slate-700'
                    : 'rounded-md bg-amber-100 px-2 py-1 text-xs font-medium text-amber-700'
          }
        >
          {statusLabel ??
            (isSuccess
              ? '已完成'
              : isError
                ? '本项失败'
                : isPaused
                  ? '已暂停'
                  : isStopped
                    ? '已停止'
                    : '处理中')}
        </span>
      </div>
      {isSuccess ? null : (
        <>
          <div className="mt-3 h-2 overflow-hidden rounded-full bg-muted">
            <div
              className={
                isError
                  ? 'h-full rounded-full bg-destructive transition-all'
                  : isPaused
                    ? 'h-full rounded-full bg-amber-500 transition-all'
                    : isStopped
                      ? 'h-full rounded-full bg-slate-500 transition-all'
                      : 'h-full rounded-full bg-primary transition-all'
              }
              style={{ width: `${percent}%` }}
            />
          </div>
          <div className="mt-2 flex items-center justify-between gap-3 text-xs text-muted-foreground">
            <span>
              {current}/{Math.max(total, 0)}
            </span>
            <div className="flex items-center gap-2">
              <span>{Math.round(percent)}%</span>
              {actionLabel && onAction ? (
                <button
                  className="rounded-md border border-input bg-background px-2 py-1 text-xs font-medium text-foreground transition hover:bg-muted disabled:cursor-not-allowed disabled:opacity-60"
                  disabled={actionDisabled}
                  type="button"
                  onClick={onAction}
                >
                  {actionLabel}
                </button>
              ) : null}
              {secondaryActionLabel && onSecondaryAction ? (
                <button
                  className="rounded-md border border-destructive/30 bg-background px-2 py-1 text-xs font-medium text-destructive transition hover:bg-destructive/10 disabled:cursor-not-allowed disabled:opacity-60"
                  disabled={secondaryActionDisabled}
                  type="button"
                  onClick={onSecondaryAction}
                >
                  {secondaryActionLabel}
                </button>
              ) : null}
            </div>
          </div>
        </>
      )}
      {error ? <p className="mt-2 line-clamp-2 text-xs text-destructive">{error}</p> : null}
    </div>
  )
}

export function showProgressToast(input: ProgressToastInput): void {
  toast.custom(() => renderProgressToastContent(input), {
    id: input.id,
    duration: input.duration ?? Infinity,
    unstyled: true
  })
}

export function showProgressSuccess(id: string, title: string, description?: string): void {
  toast.custom(
    () =>
      renderProgressToastContent({
        id,
        icon: CheckCircle2,
        title,
        description,
        current: 1,
        total: 1,
        status: 'success',
        statusLabel: '已完成'
      }),
    {
      id,
      duration: 4000,
      unstyled: true
    }
  )
}

export function showProgressError(id: string, title: string, description?: string): void {
  toast.custom(
    () =>
      renderProgressToastContent({
        id,
        icon: XCircle,
        title,
        description,
        current: 1,
        total: 1,
        status: 'error',
        statusLabel: '失败'
      }),
    {
      id,
      duration: 6000,
      unstyled: true
    }
  )
}

export function closeProgressToast(id: string): void {
  toast.dismiss(id)
}

export function showDefaultProgressSuccess(id: string, title: string, description?: string): void {
  toast.success(title, {
    id,
    description,
    duration: 4000
  })
}

export function showDefaultProgressError(id: string, title: string, description?: string): void {
  toast.error(title, {
    id,
    description,
    duration: 6000
  })
}
