'use client';

import { useEffect, useMemo, useState, type CSSProperties, type ReactNode } from 'react';
import { fetchPublicSettingsClient } from '@/lib/api';
import { buildOneTapUrls, type OneTapUrls } from '@/lib/one-tap-examples';
import { resolveFrontendBase, resolveOAuthApiBase } from '@/lib/oauth-url';
import { CodeBlock } from '@/components/code-block';
import { cn } from '@/lib/utils';
import {
  buildButtonSnippet,
  DEFAULT_BUILDER_OPTIONS,
  ICON_OPTIONS,
  resolveButtonStyle,
  SIZE_OPTIONS,
  THEME_OPTIONS,
  VIEW_OPTIONS,
  type ButtonBuilderOptions
} from '@/lib/one-tap-builder';

type ColorKey = 'bg' | 'bgHover' | 'border' | 'borderHover' | 'text';

const COLOR_FIELDS: Array<{ key: ColorKey; label: string }> = [
  { key: 'bg', label: 'Цвет фона' },
  { key: 'bgHover', label: 'Фон при наведении' },
  { key: 'border', label: 'Цвет обводки' },
  { key: 'borderHover', label: 'Обводка при наведении' },
  { key: 'text', label: 'Цвет текста' }
];

function Field({ label, children }: { label: string; children: ReactNode }) {
  return (
    <label className="flex flex-col gap-1.5">
      <span className="text-xs font-medium text-zinc-500 dark:text-zinc-400">{label}</span>
      {children}
    </label>
  );
}

const inputClass =
  'h-9 w-full rounded-lg border border-zinc-300 bg-white px-3 text-sm text-zinc-900 outline-none transition focus:border-zinc-400 focus:ring-2 focus:ring-zinc-200 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-100 dark:focus:ring-zinc-700';

export function OneTapButtonBuilder() {
  const [apiBase, setApiBase] = useState('http://localhost:3000');
  const [frontendBase, setFrontendBase] = useState('http://localhost:3002');
  const [projectName, setProjectName] = useState('MVK ID');
  const [options, setOptions] = useState<ButtonBuilderOptions>(DEFAULT_BUILDER_OPTIONS);
  const [hovered, setHovered] = useState(false);
  const [status, setStatus] = useState<string | null>(null);

  useEffect(() => {
    void fetchPublicSettingsClient()
      .then((settings) => {
        setApiBase(resolveOAuthApiBase(settings));
        setFrontendBase(resolveFrontendBase(settings));
        if (settings.PROJECT_NAME?.trim()) {
          const name = settings.PROJECT_NAME.trim();
          setProjectName(name);
          setOptions((prev) =>
            prev.providerName === DEFAULT_BUILDER_OPTIONS.providerName ? { ...prev, providerName: name } : prev
          );
        }
      })
      .catch(() => undefined);
  }, []);

  const urls: OneTapUrls = useMemo(
    () => buildOneTapUrls(apiBase, frontendBase, projectName),
    [apiBase, frontendBase, projectName]
  );
  const snippet = useMemo(() => buildButtonSnippet(options, urls), [options, urls]);
  const style = useMemo(() => resolveButtonStyle(options), [options]);

  function update<K extends keyof ButtonBuilderOptions>(key: K, value: ButtonBuilderOptions[K]) {
    setOptions((prev) => ({ ...prev, [key]: value }));
  }

  function toggleColor(key: ColorKey, enabled: boolean) {
    setOptions((prev) => ({
      ...prev,
      [key]: enabled ? (prev[key] || style.palette[key] || '#ffffff') : ''
    }));
  }

  const buttonStyle: CSSProperties = {
    height: style.preset.height,
    fontSize: style.preset.font,
    gap: style.preset.gap,
    padding: style.iconOnly ? 0 : `0 ${style.preset.padX}px`,
    width: style.iconOnly ? style.preset.height : 'auto',
    borderRadius: style.radius,
    background: hovered ? style.bgHover : style.bg,
    color: style.text,
    border: `1px solid ${hovered ? style.borderHover : style.border}`,
    boxShadow: '0 8px 24px rgba(31,36,48,.12)',
    transition: 'all .18s ease'
  };

  const badgeStyle: CSSProperties = {
    minWidth: style.preset.badge,
    height: style.preset.badge,
    padding: `0 ${Math.round(style.preset.badge / 4)}px`,
    fontSize: Math.round(style.preset.font * 0.85),
    background: style.palette.badgeBg,
    color: style.palette.badgeColor
  };

  function tryLogin() {
    if (typeof window === 'undefined') return;
    const params = new URLSearchParams({
      client_id: options.clientId || 'YOUR_CLIENT_ID',
      redirect_uri: options.redirectUri,
      response_type: 'code',
      scope: 'openid profile email',
      display: 'popup',
      popup_origin: window.location.origin,
      state: 'preview_' + Math.random().toString(36).slice(2)
    });
    const url = `${frontendBase}/auth/oauth/authorize?${params.toString()}`;
    const popup = window.open(url, 'mvkid_preview', 'popup,width=480,height=640');
    if (!popup) {
      setStatus('Браузер заблокировал popup — разрешите всплывающие окна для теста.');
      return;
    }
    setStatus('Открыт popup авторизации. После входа токен придёт через postMessage.');
    function onMessage(event: MessageEvent) {
      if (event.data?.type !== 'lendry-sso-onetap') return;
      window.removeEventListener('message', onMessage);
      setStatus(`Получен ответ: метод ${event.data.method ?? 'popup'}.`);
    }
    window.addEventListener('message', onMessage);
  }

  return (
    <div className="my-4 grid gap-4 lg:grid-cols-[1.1fr_1fr]">
      {/* Левая колонка: превью + код */}
      <div className="space-y-3">
        <div className="flex min-h-[140px] items-center justify-center rounded-xl border border-zinc-200 bg-[#e9edf3] p-6 dark:border-zinc-800 dark:bg-[#15171c]">
          <button
            type="button"
            className="inline-flex cursor-pointer items-center justify-center font-semibold leading-none"
            style={buttonStyle}
            onMouseEnter={() => setHovered(true)}
            onMouseLeave={() => setHovered(false)}
            onClick={tryLogin}
            aria-label={`Войти через ${options.providerName || projectName}`}
          >
            {style.showBadge ? (
              <span className="inline-flex items-center justify-center rounded-full font-bold" style={badgeStyle}>
                ID
              </span>
            ) : null}
            {!style.iconOnly ? <span>Войти через {options.providerName || projectName}</span> : null}
          </button>
        </div>

        {status ? (
          <p className="rounded-lg border border-blue-200 bg-blue-50 px-3 py-2 text-xs text-blue-700 dark:border-blue-900 dark:bg-blue-950/40 dark:text-blue-300">
            {status}
          </p>
        ) : null}

        <CodeBlock code={snippet} language="html" title="Код для вставки" />
      </div>

      {/* Правая колонка: параметры */}
      <div className="space-y-3 rounded-xl border border-zinc-200 p-4 dark:border-zinc-800">
        <Field label="Client ID (из админки: RBAC → OAuth приложения)">
          <input
            className={inputClass}
            value={options.clientId}
            onChange={(event) => update('clientId', event.target.value)}
            placeholder="YOUR_CLIENT_ID"
          />
        </Field>

        <Field label="Redirect URI">
          <input
            className={inputClass}
            value={options.redirectUri}
            onChange={(event) => update('redirectUri', event.target.value)}
            placeholder="https://app.example.com/auth/callback"
          />
        </Field>

        <Field label="Название провайдера (текст на кнопке)">
          <input
            className={inputClass}
            value={options.providerName}
            onChange={(event) => update('providerName', event.target.value)}
            placeholder={projectName}
          />
        </Field>

        <div className="grid grid-cols-2 gap-3">
          <Field label="Размер">
            <select
              className={inputClass}
              value={options.size}
              onChange={(event) => update('size', event.target.value as ButtonBuilderOptions['size'])}
            >
              {SIZE_OPTIONS.map((opt) => (
                <option key={opt.value} value={opt.value}>
                  {opt.label}
                </option>
              ))}
            </select>
          </Field>

          <Field label="Тема">
            <select
              className={inputClass}
              value={options.theme}
              onChange={(event) => update('theme', event.target.value as ButtonBuilderOptions['theme'])}
            >
              {THEME_OPTIONS.map((opt) => (
                <option key={opt.value} value={opt.value}>
                  {opt.label}
                </option>
              ))}
            </select>
          </Field>

          <Field label="Вид">
            <select
              className={inputClass}
              value={options.view}
              onChange={(event) => update('view', event.target.value as ButtonBuilderOptions['view'])}
            >
              {VIEW_OPTIONS.map((opt) => (
                <option key={opt.value} value={opt.value}>
                  {opt.label}
                </option>
              ))}
            </select>
          </Field>

          <Field label="Тип иконки">
            <select
              className={inputClass}
              value={options.icon}
              onChange={(event) => update('icon', event.target.value as ButtonBuilderOptions['icon'])}
            >
              {ICON_OPTIONS.map((opt) => (
                <option key={opt.value} value={opt.value}>
                  {opt.label}
                </option>
              ))}
            </select>
          </Field>
        </div>

        <Field label={`Радиус скругления — ${options.radius}px`}>
          <input
            type="range"
            min={0}
            max={32}
            value={options.radius}
            onChange={(event) => update('radius', Number(event.target.value))}
            className="w-full accent-zinc-900 dark:accent-zinc-100"
          />
        </Field>

        <div className="space-y-2 border-t border-zinc-200 pt-3 dark:border-zinc-800">
          <p className="text-xs font-medium text-zinc-500 dark:text-zinc-400">
            CSS-цвета (необязательно — иначе берётся цвет темы)
          </p>
          {COLOR_FIELDS.map((field) => {
            const enabled = Boolean(options[field.key]);
            const fallback = style.palette[field.key] || '#ffffff';
            const value = options[field.key] || fallback;
            return (
              <div key={field.key} className="flex items-center gap-3">
                <input
                  type="checkbox"
                  checked={enabled}
                  onChange={(event) => toggleColor(field.key, event.target.checked)}
                  className="h-4 w-4 accent-zinc-900 dark:accent-zinc-100"
                />
                <input
                  type="color"
                  value={value.startsWith('#') ? value : '#ffffff'}
                  disabled={!enabled}
                  onChange={(event) => update(field.key, event.target.value)}
                  className={cn('h-8 w-10 cursor-pointer rounded border border-zinc-300 bg-transparent dark:border-zinc-700', !enabled && 'opacity-40')}
                />
                <span className="text-sm text-zinc-600 dark:text-zinc-300">{field.label}</span>
                {enabled ? (
                  <code className="ml-auto rounded bg-zinc-100 px-1.5 py-0.5 text-xs dark:bg-zinc-800">{options[field.key]}</code>
                ) : null}
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
}
