import { A, useParams } from '@solidjs/router';
import { createEffect, createResource, createSignal, onMount, Show } from 'solid-js';
import OnboardingManagementTabs from '~/components/admin/OnboardingManagementTabs';
import OnboardingFlowBuilder, {
  buildStepsFromFields,
  inferStepCount,
  type OnboardingField,
  type OnboardingStep,
} from '~/components/admin/OnboardingFlowBuilder';

const API = '/api/gateway';
const FRONTEND_PREVIEW_BASE = String(import.meta.env.VITE_FRONTEND_PREVIEW_URL || 'http://localhost:3001').replace(/\/+$/, '');

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

type OnboardingSchemaPayload = {
  id: string;
  schema_json?: {
    title?: string;
    roleKey?: string;
    description?: string;
    finalSubmissionMessage?: string;
    steps?: OnboardingStep[];
    version?: number;
  };
  is_active?: boolean;
};

async function loadSchema(roleId: string): Promise<OnboardingSchemaPayload | null> {
  try {
    const res = await fetch(`${API}/api/admin/onboarding-config/${roleId}`);
    if (!res.ok) return null;
    return res.json();
  } catch {
    return null;
  }
}

function flattenSteps(steps: OnboardingStep[]): OnboardingField[] {
  return steps.flatMap((step) => step.fields || []);
}

export default function OnboardingSchemaDetailPage() {
  const params = useParams();
  const [schema] = createResource(() => params.schemaId, loadSchema);
  const [roleMap, setRoleMap] = createSignal<Record<string, string>>({});
  const [roleKeyById, setRoleKeyById] = createSignal<Record<string, string>>({});
  const [roleOptions, setRoleOptions] = createSignal<{ value: string; label: string }[]>([]);

  const [title, setTitle] = createSignal('');
  const [roleKey, setRoleKey] = createSignal('');
  const [description, setDescription] = createSignal('');
  const [finalSubmissionMessage, setFinalSubmissionMessage] = createSignal('');
  const [stepCount, setStepCount] = createSignal(1);
  const [selectedFields, setSelectedFields] = createSignal<OnboardingField[]>([]);
  const [saving, setSaving] = createSignal(false);
  const [error, setError] = createSignal('');
  const [loaded, setLoaded] = createSignal(false);
  const [livePreviewUrl, setLivePreviewUrl] = createSignal('');

  onMount(async () => {
    try {
      const accessToken = typeof sessionStorage !== 'undefined'
        ? sessionStorage.getItem('nxtgauge_admin_access_token') || ''
        : '';
      const res = await fetch(`${API}/api/admin/roles?audience=EXTERNAL`, {
        headers: {
          Accept: 'application/json',
          ...(accessToken ? { Authorization: `Bearer ${accessToken}` } : {}),
        },
        credentials: 'include',
      });
      if (!res.ok) return;
      const payload = await res.json();
      const rows = Array.isArray(payload) ? payload : (payload.roles || []);
      const keyToId: Record<string, string> = {};
      const idToKey: Record<string, string> = {};
      const options: { value: string; label: string }[] = [];
      rows
        .filter((item: any) => String(item?.audience || '').toUpperCase() === 'EXTERNAL')
        .forEach((item: any) => {
          const key = String(item?.key || '').trim().toUpperCase();
          const id = String(item?.id || '').trim();
          if (!key || !id) return;
          keyToId[key] = id;
          idToKey[id] = key.toLowerCase();
          options.push({ value: key.toLowerCase(), label: String(item?.name || key).trim() });
        });
      setRoleMap(keyToId);
      setRoleKeyById(idToKey);
      setRoleOptions(options);
      if (!roleKey() && idToKey[String(params.schemaId || '').trim()]) {
        setRoleKey(idToKey[String(params.schemaId || '').trim()]);
      }
    } catch {
      setRoleMap({});
      setRoleKeyById({});
      setRoleOptions([]);
    }
  });

  createEffect(() => {
    const next = schema();
    if (!next || loaded()) return;
    const payload = next.schema_json || {};
    const steps = payload.steps || [];
    setTitle(payload.title || '');
    const fallbackRole = roleKeyById()[String(params.schemaId || '').trim()] || 'company';
    setRoleKey(payload.roleKey || fallbackRole);
    setDescription(payload.description || '');
    setFinalSubmissionMessage(payload.finalSubmissionMessage || 'Your onboarding has been submitted for review. We will notify you once it is approved.');
    setStepCount(inferStepCount(steps));
    setSelectedFields(flattenSteps(steps));
    setLoaded(true);
  });

  createEffect(() => {
    if (!loaded()) return;
    if (roleKey()) return;
    const fallback = roleKeyById()[String(params.schemaId || '').trim()];
    if (fallback) setRoleKey(fallback);
  });

  const handleChange = (next: {
    title?: string;
    roleKey?: string;
    description?: string;
    finalSubmissionMessage?: string;
    stepCount?: number;
    selectedFields?: OnboardingField[];
  }) => {
    if (typeof next.title === 'string') setTitle(next.title);
    if (typeof next.roleKey === 'string') setRoleKey(next.roleKey);
    if (typeof next.description === 'string') setDescription(next.description);
    if (typeof next.finalSubmissionMessage === 'string') setFinalSubmissionMessage(next.finalSubmissionMessage);
    if (typeof next.stepCount === 'number') setStepCount(next.stepCount);
    if (Array.isArray(next.selectedFields)) setSelectedFields(next.selectedFields);
  };

  const persist = async () => {
    try {
      setSaving(true);
      setError('');
      const current = schema();
      const accessToken = typeof sessionStorage !== 'undefined'
        ? sessionStorage.getItem('nxtgauge_admin_access_token') || ''
        : '';
      const normalizedRole = normalizeRoleKey(roleKey());
      const selectedRoleId = roleMap()[normalizedRole] || String(params.schemaId || '').trim();
      const response = await fetch(`${API}/api/admin/onboarding-config`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          ...(accessToken ? { Authorization: `Bearer ${accessToken}` } : {}),
        },
        credentials: 'include',
        body: JSON.stringify({
          role_id: selectedRoleId,
          schema_json: {
            title: title(),
            roleKey: roleKey(),
            description: description(),
            finalSubmissionMessage: finalSubmissionMessage(),
            version: current?.schema_json?.version || 1,
            steps: buildStepsFromFields(selectedFields(), stepCount()),
          },
        }),
      });
      const payload = await response.json();
      if (!response.ok) throw new Error(payload?.message || 'Failed to save onboarding flow');
      const nextRoleId = String(payload?.role_id || selectedRoleId).trim();
      if (nextRoleId && nextRoleId !== String(params.schemaId || '').trim()) {
        window.location.href = `/admin/onboarding-schemas/${encodeURIComponent(nextRoleId)}`;
        return;
      }
      setLoaded(false);
      await schema.refetch();
    } catch (nextError: any) {
      setError(nextError?.message || 'Failed to save onboarding flow');
    } finally {
      setSaving(false);
    }
  };

  createEffect(() => {
    const role = normalizeRoleKey(roleKey());
    const schemaId = String(params.schemaId || '').trim();
    if (!role) {
      setLivePreviewUrl('');
      return;
    }
    const query = new URLSearchParams({ roleKey: role });
    if (schemaId) query.set('schemaId', schemaId);
    setLivePreviewUrl(`${FRONTEND_PREVIEW_BASE}/onboarding?${query.toString()}`);
  });

  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">Onboarding Management</h1>
          <p class="text-sm text-gray-500 mt-0.5">Open one onboarding form at a time, check if it is published, then update the role, questions, steps, and final success message.</p>
        </div>
        <div class="flex items-center gap-2">
          <button class="rounded-lg border border-gray-200 px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 transition-colors" type="button" disabled={saving()} onClick={() => void persist()}>
            Save Active Version
          </button>
          <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/onboarding-schemas">Back to Onboarding Management</A>
        </div>
      </div>
      <OnboardingManagementTabs />
      <div class="p-6 flex-1">

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

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

      <Show when={schema() && loaded()}>
        <>
          <div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:16px;margin-bottom:16px">
            <div class="rounded-xl border border-gray-200 bg-white shadow-sm"><p class="kv-label">Status</p><p class="kv-value">{schema()?.is_active ? 'PUBLISHED' : 'DRAFT'}</p></div>
            <div class="rounded-xl border border-gray-200 bg-white shadow-sm"><p class="kv-label">Version</p><p class="kv-value">{schema()?.schema_json?.version || 1}</p></div>
            <div class="rounded-xl border border-gray-200 bg-white shadow-sm"><p class="kv-label">Steps</p><p class="kv-value">{stepCount()}</p></div>
            <div class="rounded-xl border border-gray-200 bg-white shadow-sm"><p class="kv-label">Questions</p><p class="kv-value">{selectedFields().length}</p></div>
          </div>

          <OnboardingFlowBuilder
            title={title()}
            roleKey={roleKey()}
            description={description()}
            finalSubmissionMessage={finalSubmissionMessage()}
            stepCount={stepCount()}
            selectedFields={selectedFields()}
            saving={saving()}
            error={error()}
            livePreviewUrl={livePreviewUrl()}
            livePreviewHint="Edit page preview loads the exact flow by schema id in the real onboarding UI."
            roleOptions={roleOptions()}
            primaryLabel="Save Onboarding Flow"
            onChange={handleChange}
            onSubmit={() => void persist()}
          />
        </>
      </Show>
      </div>
      </div>
  );
}
