'use client';

import { useEffect, useState } from 'react';
import { Copy, ExternalLink, KeyRound, Loader2, RefreshCw, Trash2 } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { OAuthClient } from '@/lib/api';
import { OAuthEndpoints, buildAuthorizeUrl } from '@/lib/oauth-url';

function CopyRow({ label, value, onCopy }: { label: string; value: string; onCopy: (value: string, label: string) => void }) {
  return (
    <div className="rounded-2xl bg-[#f4f5f8] p-4 text-sm">
      <div className="mb-2 flex items-center justify-between gap-2">
        <span className="font-medium">{label}</span>
        <Button variant="ghost" size="icon" aria-label={`Скопировать ${label}`} onClick={() => onCopy(value, label)}>
          <Copy className="h-4 w-4" />
        </Button>
      </div>
      <code className="block break-all text-xs">{value}</code>
    </div>
  );
}

export function OAuthClientDetailDialog({
  client,
  endpoints,
  open,
  onOpenChange,
  onCopy,
  onRotateSecret,
  onToggleActive,
  onDelete,
  onSaveRedirectUris
}: {
  client: OAuthClient | null;
  endpoints: OAuthEndpoints;
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onCopy: (value: string, label: string) => void;
  onRotateSecret: (clientId: string) => void;
  onToggleActive: (client: OAuthClient) => void;
  onDelete: (client: OAuthClient) => void;
  onSaveRedirectUris: (client: OAuthClient, redirectUris: string[]) => Promise<void>;
}) {
  const [redirectUrisDraft, setRedirectUrisDraft] = useState('');
  const [savingRedirectUris, setSavingRedirectUris] = useState(false);

  useEffect(() => {
    if (!client) return;
    setRedirectUrisDraft(client.redirectUris.join('\n'));
  }, [client]);

  if (!client) return null;

  const primaryRedirect = client.redirectUris[0] ?? 'https://app.example.com/oauth/callback';
  const scope = client.scopes.join(' ');
  const sampleAuthorizeUrl = buildAuthorizeUrl(endpoints.issuer, {
    clientId: client.clientId,
    redirectUri: primaryRedirect,
    scope
  });

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-h-[90vh] overflow-y-auto sm:max-w-2xl">
        <DialogHeader>
          <DialogTitle>{client.name}</DialogTitle>
        </DialogHeader>

        <div className="space-y-4 text-sm">
          <div className="flex flex-wrap gap-2">
            <span className="rounded-full bg-[#eef4ff] px-3 py-1 text-xs font-medium text-[#1d4ed8]">
              {client.type === 'PUBLIC' ? 'Public' : 'Confidential'}
            </span>
            <span className={`rounded-full px-3 py-1 text-xs font-medium ${client.isActive ? 'bg-emerald-50 text-emerald-700' : 'bg-zinc-100 text-zinc-600'}`}>
              {client.isActive ? 'Активно' : 'Отключено'}
            </span>
            {client.createdByDisplayName ? (
              <span className="rounded-full bg-zinc-100 px-3 py-1 text-xs text-zinc-600">Создал: {client.createdByDisplayName}</span>
            ) : null}
          </div>

          <section className="space-y-3">
            <h3 className="font-medium">Данные клиента</h3>
            <CopyRow label="Client ID" value={client.clientId} onCopy={onCopy} />
            {client.type !== 'PUBLIC' ? (
              <p className="text-xs text-[#667085]">
                Client Secret выдаётся один раз при создании или после «Новый secret». Храните только на backend.
              </p>
            ) : null}
            <div className="space-y-2">
              <div className="flex items-center justify-between gap-2">
                <span className="font-medium">Redirect URI</span>
                {client.canManage ? null : (
                  <Button variant="ghost" size="icon" aria-label="Скопировать Redirect URI" onClick={() => onCopy(client.redirectUris.join('\n'), 'Redirect URI')}>
                    <Copy className="h-4 w-4" />
                  </Button>
                )}
              </div>
              {client.canManage ? (
                <>
                  <textarea
                    value={redirectUrisDraft}
                    onChange={(event) => setRedirectUrisDraft(event.target.value)}
                    placeholder="https://app.example.com/oauth/callback"
                    className="min-h-[96px] w-full rounded-xl border border-[#eceef4] bg-white px-3 py-2 text-sm"
                  />
                  <p className="text-xs text-[#667085]">
                    По одному URI на строку. Должен точно совпадать с redirect_uri в запросе authorize (протокол, домен, путь, слэш).
                  </p>
                  <Button
                    size="sm"
                    disabled={savingRedirectUris}
                    onClick={() => {
                      const redirectUris = redirectUrisDraft
                        .split('\n')
                        .map((item) => item.trim())
                        .filter(Boolean);
                      setSavingRedirectUris(true);
                      void onSaveRedirectUris(client, redirectUris).finally(() => setSavingRedirectUris(false));
                    }}
                  >
                    {savingRedirectUris ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : null}
                    Сохранить redirect URI
                  </Button>
                </>
              ) : (
                <div className="rounded-2xl bg-[#f4f5f8] p-4 text-sm">
                  <code className="block whitespace-pre-wrap break-all text-xs">{client.redirectUris.join('\n')}</code>
                </div>
              )}
            </div>
            <CopyRow label="Scopes" value={scope} onCopy={onCopy} />
          </section>

          <section className="space-y-3">
            <h3 className="font-medium">Подключение OAuth 2.0 / OpenID Connect</h3>
            <p className="text-xs text-[#667085]">
              Issuer и endpoints берутся из настройки <strong>PUBLIC_API_URL</strong> в админке. В стороннем сервисе укажите issuer = базовый URL API, не authorization endpoint.
            </p>
            <CopyRow label="Issuer (PUBLIC_API_URL)" value={endpoints.issuer} onCopy={onCopy} />
            <CopyRow label="Authorization endpoint" value={endpoints.authorizationEndpoint} onCopy={onCopy} />
            <CopyRow label="Token endpoint" value={endpoints.tokenEndpoint} onCopy={onCopy} />
            <CopyRow label="UserInfo endpoint" value={endpoints.userInfoEndpoint} onCopy={onCopy} />
            <CopyRow label="OIDC Discovery" value={endpoints.openIdConfigurationUrl} onCopy={onCopy} />
            <CopyRow label="Пример authorize URL" value={sampleAuthorizeUrl} onCopy={onCopy} />
          </section>

          <section className="rounded-2xl border border-[#eceef4] p-4">
            <div className="mb-2 flex items-center gap-2 font-medium">
              <KeyRound className="h-4 w-4" />
              Быстрый старт
            </div>
            <ol className="list-decimal space-y-1 pl-5 text-xs text-[#667085]">
              <li>Укажите issuer = PUBLIC_API_URL в OIDC-клиенте (PHP, Keycloak, Grafana и т.д.).</li>
              <li>Перенаправьте пользователя на authorization endpoint — стандартные параметры client_id, redirect_uri, response_type=code.</li>
              <li>IdP покажет вход и экран «Разрешить доступ», затем вернёт code на redirect_uri.</li>
              <li>На backend обменяйте code через POST /oauth/token (form-urlencoded или JSON).</li>
            </ol>
            <a
              href={endpoints.openIdConfigurationUrl}
              target="_blank"
              rel="noreferrer"
              className="mt-2 inline-flex items-center gap-1 text-xs text-[#1d4ed8] hover:underline"
            >
              Открыть OpenID Configuration
              <ExternalLink className="h-3.5 w-3.5" />
            </a>
          </section>

          {client.canManage ? (
            <div className="flex flex-wrap gap-2 border-t border-[#eceef4] pt-4">
              {client.type !== 'PUBLIC' ? (
                <Button variant="secondary" size="sm" onClick={() => onRotateSecret(client.clientId)}>
                  <RefreshCw className="h-4 w-4" />
                  Новый secret
                </Button>
              ) : null}
              <Button variant="secondary" size="sm" onClick={() => onToggleActive(client)}>
                {client.isActive ? 'Отключить' : 'Включить'}
              </Button>
              <Button
                variant="secondary"
                size="sm"
                className="text-red-600 hover:text-red-700"
                onClick={() => onDelete(client)}
              >
                <Trash2 className="h-4 w-4" />
                Удалить
              </Button>
            </div>
          ) : null}
        </div>
      </DialogContent>
    </Dialog>
  );
}
