import { A, useNavigate } from '@solidjs/router';
import { createMemo, createResource, createSignal, Show } from 'solid-js';
import AdminShell from '~/components/AdminShell';
import { STATIC_PERMISSIONS, type Permission } from '~/lib/admin-modules';

const API = '/api/gateway';

async function loadPermissions(): Promise<Permission[]> {
  try {
    const res = await fetch(`${API}/api/admin/permissions`);
    if (!res.ok) return STATIC_PERMISSIONS;
    const data = await res.json();
    const rows: Permission[] = Array.isArray(data) ? data : (data.permissions || []);
    return rows.length > 0 ? rows : STATIC_PERMISSIONS;
  } catch {
    return STATIC_PERMISSIONS;
  }
}

export default function CreateInternalRolePage() {
  const navigate = useNavigate();
  const [permissions] = createResource(loadPermissions);

  const [roleName, setRoleName] = createSignal('');
  const [description, setDescription] = createSignal('');
  const [assignedModules, setAssignedModules] = createSignal<string[]>([]);
  const [permissionIds, setPermissionIds] = createSignal<string[]>([]);
  const [saving, setSaving] = createSignal(false);
  const [error, setError] = createSignal('');

  const permsByModule = createMemo(() => {
    const map: Record<string, Permission[]> = {};
    (permissions() || []).forEach((p) => {
      if (!map[p.module]) map[p.module] = [];
      map[p.module].push(p);
    });
    return map;
  });

  const allModules = createMemo(() => Object.keys(permsByModule()).sort());

  const toggleModule = (mod: string) => {
    const current = assignedModules();
    if (current.includes(mod)) {
      setAssignedModules(current.filter((m) => m !== mod));
      // remove permissions for this module
      const idsToRemove = (permsByModule()[mod] || []).map((p) => p.id);
      setPermissionIds(permissionIds().filter((id) => !idsToRemove.includes(id)));
    } else {
      setAssignedModules([...current, mod]);
    }
  };

  const togglePermission = (id: string) => {
    const current = permissionIds();
    if (current.includes(id)) {
      setPermissionIds(current.filter((p) => p !== id));
    } else {
      setPermissionIds([...current, id]);
    }
  };

  const handleSave = async () => {
    if (!roleName().trim()) { setError('Role name is required'); return; }
    if (assignedModules().length === 0) { setError('Select at least one module'); return; }
    if (permissionIds().length === 0) { setError('Assign at least one permission'); return; }

    try {
      setSaving(true);
      setError('');
      const res = await fetch(`${API}/api/admin/roles`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          name: roleName().trim(),
          description: description().trim(),
          audience: 'INTERNAL',
          modules: assignedModules(),
          permissionIds: permissionIds(),
        }),
      });
      if (!res.ok) {
        const body = await res.json().catch(() => ({}));
        throw new Error(body.message || 'Failed to create role');
      }
      navigate('/admin/roles');
    } catch (err: any) {
      setError(err.message || 'Failed to create role');
    } finally {
      setSaving(false);
    }
  };

  return (
    <AdminShell>
      <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">
          <h1 class="text-xl font-semibold text-gray-900">Create Internal Role</h1>
          <p class="text-sm text-gray-500 mt-0.5">Create a new internal role and choose what it can access.</p>
        </div>

        <div class="flex-1 p-6">
          <nav class="hidden" aria-label="Role Management Navigation">
            <A class="hidden" href="/admin/roles">Internal Roles</A>
            <A class="hidden" href="/admin/runtime-roles">External Runtime Roles</A>
            <A class="hidden" href="/admin/onboarding-schemas">Onboarding Schemas</A>
          </nav>

          <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>

          {/* Role Details */}
          <div class="mb-6 rounded-xl border border-gray-200 bg-white p-6 shadow-sm">
            <h3>Role Basics</h3>
            <p>Start by giving this role a clear name.</p>
            <div class="mt-4 grid grid-cols-1 gap-4 sm:grid-cols-2">
              <div class="field">
                <label class="mb-1.5 block text-sm font-medium text-gray-700">Role Name <span class="text-red-500">*</span></label>
                <input
                  class="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm outline-none focus:border-[#0a1d37] focus:ring-1 focus:ring-[#0a1d37]"
                  value={roleName()}
                  onInput={(e) => setRoleName(e.currentTarget.value)}
                  placeholder="e.g. Customer Support Rep"
                />
              </div>
              <div class="field">
                <label class="mb-1.5 block text-sm font-medium text-gray-700">Description</label>
                <input
                  class="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm outline-none focus:border-[#0a1d37] focus:ring-1 focus:ring-[#0a1d37]"
                  value={description()}
                  onInput={(e) => setDescription(e.currentTarget.value)}
                  placeholder="Short description of this role"
                />
              </div>
            </div>
          </div>

          {/* Module Access */}
          <div class="mb-6 rounded-xl border border-gray-200 bg-white p-6 shadow-sm">
            <h3>Area Access</h3>
            <p>Select which areas this role can access. You can set permissions for selected areas below.</p>
            <Show when={permissions.loading}>
              <p class="notice">Loading available areas...</p>
            </Show>
            <Show when={!permissions.loading && allModules().length > 0}>
              <div class="mt-3 flex flex-wrap gap-2">
                {allModules().map((mod) => (
                  <button
                    type="button"
                    class={`flex cursor-pointer items-center gap-1.5 rounded-full border border-gray-200 bg-white px-3 py-1.5 text-xs font-medium text-gray-600 hover:border-gray-300 ${assignedModules().includes(mod) ? 'selected' : ''}`}
                    onClick={() => toggleModule(mod)}
                  >
                    <span class={`inline-block w-3.5 h-3.5 rounded-[3px] border-2 flex-shrink-0 ${assignedModules().includes(mod) ? 'border-[#0a1d37] bg-[#0a1d37]' : 'border-slate-300 bg-white'}`} />
                    {mod}
                  </button>
                ))}
              </div>
            </Show>
            <Show when={!permissions.loading && allModules().length === 0}>
              <p class="notice">No areas available.</p>
            </Show>
          </div>

          {/* Permission Table */}
          <Show when={assignedModules().length > 0}>
            <div class="mb-6 rounded-xl border border-gray-200 bg-white p-6 shadow-sm">
              <h3>Permissions</h3>
              <p>Choose what this role can do in each selected area.</p>
              <div class="table-card overflow-x-auto">
                <table data-table class="w-full text-sm">
                  <thead>
                    <tr>
                      <th style="width:45%">Area</th>
                      <th style="width:11%">No Access</th>
                      <th style="width:11%">Read</th>
                      <th style="width:11%">Create</th>
                      <th style="width:11%">Update</th>
                      <th style="width:11%">Delete</th>
                    </tr>
                  </thead>
                  <tbody>
                    {assignedModules().sort().map((mod) => {
                      const perms = permsByModule()[mod] || [];
                      const actionMap: Record<string, string> = {};
                      perms.forEach((p) => { actionMap[p.action] = p.id; });
                      const hasRead = !!actionMap['Read'] && permissionIds().includes(actionMap['Read']);
                      const hasCreate = !!actionMap['Create'] && permissionIds().includes(actionMap['Create']);
                      const hasUpdate = !!actionMap['Update'] && permissionIds().includes(actionMap['Update']);
                      const hasDelete = !!actionMap['Delete'] && permissionIds().includes(actionMap['Delete']);
                      const noAccess = !hasRead && !hasCreate && !hasUpdate && !hasDelete;
                      return (
                        <tr class="hover:bg-slate-50">
                          <td class="font-semibold text-slate-900">{mod}</td>
                          <td><input type="checkbox" checked={noAccess} disabled aria-label={`${mod} no access`} /></td>
                          <td>{actionMap['Read'] ? <input type="checkbox" checked={hasRead} onChange={() => togglePermission(actionMap['Read'])} aria-label={`${mod} read`} /> : <span class="text-slate-300">—</span>}</td>
                          <td>{actionMap['Create'] ? <input type="checkbox" checked={hasCreate} onChange={() => togglePermission(actionMap['Create'])} aria-label={`${mod} create`} /> : <span class="text-slate-300">—</span>}</td>
                          <td>{actionMap['Update'] ? <input type="checkbox" checked={hasUpdate} onChange={() => togglePermission(actionMap['Update'])} aria-label={`${mod} update`} /> : <span class="text-slate-300">—</span>}</td>
                          <td>{actionMap['Delete'] ? <input type="checkbox" checked={hasDelete} onChange={() => togglePermission(actionMap['Delete'])} aria-label={`${mod} delete`} /> : <span class="text-slate-300">—</span>}</td>
                        </tr>
                      );
                    })}
                  </tbody>
                </table>
              </div>
            </div>
          </Show>

          {/* Save */}
          <div class="flex justify-end gap-3 mt-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/roles">Cancel</A>
            <button
              class="btn-primary"
              onClick={handleSave}
              disabled={saving() || !roleName().trim()}
            >
              {saving() ? 'Creating...' : 'Create Role'}
            </button>
          </div>
        </div>
      </div>
    </AdminShell>
  );
}
