import { A, useNavigate, useParams } from '@solidjs/router';
import { createMemo, createResource, createSignal, Show } from 'solid-js';
import ExternalRoleForm, { type ExternalRoleConfig } from '~/components/admin/ExternalRoleForm';
import ExternalRoleTabs from '~/components/admin/ExternalRoleTabs';

const API = '';

function normalizeRoleKey(value: string): string {
  return String(value || '').trim().toLowerCase().replace(/[-\s]+/g, '_');
}

function inferredVertical(roleKey: string): 'jobs' | 'marketplace' {
  const key = normalizeRoleKey(roleKey);
  return key === 'company' || key === 'job_seeker' ? 'jobs' : 'marketplace';
}

function inferredCategory(roleKey: string): ExternalRoleConfig['roleCategory'] {
  const key = normalizeRoleKey(roleKey);
  if (key === 'company') return 'employer';
  if (key === 'customer') return 'consumer';
  if (key === 'job_seeker') return 'specialist';
  return 'provider';
}

function normalizeVertical(raw: unknown, fallbackRoleKey: string): 'jobs' | 'marketplace' {
  const value = String(raw || '').trim().toLowerCase();
  if (value === 'jobs' || value === 'job') return 'jobs';
  if (value === 'marketplace' || value === 'service' || value === 'services') return 'marketplace';
  return inferredVertical(fallbackRoleKey);
}

async function loadRole(roleKey: string): Promise<ExternalRoleConfig | null> {
  try {
    const res = await fetch(`${API}/api/admin/roles?audience=EXTERNAL`);
    if (!res.ok) return null;
    const data = await res.json();
    const rows = Array.isArray(data) ? data : (data.roles || []);
    const normalizedRoleKey = decodeURIComponent(roleKey).toLowerCase();
    const row = rows.find((item: any) => String(item.key || item.role_key || item.roleKey || '').toLowerCase() === normalizedRoleKey);
    if (!row) return null;

    const cfg = row.config_json || {};
    const roleId = String(row.id || '');

    let dashboardConfig: any = null;
    let onboardingConfig: any = null;
    if (roleId) {
      const [dashboardRes, onboardingRes] = await Promise.all([
        fetch(`${API}/api/admin/dashboard-config/${roleId}?audience=EXTERNAL`).catch(() => null),
        fetch(`${API}/api/admin/onboarding-config/${roleId}`).catch(() => null),
      ]);
      dashboardConfig = dashboardRes && dashboardRes.ok ? await dashboardRes.json().catch(() => null) : null;
      onboardingConfig = onboardingRes && onboardingRes.ok ? await onboardingRes.json().catch(() => null) : null;
    }

    const dashboardJson = dashboardConfig?.config_json || {};
    const enabledFromDashboard = Array.isArray(dashboardJson?.enabled_modules) ? dashboardJson.enabled_modules : [];
    const navFromDashboard = Array.isArray(dashboardJson?.nav) ? dashboardJson.nav : [];
    const modulesFromDashboard = Array.isArray(dashboardJson?.modules) ? dashboardJson.modules : [];
    const enabledModulesFallback = enabledFromDashboard.length > 0
      ? enabledFromDashboard
      : (
          navFromDashboard.length > 0
            ? navFromDashboard.map((item: any) => String(item?.key || '').trim()).filter(Boolean)
            : modulesFromDashboard.map((item: any) => String(item?.key || item?.moduleKey || '').trim()).filter(Boolean)
        );

    return {
      id: row.id,
      roleKey: String(cfg.roleKey || row.key || row.role_key || ''),
      displayName: String(cfg.displayName || row.name || row.display_name || ''),
      vertical: normalizeVertical(cfg.vertical || row.vertical, row.key || row.role_key || ''),
      roleCategory: cfg.roleCategory || inferredCategory(row.key || row.role_key || ''),
      enabledModules: Array.isArray(cfg.enabledModules) && cfg.enabledModules.length > 0 ? cfg.enabledModules : enabledModulesFallback,
      permissions: (cfg.permissions && typeof cfg.permissions === 'object') ? cfg.permissions : {},
      onboardingSchemaId: String(cfg.onboardingSchemaId || onboardingConfig?.id || ''),
      requiresOnboardingApproval: cfg.requiresOnboardingApproval ?? true,
      requiresLeadApproval: cfg.requiresLeadApproval ?? false,
      requiresJobApproval: cfg.requiresJobApproval ?? false,
      featureLimits: (cfg.featureLimits && typeof cfg.featureLimits === 'object') ? cfg.featureLimits : {},
      runtimeConfigVersion: Number(cfg.version || cfg.runtimeConfigVersion || 1),
      isActive: row.is_active !== false,
    };
  } catch {
    return null;
  }
}

export default function EditExternalRolePage() {
  const params = useParams();
  const navigate = useNavigate();
  const [data] = createResource(() => params.roleKey, loadRole);
  const [saving, setSaving] = createSignal(false);
  const [error, setError] = createSignal('');
  const roleKey = createMemo(() => decodeURIComponent(params.roleKey || ''));
  const [onboardingSchemas] = createResource(async () => {
    try {
      const res = await fetch(`${API}/api/admin/onboarding-config`);
      if (!res.ok) return [] as string[];
      const data = await res.json();
      const rows = Array.isArray(data) ? data : (data.schemas || data.configs || []);
      return rows.map((item: any) => String(item?.id || '').trim()).filter(Boolean);
    } catch {
      return [] as string[];
    }
  });

  const handleSubmit = async (config: ExternalRoleConfig) => {
    if (!config.id) {
      setError('Missing role id, cannot update.');
      return;
    }
    try {
      setSaving(true);
      setError('');
      const res = await fetch(`${API}/api/admin/roles/${config.id}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          key: config.roleKey.toUpperCase(),
          name: config.displayName,
          audience: 'EXTERNAL',
          config_json: {
            roleKey: config.roleKey,
            displayName: config.displayName,
            vertical: config.vertical,
            roleCategory: config.roleCategory,
            enabledModules: config.enabledModules,
            permissions: config.permissions,
            onboardingSchemaId: config.onboardingSchemaId,
            requiresOnboardingApproval: config.requiresOnboardingApproval,
            requiresLeadApproval: config.requiresLeadApproval,
            requiresJobApproval: config.requiresJobApproval,
            featureLimits: config.featureLimits || {},
            version: config.runtimeConfigVersion || 1,
          },
          is_active: config.isActive,
        }),
      });
      if (!res.ok) {
        const body = await res.json().catch(() => ({}));
        throw new Error(body.message || 'Failed to update runtime role');
      }
      navigate(`/admin/runtime-roles?roleKey=${encodeURIComponent(config.roleKey)}`);
    } catch (nextError: any) {
      setError(nextError?.message || 'Failed to update runtime role');
    } finally {
      setSaving(false);
    }
  };

  return (
      <div class="flex flex-col -mx-6 -mt-6 min-h-full">
      <div class="bg-white border-b border-gray-200 px-6 py-4 flex items-center justify-between">
        <div>
          <h1 class="text-xl font-semibold text-gray-900">External Role Management</h1>
          <p class="text-sm text-gray-500 mt-0.5">Update this external role with simple settings: pages, permissions, profile flow, approvals, and limits.</p>
        </div>
        <div class="flex items-center gap-2">
          <A class="rounded-lg border border-gray-200 px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 transition-colors" href={`/admin/role-ui-configs?roleKey=${encodeURIComponent(roleKey())}`}>Open Inspector</A>
          <A class="rounded-lg border border-gray-200 px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 transition-colors" href="/admin/runtime-roles">Back to External Roles</A>
        </div>
      </div>
      <div class="p-6 flex-1">

      <ExternalRoleTabs roleKey={roleKey()} />

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

      <div class="rounded-xl border border-gray-200 bg-white shadow-sm">
        <h2 style="margin-bottom:6px">How Saving Works</h2>
        <p class="notice" style="margin:0">
          Saving here updates the live role settings used by the app.
        </p>
      </div>

      <Show when={data.loading}>
        <div class="rounded-xl border border-gray-200 bg-white shadow-sm"><p class="notice">Loading external role...</p></div>
      </Show>

      <Show when={!data.loading && !data()}>
        <div class="rounded-xl border border-gray-200 bg-white shadow-sm"><p class="notice">Role "{roleKey()}" not found.</p></div>
      </Show>

      <Show when={!data.loading && data()}>
        <ExternalRoleForm
          initialValue={data()!}
          onboardingSchemaOptions={onboardingSchemas() || []}
          saving={saving()}
          submitLabel="Save Role Changes"
          onSubmit={handleSubmit}
        />
      </Show>
      </div>
      </div>
  );
}
