import { Show, createSignal, onMount } from "solid-js";

type PaymentGatewayConfig = {
  provider: string;
  mode: 'sandbox' | 'live';
  enabled: boolean;
  baseUrl: string;
  callbackUrl: string;
  webhookUrl: string;
  merchantId: string;
  apiKey: string;
  secretKey: string;
  clientId: string;
  clientSecret: string;
};

const DEFAULT_CONFIG: PaymentGatewayConfig = {
  provider: 'PayU',
  mode: 'sandbox',
  enabled: true,
  baseUrl: 'https://test.payu.in',
  callbackUrl: '',
  webhookUrl: '',
  merchantId: '',
  apiKey: '',
  secretKey: '',
  clientId: '',
  clientSecret: '',
};

const READ_ENDPOINTS = [
  '/api/admin/payment-gateway-config',
];

const WRITE_ENDPOINTS = [
  '/api/admin/payment-gateway-config',
];

function authHeaders() {
  const token = typeof sessionStorage !== 'undefined'
    ? (sessionStorage.getItem('nxtgauge_admin_access_token') || '')
    : '';
  return {
    'Content-Type': 'application/json',
    Accept: 'application/json',
    ...(token ? { Authorization: `Bearer ${token}` } : {}),
  };
}

// The server only ever sends masked secrets (e.g. "••••••••3f2a"); it never
// sends the real PayU merchant salt or OAuth client secret to the browser.
// A value containing the mask character means "unchanged" — if the admin
// doesn't edit the field, we must not send the placeholder back as if it
// were a real new secret.
const MASK_CHAR = '•';
function isMaskedPlaceholder(value: string): boolean {
  return value.includes(MASK_CHAR);
}

function normalizePayload(payload: any): PaymentGatewayConfig {
  const src = payload?.config || payload?.data || payload || {};
  return {
    provider: String(src.provider || DEFAULT_CONFIG.provider),
    mode: String(src.mode || DEFAULT_CONFIG.mode).toLowerCase() === 'live' ? 'live' : 'sandbox',
    enabled: src.enabled !== false,
    baseUrl: String(src.baseUrl || src.base_url || ''),
    callbackUrl: String(src.callbackUrl || src.callback_url || ''),
    webhookUrl: String(src.webhookUrl || src.webhook_url || ''),
    merchantId: String(src.merchantId || src.merchant_id || ''),
    apiKey: String(src.apiKey || src.api_key || ''),
    secretKey: String(src.secretKey || src.secret_key || ''),
    clientId: String(src.clientId || src.client_id || ''),
    clientSecret: String(src.clientSecret || src.client_secret || ''),
  };
}

export default function PaymentGatewayManagementPage() {
  const [loading, setLoading] = createSignal(false);
  const [saving, setSaving] = createSignal(false);
  const [error, setError] = createSignal('');
  const [success, setSuccess] = createSignal('');
  const [cfg, setCfg] = createSignal<PaymentGatewayConfig>(DEFAULT_CONFIG);

  const load = async () => {
    setLoading(true);
    setError('');
    try {
      let loaded = false;
      for (const endpoint of READ_ENDPOINTS) {
        const res = await fetch(endpoint, { method: 'GET', headers: authHeaders(), credentials: 'include' }).catch(() => null);
        if (!res || !res.ok) continue;
        const payload = await res.json().catch(() => ({}));
        setCfg(normalizePayload(payload));
        loaded = true;
        break;
      }
      if (!loaded) setCfg(DEFAULT_CONFIG);
    } catch (e: any) {
      setError(e?.message || 'Failed to load payment gateway configuration.');
    } finally {
      setLoading(false);
    }
  };

  onMount(() => void load());

  const setField = <K extends keyof PaymentGatewayConfig>(key: K, value: PaymentGatewayConfig[K]) => {
    setCfg((prev) => ({ ...prev, [key]: value }));
  };

  const save = async (e: Event) => {
    e.preventDefault();
    setSaving(true);
    setError('');
    setSuccess('');
    try {
      const payload = {
        provider: cfg().provider.trim(),
        mode: cfg().mode,
        enabled: cfg().enabled,
        base_url: cfg().baseUrl.trim(),
        callback_url: cfg().callbackUrl.trim(),
        webhook_url: cfg().webhookUrl.trim(),
        merchant_id: cfg().merchantId.trim(),
        api_key: cfg().apiKey.trim(),
        secret_key: cfg().secretKey.trim(),
        client_id: cfg().clientId.trim(),
        client_secret: cfg().clientSecret.trim(),
      };

      let saved = false;
      for (const endpoint of WRITE_ENDPOINTS) {
        const methods: Array<'PUT' | 'PATCH' | 'POST'> = ['PUT', 'PATCH', 'POST'];
        for (const method of methods) {
          const res = await fetch(endpoint, {
            method,
            headers: authHeaders(),
            credentials: 'include',
            body: JSON.stringify(payload),
          }).catch(() => null);
          if (!res || !res.ok) continue;
          saved = true;
          break;
        }
        if (saved) break;
      }

      if (!saved) throw new Error('Could not save configuration. Please verify backend endpoint wiring.');
      setSuccess('Payment gateway configuration saved successfully.');
      await load();
    } catch (e: any) {
      setError(e?.message || 'Failed to save payment gateway configuration.');
    } finally {
      setSaving(false);
    }
  };

  const inputCls = 'w-full rounded-lg border border-gray-200 px-3 py-2 text-sm outline-none focus:border-[#FF5E13] focus:ring-1 focus:ring-[#FF5E13]';
  const labelCls = 'mb-1.5 block text-sm font-medium text-gray-700';

  return (
    <div class="w-full space-y-6 pb-8">
      <div style="margin-bottom:1.5rem">
        <h1 class="text-[28px] font-bold leading-tight text-[#111827]">Payment Gateway Management</h1>
        <p class="mt-1 text-[14px] text-[#6B7280]">Manage PayU credentials, mode, and callback URLs for platform payments.</p>
      </div>

      <Show when={error()}>
        <div class="rounded-lg border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700">{error()}</div>
      </Show>
      <Show when={success()}>
        <div class="rounded-lg border border-emerald-200 bg-emerald-50 px-4 py-3 text-sm text-emerald-700">{success()}</div>
      </Show>

      <section class="rounded-xl border border-gray-200 bg-white shadow-sm p-6">
        <Show when={loading()}>
          <p class="text-sm text-gray-500">Loading configuration...</p>
        </Show>

        <form onSubmit={save} class="grid grid-cols-1 gap-4 sm:grid-cols-2">
          <div>
            <label class={labelCls}>Provider</label>
            <input class={inputCls} value={cfg().provider} onInput={(e) => setField('provider', e.currentTarget.value)} placeholder="PayU" />
          </div>
          <div>
            <label class={labelCls}>Mode</label>
            <select class={inputCls} value={cfg().mode} onChange={(e) => setField('mode', e.currentTarget.value === 'live' ? 'live' : 'sandbox')}>
              <option value="sandbox">Sandbox (Test)</option>
              <option value="live">Live (Production)</option>
            </select>
          </div>
          <div>
            <label class={labelCls}>Base API URL</label>
            <input class={inputCls} value={cfg().baseUrl} onInput={(e) => setField('baseUrl', e.currentTarget.value)} placeholder="https://test.payu.in" />
          </div>
          <div>
            <label class={labelCls}>Merchant Key</label>
            <input class={inputCls} value={cfg().apiKey} onInput={(e) => setField('apiKey', e.currentTarget.value)} placeholder="PayU merchant key" />
          </div>
          <div>
            <label class={labelCls}>Merchant Salt</label>
            <input
              type="password"
              class={inputCls}
              value={cfg().secretKey}
              onInput={(e) => setField('secretKey', e.currentTarget.value)}
              placeholder="PayU merchant salt"
            />
            <Show when={isMaskedPlaceholder(cfg().secretKey)}>
              <p class="mt-1 text-xs text-gray-500">Masked — the real value is never sent to the browser. Type a new salt to replace it, or leave as-is to keep the current one.</p>
            </Show>
          </div>
          <div>
            <label class={labelCls}>Client ID (optional)</label>
            <input class={inputCls} value={cfg().clientId} onInput={(e) => setField('clientId', e.currentTarget.value)} placeholder="PayU OAuth client id" />
          </div>
          <div>
            <label class={labelCls}>Client Secret (optional)</label>
            <input
              type="password"
              class={inputCls}
              value={cfg().clientSecret}
              onInput={(e) => setField('clientSecret', e.currentTarget.value)}
              placeholder="PayU OAuth client secret"
            />
            <Show when={isMaskedPlaceholder(cfg().clientSecret)}>
              <p class="mt-1 text-xs text-gray-500">Masked — the real value is never sent to the browser. Type a new secret to replace it, or leave as-is to keep the current one.</p>
            </Show>
          </div>
          <div>
            <label class={labelCls}>Callback URL (surl/furl)</label>
            <input class={inputCls} value={cfg().callbackUrl} onInput={(e) => setField('callbackUrl', e.currentTarget.value)} placeholder="https://yourapp.com/api/payments/payu-return" />
          </div>
          <div>
            <label class={labelCls}>Webhook URL</label>
            <input class={inputCls} value={cfg().webhookUrl} onInput={(e) => setField('webhookUrl', e.currentTarget.value)} placeholder="https://yourapp.com/api/payments/payu/webhook" />
          </div>
          <div class="sm:col-span-2">
            <label class="inline-flex items-center gap-2 text-sm text-gray-700">
              <input type="checkbox" checked={cfg().enabled} onChange={(e) => setField('enabled', e.currentTarget.checked)} />
              Enable payment gateway
            </label>
          </div>
          <div class="sm:col-span-2 flex items-center justify-end gap-2 border-t border-gray-100 pt-4">
            <button type="button" class="rounded-lg border border-gray-200 px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50" onClick={() => void load()}>
              Reload
            </button>
            <button type="submit" class="rounded-lg bg-[#0D0D2A] px-4 py-2 text-sm font-semibold text-white hover:bg-[#17173f]" disabled={saving()}>
              {saving() ? 'Saving...' : 'Save Configuration'}
            </button>
          </div>
        </form>
      </section>
    </div>
  );
}
