import {Save} from 'lucide-react';
import {FormEvent, useState} from 'react';

import {upsertProfileInviteCode} from '../api/adminApiClient';
import type {ProfileInviteCodeAdminResponse} from '../api/adminApiTypes';
import {handlePageError} from './pageUtils';

interface AdminInviteCodePageProps {
  token: string;
  result: ProfileInviteCodeAdminResponse | null;
  onUnauthorized: (message?: string) => void;
  onResultChange: (result: ProfileInviteCodeAdminResponse) => void;
}

export function AdminInviteCodePage({
  token,
  result,
  onUnauthorized,
  onResultChange,
}: AdminInviteCodePageProps) {
  const [inviteCode, setInviteCode] = useState('');
  const [metadataText, setMetadataText] = useState('{}');
  const [errorMessage, setErrorMessage] = useState('');
  const [isSaving, setIsSaving] = useState(false);

  async function handleSave(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    if (isSaving) {
      return;
    }

    setErrorMessage('');
    setIsSaving(true);
    try {
      const response = await upsertProfileInviteCode(token, {
        inviteCode: inviteCode.trim(),
        metadata: parseMetadata(metadataText),
      });
      onResultChange(response);
    } catch (error: unknown) {
      handlePageError(error, onUnauthorized, setErrorMessage);
    } finally {
      setIsSaving(false);
    }
  }

  return (
    <section className="admin-page">
      <div className="admin-page-heading">
        <div>
          <h2>邀请码</h2>
          <p>注册链路预置码</p>
        </div>
      </div>

      <div className="admin-two-column admin-two-column-wide">
        <form className="admin-panel admin-form" onSubmit={handleSave}>
          <label className="admin-field">
            <span>Invite Code</span>
            <input
              autoComplete="off"
              value={inviteCode}
              onChange={(event) => setInviteCode(event.target.value)}
            />
          </label>

          <label className="admin-field">
            <span>Metadata JSON</span>
            <textarea
              rows={10}
              spellCheck={false}
              value={metadataText}
              onChange={(event) => setMetadataText(event.target.value)}
            />
          </label>

          {errorMessage ? (
            <div className="admin-alert" role="status">
              {errorMessage}
            </div>
          ) : null}

          <button
            className="admin-primary-button"
            disabled={isSaving || !inviteCode.trim() || !isMetadataReady(metadataText)}
            type="submit"
          >
            <Save size={17} aria-hidden="true" />
            <span>{isSaving ? '保存中' : '保存'}</span>
          </button>
        </form>

        <section className="admin-panel admin-result-panel">
          <div className="admin-panel-heading">
            <h3>记录</h3>
            <span>{result?.inviteCode ?? '-'}</span>
          </div>
          {result ? (
            <dl className="admin-info-list">
              <div>
                <dt>User ID</dt>
                <dd>{result.userId}</dd>
              </div>
              <div>
                <dt>邀请码</dt>
                <dd>{result.inviteCode}</dd>
              </div>
              <div>
                <dt>创建</dt>
                <dd>{result.createdAt}</dd>
              </div>
              <div>
                <dt>更新</dt>
                <dd>{result.updatedAt}</dd>
              </div>
              <div>
                <dt>Metadata</dt>
                <dd>
                  <pre className="admin-code-block">
                    {JSON.stringify(result.metadata, null, 2)}
                  </pre>
                </dd>
              </div>
            </dl>
          ) : (
            <div className="admin-empty-state">暂无记录</div>
          )}
        </section>
      </div>
    </section>
  );
}

function parseMetadata(value: string): Record<string, unknown> {
  const trimmed = value.trim();
  if (!trimmed) {
    return {};
  }

  const parsed = JSON.parse(trimmed) as unknown;
  if (!isRecord(parsed)) {
    throw new Error('Metadata 必须是 JSON 对象');
  }
  return parsed;
}

function isMetadataReady(value: string) {
  try {
    parseMetadata(value);
    return true;
  } catch {
    return false;
  }
}

function isRecord(value: unknown): value is Record<string, unknown> {
  return typeof value === 'object' && value !== null && !Array.isArray(value);
}
