import { For, Show, createMemo, createSignal, onMount } from 'solid-js';
import { BTN_GHOST, BTN_PRIMARY, CARD } from '~/components/DashboardShell';

const API = '/api/gateway';

type UserRoleItem = {
  role_key: string;
  role_name?: string;
  status?: string;
};

type ExternalRoleItem = {
  id: string;
  key: string;
  name: string;
  audience?: string;
  is_active?: boolean;
};

async function apiFetch(path: string, opts?: RequestInit) {
  return fetch(`${API}${path}`, {
    ...opts,
    credentials: 'include',
    headers: { 'Content-Type': 'application/json', ...(opts?.headers ?? {}) },
  });
}

function toTitle(value: string): string {
  return String(value || '')
    .toLowerCase()
    .replace(/_/g, ' ')
    .replace(/\b\w/g, (c) => c.toUpperCase());
}

export default function ExploreServicesPage() {
  const [activeRoles, setActiveRoles] = createSignal<UserRoleItem[]>([]);
  const [externalRoles, setExternalRoles] = createSignal<ExternalRoleItem[]>([]);
  const [activeRoleKey, setActiveRoleKey] = createSignal('');
  const [loading, setLoading] = createSignal(true);
  const [busyRoleKey, setBusyRoleKey] = createSignal<string | null>(null);
  const [msg, setMsg] = createSignal('');
  const [err, setErr] = createSignal('');

  const activeRoleSet = createMemo(() => new Set(activeRoles().map((r) => String(r.role_key || '').toUpperCase())));

  const cards = createMemo(() =>
    externalRoles().map((r) => {
      const key = String(r.key || '').toUpperCase();
      const isRegistered = activeRoleSet().has(key);
      const isCurrent = activeRoleKey() === key;
      return {
        key,
        title: r.name || toTitle(key),
        subtitle: isRegistered
          ? 'Role is already linked to your account. You can switch instantly.'
          : 'Add this role to unlock its dashboard and workflows.',
        action: isCurrent ? 'Current Role' : (isRegistered ? 'Switch' : 'Register'),
      };
    }),
  );

  const load = async () => {
    setLoading(true);
    setErr('');
    try {
      if (typeof window !== 'undefined') {
        const raw = window.localStorage.getItem('nxtgauge_auth_user') || window.localStorage.getItem('nxtgauge_user');
        if (raw) {
          try {
            const parsed = JSON.parse(raw);
            setActiveRoleKey(String(parsed?.active_role || parsed?.role || '').toUpperCase());
          } catch {
            setActiveRoleKey('');
          }
        }
      }

      const [rolesRes, externalRes] = await Promise.all([
        apiFetch('/api/me/roles'),
        apiFetch('/api/admin/roles?audience=EXTERNAL&per_page=200'),
      ]);

      const rolesData = await rolesRes.json().catch(() => []);
      const externalData = await externalRes.json().catch(() => ({}));

      if (rolesRes.ok) {
        setActiveRoles(Array.isArray(rolesData) ? rolesData : []);
      } else {
        setActiveRoles([]);
      }

      if (externalRes.ok) {
        const rows = Array.isArray(externalData)
          ? externalData
          : (Array.isArray(externalData?.roles) ? externalData.roles : []);
        setExternalRoles(
          rows
            .filter((r: any) => String(r?.audience || 'EXTERNAL').toUpperCase() === 'EXTERNAL')
            .map((r: any) => ({
              id: String(r?.id || ''),
              key: String(r?.key || '').toUpperCase(),
              name: String(r?.name || toTitle(String(r?.key || ''))),
              audience: String(r?.audience || 'EXTERNAL').toUpperCase(),
              is_active: r?.is_active !== false,
            }))
            .filter((r: ExternalRoleItem) => Boolean(r.key))
            .sort((a: ExternalRoleItem, b: ExternalRoleItem) => a.name.localeCompare(b.name)),
        );
      } else {
        setExternalRoles([]);
        setErr('Unable to load available services right now.');
      }
    } catch {
      setErr('Network error while loading services.');
      setActiveRoles([]);
      setExternalRoles([]);
    } finally {
      setLoading(false);
    }
  };

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

  const registerRole = async (roleKey: string) => {
    setBusyRoleKey(roleKey);
    setMsg('');
    setErr('');
    try {
      const res = await apiFetch('/api/me/roles/register', {
        method: 'POST',
        body: JSON.stringify({ role_key: roleKey }),
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) {
        setErr(String(data?.error || data?.message || 'Failed to register role.'));
        return;
      }
      setMsg(`${toTitle(roleKey)} registered successfully.`);
      await load();
    } catch {
      setErr('Network error while registering role.');
    } finally {
      setBusyRoleKey(null);
    }
  };

  const switchRole = async (roleKey: string) => {
    setBusyRoleKey(roleKey);
    setMsg('');
    setErr('');
    try {
      const res = await apiFetch('/api/auth/switch-role', {
        method: 'POST',
        body: JSON.stringify({ role_key: roleKey }),
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) {
        setErr(String(data?.error || data?.message || 'Failed to switch role.'));
        return;
      }

      const accessToken = String(data?.access_token || '').trim();
      if (typeof window !== 'undefined' && accessToken) {
        window.sessionStorage.setItem('nxtgauge_access_token', accessToken);
        window.sessionStorage.setItem('nxtgauge_frontend_access_token', accessToken);
      }

      if (typeof window !== 'undefined') {
        const keys = ['nxtgauge_auth_user', 'nxtgauge_user', 'nxtgauge_signup_profile_v1'];
        for (const key of keys) {
          const raw = window.localStorage.getItem(key);
          if (!raw) continue;
          try {
            const parsed = JSON.parse(raw);
            const next = { ...parsed, active_role: roleKey, role: roleKey.toLowerCase(), roleKey: roleKey.toLowerCase() };
            window.localStorage.setItem(key, JSON.stringify(next));
          } catch {
            // ignore malformed payload
          }
        }
      }

      setMsg(`Switched to ${toTitle(roleKey)}. Redirecting...`);
      setTimeout(() => {
        window.location.href = '/dashboard';
      }, 250);
    } catch {
      setErr('Network error while switching role.');
    } finally {
      setBusyRoleKey(null);
    }
  };

  return (
    <div style={{ display: 'grid', gap: '14px', 'max-width': '1080px' }}>
      <div style={CARD}>
        <p style={{ margin: '0', 'font-size': '30px', 'font-weight': '800', color: '#111827', 'line-height': '1.15' }}>Explore Nxtgauge</p>
        <p style={{ margin: '8px 0 0', 'font-size': '14px', color: '#6B7280' }}>
          Runtime-driven service catalog based on your account and active role configuration.
        </p>
      </div>

      <Show when={msg()}>
        <div style={{ ...CARD, border: '1px solid #FFD8C2', background: '#FFF7ED', padding: '12px 14px', color: '#C2410C', 'font-size': '13px', 'font-weight': '700' }}>
          {msg()}
        </div>
      </Show>
      <Show when={err()}>
        <div style={{ ...CARD, border: '1px solid #FECACA', background: '#FEF2F2', padding: '12px 14px', color: '#B91C1C', 'font-size': '13px', 'font-weight': '700' }}>
          {err()}
        </div>
      </Show>

      <div style={CARD}>
        <div style={{ display: 'flex', 'justify-content': 'space-between', 'align-items': 'center', 'margin-bottom': '10px' }}>
          <p style={{ margin: '0', 'font-size': '16px', 'font-weight': '800', color: '#111827' }}>Available Services</p>
          <button type="button" onClick={() => void load()} style={BTN_GHOST}>Refresh</button>
        </div>

        <Show when={loading()}>
          <p style={{ margin: '0', 'font-size': '13px', color: '#6B7280' }}>Loading services...</p>
        </Show>

        <Show when={!loading() && cards().length === 0}>
          <p style={{ margin: '0', 'font-size': '13px', color: '#6B7280' }}>No services returned by runtime configuration.</p>
        </Show>

        <Show when={!loading() && cards().length > 0}>
          <div style={{ display: 'grid', 'grid-template-columns': 'repeat(3,minmax(0,1fr))', gap: '10px' }}>
            <For each={cards()}>
              {(card) => (
                <div style={{ border: '1px solid #E5E7EB', background: '#fff', 'border-radius': '14px', padding: '14px', display: 'flex', 'flex-direction': 'column', gap: '8px', 'box-shadow': '0 1px 4px rgba(0,0,0,0.05)' }}>
                  <p style={{ margin: '0', 'font-size': '17px', 'font-weight': '800', color: '#111827' }}>{card.title}</p>
                  <p style={{ margin: '0', 'font-size': '12px', color: '#6B7280', 'line-height': '1.45' }}>{card.subtitle}</p>
                  <button
                    type="button"
                    disabled={busyRoleKey() === card.key || card.action === 'Current Role'}
                    onClick={() => card.action === 'Register' ? void registerRole(card.key) : void switchRole(card.key)}
                    style={{
                      ...(card.action === 'Register' ? BTN_PRIMARY : BTN_GHOST),
                      height: '32px',
                      'font-size': '12px',
                      padding: '0 10px',
                      'margin-top': 'auto',
                      opacity: busyRoleKey() === card.key || card.action === 'Current Role' ? '0.7' : '1',
                    }}
                  >
                    {busyRoleKey() === card.key
                      ? (card.action === 'Register' ? 'Registering...' : 'Switching...')
                      : card.action}
                  </button>
                </div>
              )}
            </For>
          </div>
        </Show>
      </div>
    </div>
  );
}
