'use client';

import { Loader2 } from 'lucide-react';
import { InlineKeyboardButton, parseInlineKeyboardMarkup } from '@/lib/bot-reply-markup';
import { cn } from '@/lib/utils';

export function buildInlineButtonKey(messageId: number, rowIndex: number, buttonIndex: number) {
  return `${messageId}:${rowIndex}:${buttonIndex}`;
}

interface BotInlineKeyboardProps {
  markup: unknown;
  messageId: number;
  loadingButtonKey?: string | null;
  disabled?: boolean;
  onCallbackClick?: (callbackData: string, buttonKey: string) => void | Promise<void>;
  onOpenMiniApp?: (url: string) => void;
  onOpenUrl?: (url: string) => void;
}

export function BotInlineKeyboard({
  markup,
  messageId,
  loadingButtonKey = null,
  disabled = false,
  onCallbackClick,
  onOpenMiniApp,
  onOpenUrl
}: BotInlineKeyboardProps) {
  const rows = parseInlineKeyboardMarkup(markup);
  if (!rows.length) return null;

  return (
    <div className="mt-2 space-y-1.5">
      {rows.map((row, rowIndex) => (
        <div
          key={`row-${rowIndex}`}
          className={cn('flex gap-1.5', row.length === 1 ? 'flex-col' : 'flex-row flex-wrap')}
        >
          {row.map((button, buttonIndex) => (
            <InlineKeyboardButtonView
              key={`btn-${rowIndex}-${buttonIndex}`}
              button={button}
              buttonKey={buildInlineButtonKey(messageId, rowIndex, buttonIndex)}
              fullWidth={row.length === 1}
              loading={loadingButtonKey === buildInlineButtonKey(messageId, rowIndex, buttonIndex)}
              disabled={disabled || (loadingButtonKey !== null && loadingButtonKey !== buildInlineButtonKey(messageId, rowIndex, buttonIndex))}
              onCallbackClick={onCallbackClick}
              onOpenMiniApp={onOpenMiniApp}
              onOpenUrl={onOpenUrl}
            />
          ))}
        </div>
      ))}
    </div>
  );
}

function InlineKeyboardButtonView({
  button,
  buttonKey,
  fullWidth,
  loading,
  disabled,
  onCallbackClick,
  onOpenMiniApp,
  onOpenUrl
}: {
  button: InlineKeyboardButton;
  buttonKey: string;
  fullWidth: boolean;
  loading: boolean;
  disabled: boolean;
  onCallbackClick?: (callbackData: string, buttonKey: string) => void | Promise<void>;
  onOpenMiniApp?: (url: string) => void;
  onOpenUrl?: (url: string) => void;
}) {
  const webAppUrl = button.web_app?.url;
  const callbackData = button.callback_data ?? button.callbackData;

  async function handleClick(event: React.MouseEvent<HTMLButtonElement>) {
    event.preventDefault();
    if (disabled || loading) return;

    if (webAppUrl) {
      if (onOpenMiniApp) {
        onOpenMiniApp(webAppUrl);
      } else {
        window.open(webAppUrl, '_blank', 'noopener,noreferrer');
      }
      return;
    }

    if (button.url) {
      if (onOpenUrl) {
        onOpenUrl(button.url);
      } else {
        window.open(button.url, '_blank', 'noopener,noreferrer');
      }
      return;
    }

    if (callbackData && onCallbackClick) {
      await onCallbackClick(callbackData, buttonKey);
    }
  }

  return (
    <button
      type="button"
      disabled={disabled || loading}
      className={cn(
        'inline-flex min-h-9 items-center justify-center rounded-xl border border-[#dce3ec] bg-[#f4f7fb] px-3 py-2 text-xs font-medium text-[#1f2430] transition',
        'hover:bg-[#e8eef6] disabled:cursor-not-allowed disabled:opacity-60',
        fullWidth ? 'w-full' : 'min-w-0 flex-1'
      )}
      onClick={(event) => void handleClick(event)}
    >
      {loading ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : button.text}
    </button>
  );
}
