import type { FormEvent } from 'react';
import { useCallback, useMemo, useState } from 'react';
import { useQueries, useQueryClient } from '@tanstack/react-query';
import { Link } from 'react-router-dom';
import { Building2, ChevronDown, ChevronRight, Loader2, Pencil, Trash2, X } from 'lucide-react';

import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { ModuleHeader } from '@/components/ui/module-header';
import { NativeSelect } from '@/components/ui/native-select';
import { Textarea } from '@/components/ui/textarea';
import { TenantParentPicker } from '@/components/tenant-create/TenantParentPicker';
import { ImageUpload } from '@/components/common/ImageUpload';
import { TenantLogo } from '@/components/common/TenantLogo';
import { useScopeContext } from '@/contexts/scope-context';
import { useTenantChildren } from '@/business/scope/queries';
import { useIamCapabilities } from '@/business/iam-capabilities/hooks';
import { usePermissions } from '@/hooks/usePermissions';
import { getErrorMessage } from '@/shared/errors/errorMessages';
import {
  createCampus,
  createClass,
  createSchoolWithFirstCampus,
  deleteCampus,
  deleteClass,
  deleteOrganization,
  deleteSchool,
  updateCampus,
  updateClass,
  updateOrganization,
  updateSchool,
  getScopeChildren,
} from '@/business/tenant-create/api';
import { APP_ROUTE_PATHS } from '@/shared/constants/routes';
import { CAMPUS_TIMEZONE_OPTIONS } from '@/shared/constants/timezones';
import {
  TENANT_TYPE_LABELS,
  getRequiredParentLevel,
  type TenantType,
} from '@/business/tenant-create/selectors';
import type { PermissionName } from '@/shared/auth/permissions';
import type { CreatableTenantType } from '@/shared/types/iamCapabilities';
import type { ActiveTenant, TenantChild } from '@/shared/types/scope';

const LOCATION_ROOT_PAGE_SIZE = 10;
const LOCATION_FETCH_LIMIT = 1000;

interface StatusMessage {
  readonly type: 'success' | 'error';
  readonly text: string;
}

interface CampusNode {
  readonly row: TenantChild;
  readonly classes: readonly TenantChild[];
}

interface SchoolNode {
  readonly row: TenantChild;
  readonly campuses: readonly CampusNode[];
}

interface OrganizationNode {
  readonly row: TenantChild;
  readonly schools: readonly SchoolNode[];
}

/** File-upload table (folder) per tenant type, for logo uploads. */
const TENANT_FILE_TABLE: Record<TenantType, string> = {
  organization: 'organizations',
  school: 'schools',
  campus: 'campuses',
  class: 'classes',
};

const LOCATION_MUTATION_PERMISSIONS: Record<
  TenantType,
  { readonly update: PermissionName; readonly delete: PermissionName }
> = {
  organization: { update: 'UPDATE_ORGANIZATIONS', delete: 'DELETE_ORGANIZATIONS' },
  school: { update: 'UPDATE_SCHOOLS', delete: 'DELETE_SCHOOLS' },
  campus: { update: 'UPDATE_CAMPUSES', delete: 'DELETE_CAMPUSES' },
  class: { update: 'UPDATE_CLASSES', delete: 'DELETE_CLASSES' },
};

function displayName(row: TenantChild): string {
  return row.name?.trim() || row.id;
}

function uniqueRows(rows: readonly TenantChild[]): TenantChild[] {
  const seen = new Set<string>();
  const result: TenantChild[] = [];
  for (const row of rows) {
    const key = `${row.level}:${row.id}`;
    if (seen.has(key)) continue;
    seen.add(key);
    result.push(row);
  }
  return result;
}

function tenantToChild(tenant: ActiveTenant): TenantChild {
  return {
    id: tenant.id,
    level: tenant.level,
    logo: tenant.logo,
    name: tenant.name,
  };
}

function ContactSection({
  idPrefix,
  value,
  onChange,
  inputClassName,
}: {
  readonly idPrefix: string;
  readonly value: ContactFields;
  readonly onChange: (value: ContactFields) => void;
  readonly inputClassName: string;
}) {
  return (
    <div className="grid gap-4 md:grid-cols-3">
      <div className="space-y-1.5">
        <Label htmlFor={`${idPrefix}-address`} className="text-slate-100">Address</Label>
        <Input
          id={`${idPrefix}-address`}
          value={value.address}
          className={inputClassName}
          onChange={(event) => onChange({ ...value, address: event.target.value })}
        />
      </div>
      <div className="space-y-1.5">
        <Label htmlFor={`${idPrefix}-phone`} className="text-slate-100">Phone number</Label>
        <Input
          id={`${idPrefix}-phone`}
          value={value.phone}
          className={inputClassName}
          onChange={(event) => onChange({ ...value, phone: event.target.value })}
        />
      </div>
      <div className="space-y-1.5">
        <Label htmlFor={`${idPrefix}-email`} className="text-slate-100">Email</Label>
        <Input
          id={`${idPrefix}-email`}
          type="email"
          value={value.email}
          className={inputClassName}
          onChange={(event) => onChange({ ...value, email: event.target.value })}
        />
      </div>
    </div>
  );
}

interface ContactFields {
  readonly address: string;
  readonly phone: string;
  readonly email: string;
}

interface ContactPayload {
  readonly address: string | null;
  readonly phone: string | null;
  readonly email: string | null;
}

function cleanOptionalText(value: string): string | null {
  const trimmed = value.trim();
  return trimmed || null;
}

function emptyContactFields(): ContactFields {
  return { address: '', phone: '', email: '' };
}

function cleanContactFields(contact: ContactFields): ContactPayload {
  const address = contact.address.trim();
  const phone = contact.phone.trim();
  const email = contact.email.trim();
  return {
    address: address || null,
    phone: phone || null,
    email: email || null,
  };
}

function rowContactFields(row: TenantChild): ContactFields {
  return {
    address: row.address ?? '',
    phone: row.phone ?? '',
    email: row.email ?? '',
  };
}

async function updateLocation(
  row: TenantChild,
  name: string,
  logo: string | null,
  contact: ContactFields,
  description: string,
): Promise<void> {
  const cleanContact = cleanContactFields(contact);
  if (row.level === 'organization') {
    await updateOrganization(row.id, { name, logo });
  } else if (row.level === 'school') {
    await updateSchool(row.id, { name, logo, description: cleanOptionalText(description), ...cleanContact });
  } else if (row.level === 'campus') {
    await updateCampus(row.id, { name, logo, description: cleanOptionalText(description), ...cleanContact });
  } else {
    await updateClass(row.id, { name, logo });
  }
}

async function deleteLocation(row: TenantChild): Promise<void> {
  if (row.level === 'organization') {
    await deleteOrganization(row.id);
  } else if (row.level === 'school') {
    await deleteSchool(row.id);
  } else if (row.level === 'campus') {
    await deleteCampus(row.id);
  } else {
    await deleteClass(row.id);
  }
}

export default function CreateTenantPage() {
  const { tier, ownTenant, effectiveTenant } = useScopeContext();
  const queryClient = useQueryClient();
  const permissions = usePermissions();
  const capabilitiesQuery = useIamCapabilities();
  const locationsQuery = useTenantChildren(null, { limit: LOCATION_FETCH_LIMIT });

  const creatableTypes = useMemo(
    () => capabilitiesQuery.data?.creatableTenantTypes ?? [],
    [capabilitiesQuery.data],
  );

  const [type, setType] = useState<CreatableTenantType | ''>(creatableTypes[0] ?? '');
  const [name, setName] = useState('');
  const [code, setCode] = useState('');
  const [description, setDescription] = useState('');
  const [timezone, setTimezone] = useState('America/New_York');
  const [campusName, setCampusName] = useState('');
  const [contact, setContact] = useState<ContactFields>(() => emptyContactFields());
  const [firstCampusLogo, setFirstCampusLogo] = useState<string | null>(null);
  const [firstCampusContact, setFirstCampusContact] = useState<ContactFields>(() => emptyContactFields());
  const [pickedParentId, setPickedParentId] = useState<string | null>(null);
  const [orgId, setOrgId] = useState('');
  const [logo, setLogo] = useState<string | null>(null);
  const [editingLocation, setEditingLocation] = useState<TenantChild | null>(null);
  const [editName, setEditName] = useState('');
  const [editLogo, setEditLogo] = useState<string | null>(null);
  const [editDescription, setEditDescription] = useState('');
  const [editContact, setEditContact] = useState<ContactFields>(() => emptyContactFields());
  const [deleteCandidate, setDeleteCandidate] = useState<TenantChild | null>(null);
  const [expandedLocations, setExpandedLocations] = useState<ReadonlySet<string>>(() => new Set());
  const [isLocationFormOpen, setIsLocationFormOpen] = useState(false);
  const [locationsPage, setLocationsPage] = useState(0);
  const [saving, setSaving] = useState(false);
  const [savingEdit, setSavingEdit] = useState(false);
  const [deleting, setDeleting] = useState(false);
  const [status, setStatus] = useState<StatusMessage | null>(null);
  const selectedType = type && creatableTypes.includes(type) ? type : (creatableTypes[0] ?? '');
  const rawRootRows = locationsQuery.data?.rows;
  const rootRows = useMemo(() => rawRootRows ?? [], [rawRootRows]);
  const organizationRows = rootRows.filter((row) => row.level === 'organization');
  const schoolQueries = useQueries({
    queries: organizationRows.map((row) => ({
      queryKey: ['scope-children', row.level, row.id],
      queryFn: () => getScopeChildren(row.level, row.id, { limit: LOCATION_FETCH_LIMIT }),
      retry: false,
    })),
  });
  const schoolRows = uniqueRows([
    ...rootRows.filter((row) => row.level === 'school'),
    ...schoolQueries.flatMap((query) => query.data?.rows ?? []).filter((row) => row.level === 'school'),
  ]);
  const campusQueries = useQueries({
    queries: schoolRows.map((row) => ({
      queryKey: ['scope-children', row.level, row.id],
      queryFn: () => getScopeChildren(row.level, row.id, { limit: LOCATION_FETCH_LIMIT }),
      retry: false,
    })),
  });
  const campusRows = uniqueRows([
    ...rootRows.filter((row) => row.level === 'campus'),
    ...campusQueries.flatMap((query) => query.data?.rows ?? []).filter((row) => row.level === 'campus'),
  ]);
  const classQueries = useQueries({
    queries: campusRows.map((row) => ({
      queryKey: ['scope-children', row.level, row.id],
      queryFn: () => getScopeChildren(row.level, row.id, { limit: LOCATION_FETCH_LIMIT }),
      retry: false,
    })),
  });
  const classRows = uniqueRows([
    ...rootRows.filter((row) => row.level === 'class'),
    ...classQueries.flatMap((query) => query.data?.rows ?? []).filter((row) => row.level === 'class'),
  ]);
  const rows = uniqueRows([...rootRows, ...schoolRows, ...campusRows, ...classRows]);
  const hierarchy = useMemo(() => {
    const schoolsByOrganization = new Map<string, TenantChild[]>();
    for (const [index, organization] of organizationRows.entries()) {
      schoolsByOrganization.set(
        organization.id,
        uniqueRows((schoolQueries[index]?.data?.rows ?? []).filter((row) => row.level === 'school')),
      );
    }

    const currentRoot = effectiveTenant ? tenantToChild(effectiveTenant) : null;
    if (currentRoot?.level === 'organization') {
      schoolsByOrganization.set(currentRoot.id, rootRows.filter((row) => row.level === 'school'));
    }

    const campusesBySchool = new Map<string, TenantChild[]>();
    for (const [index, school] of schoolRows.entries()) {
      campusesBySchool.set(
        school.id,
        uniqueRows((campusQueries[index]?.data?.rows ?? []).filter((row) => row.level === 'campus')),
      );
    }
    if (currentRoot?.level === 'school') {
      campusesBySchool.set(currentRoot.id, rootRows.filter((row) => row.level === 'campus'));
    }

    const classesByCampus = new Map<string, TenantChild[]>();
    for (const [index, campus] of campusRows.entries()) {
      classesByCampus.set(
        campus.id,
        uniqueRows((classQueries[index]?.data?.rows ?? []).filter((row) => row.level === 'class')),
      );
    }
    if (currentRoot?.level === 'campus') {
      classesByCampus.set(currentRoot.id, rootRows.filter((row) => row.level === 'class'));
    }

    const buildCampus = (campus: TenantChild): CampusNode => ({
      row: campus,
      classes: classesByCampus.get(campus.id) ?? [],
    });
    const buildSchool = (school: TenantChild): SchoolNode => ({
      row: school,
      campuses: (campusesBySchool.get(school.id) ?? []).map(buildCampus),
    });
    const buildOrganization = (organization: TenantChild): OrganizationNode => ({
      row: organization,
      schools: (schoolsByOrganization.get(organization.id) ?? []).map(buildSchool),
    });

    if (currentRoot?.level === 'organization') {
      return [buildOrganization(currentRoot)];
    }
    if (currentRoot?.level === 'school') {
      return [{ row: currentRoot, campuses: (campusesBySchool.get(currentRoot.id) ?? []).map(buildCampus) }];
    }
    if (currentRoot?.level === 'campus') {
      return [{ row: currentRoot, classes: classesByCampus.get(currentRoot.id) ?? [] }];
    }

    return organizationRows.map(buildOrganization);
  }, [
    campusQueries,
    campusRows,
    classQueries,
    effectiveTenant,
    organizationRows,
    rootRows,
    schoolQueries,
    schoolRows,
  ]);
  const locationTotal = rows.length;
  const hierarchyPageCount = Math.max(1, Math.ceil(hierarchy.length / LOCATION_ROOT_PAGE_SIZE));
  const pagedHierarchy = useMemo(
    () => hierarchy.slice(
      locationsPage * LOCATION_ROOT_PAGE_SIZE,
      locationsPage * LOCATION_ROOT_PAGE_SIZE + LOCATION_ROOT_PAGE_SIZE,
    ),
    [hierarchy, locationsPage],
  );
  const rootStart = hierarchy.length === 0 ? 0 : locationsPage * LOCATION_ROOT_PAGE_SIZE + 1;
  const rootEnd = Math.min(rootStart + pagedHierarchy.length - 1, hierarchy.length);
  const isHierarchyLoading =
    schoolQueries.some((query) => query.isLoading) ||
    campusQueries.some((query) => query.isLoading) ||
    classQueries.some((query) => query.isLoading);
  const hasHierarchyError =
    schoolQueries.some((query) => query.isError) ||
    campusQueries.some((query) => query.isError) ||
    classQueries.some((query) => query.isError);

  // Global creators have no own org, so they must target one when creating a
  // school (campus/class inherit the org from their chosen parent).
  const needsOrgSelector = selectedType === 'school' && tier === 'global';
  const orgQuery = useTenantChildren(null, { enabled: tier === 'global', limit: LOCATION_FETCH_LIMIT });

  const requiredParentLevel = selectedType ? getRequiredParentLevel(selectedType) : null;
  // The parent is the user's own organization/location when their tier already matches the
  // required parent level; otherwise it must be picked. Schools derive their
  // organization from the creator (no picker); only campus/class carry an
  // explicit parent FK (schoolId / campus id) in the payload.
  const parentIsOwn = requiredParentLevel !== null && tier === requiredParentLevel;
  const resolvedParentId = parentIsOwn ? (ownTenant?.id ?? null) : pickedParentId;
  const needsPicker =
    (selectedType === 'campus' || selectedType === 'class') && requiredParentLevel !== null && !parentIsOwn;

  const handlePickerChange = useCallback((id: string | null) => {
    setPickedParentId(id);
  }, []);

  function resetForm() {
    setName('');
    setCode('');
    setDescription('');
    setCampusName('');
    setTimezone('America/New_York');
    setContact(emptyContactFields());
    setFirstCampusLogo(null);
    setFirstCampusContact(emptyContactFields());
    setPickedParentId(null);
    setOrgId('');
    setLogo(null);
    setIsLocationFormOpen(false);
  }

  function startEdit(row: TenantChild) {
    setIsLocationFormOpen(true);
    setEditingLocation(row);
    setEditName(displayName(row));
    setEditLogo(row.logo ?? null);
    setEditDescription(row.description ?? '');
    setEditContact(rowContactFields(row));
    setStatus(null);
  }

  function resetEdit() {
    setEditingLocation(null);
    setEditName('');
    setEditLogo(null);
    setEditDescription('');
    setEditContact(emptyContactFields());
    setIsLocationFormOpen(false);
  }

  function locationKey(row: TenantChild): string {
    return `${row.level}:${row.id}`;
  }

  function isExpanded(row: TenantChild): boolean {
    return expandedLocations.has(locationKey(row));
  }

  function toggleExpanded(row: TenantChild) {
    const key = locationKey(row);
    setExpandedLocations((current) => {
      const next = new Set(current);
      if (next.has(key)) {
        next.delete(key);
      } else {
        next.add(key);
      }
      return next;
    });
  }

  async function refreshLocationRows() {
    await queryClient.invalidateQueries({ queryKey: ['scope-children'] });
  }

  async function handleSubmit(event: FormEvent) {
    event.preventDefault();
    setStatus(null);

    if (!selectedType) return;

    // Validate parent for campus/class.
    if ((selectedType === 'campus' || selectedType === 'class') && !resolvedParentId) {
      setStatus({ type: 'error', text: 'Please choose a parent organization or location.' });
      return;
    }
    if (needsOrgSelector && !orgId) {
      setStatus({ type: 'error', text: 'Please choose an organization.' });
      return;
    }

    setSaving(true);
    try {
      const logoValue = logo ?? undefined;
      if (selectedType === 'school') {
        await createSchoolWithFirstCampus(
          {
            name: name.trim(),
            code: code.trim(),
            organization: needsOrgSelector ? orgId : undefined,
            logo: logoValue,
            description: cleanOptionalText(description),
            ...cleanContactFields(contact),
          },
          {
            name: campusName.trim(),
            timezone: timezone.trim(),
            logo: firstCampusLogo ?? undefined,
            ...cleanContactFields(firstCampusContact),
          },
        );
      } else if (selectedType === 'campus') {
        await createCampus({
          name: name.trim(),
          code: code.trim(),
          timezone: timezone.trim(),
          schoolId: resolvedParentId ?? undefined,
          logo: logoValue,
          description: cleanOptionalText(description),
          ...cleanContactFields(contact),
        });
      } else {
        await createClass({
          name: name.trim(),
          campus: resolvedParentId ?? undefined,
          logo: logoValue,
        });
      }

      await refreshLocationRows();
      setLocationsPage(0);
      setStatus({ type: 'success', text: `${TENANT_TYPE_LABELS[selectedType]} created.` });
      resetForm();
    } catch (error) {
      setStatus({ type: 'error', text: getErrorMessage(error, 'Could not create organization or location') });
    } finally {
      setSaving(false);
    }
  }

  async function handleEditSubmit(event: FormEvent) {
    event.preventDefault();
    if (!editingLocation) return;
    setStatus(null);
    setSavingEdit(true);
    try {
      await updateLocation(editingLocation, editName.trim(), editLogo, editContact, editDescription);
      await refreshLocationRows();
      setStatus({ type: 'success', text: `${TENANT_TYPE_LABELS[editingLocation.level]} updated.` });
      resetEdit();
    } catch (error) {
      setStatus({ type: 'error', text: getErrorMessage(error, 'Could not update item') });
    } finally {
      setSavingEdit(false);
    }
  }

  async function handleDeleteConfirmed() {
    if (!deleteCandidate) return;
    const deleted = deleteCandidate;
    setStatus(null);
    setDeleting(true);
    try {
      await deleteLocation(deleted);
      await refreshLocationRows();
      if (editingLocation?.id === deleted.id) resetEdit();
      setDeleteCandidate(null);
      if (pagedHierarchy.length === 1 && locationsPage > 0) {
        setLocationsPage((page) => page - 1);
      }
      setStatus({ type: 'success', text: `${TENANT_TYPE_LABELS[deleted.level]} deleted.` });
    } catch (error) {
      setStatus({ type: 'error', text: getErrorMessage(error, 'Could not delete item') });
    } finally {
      setDeleting(false);
    }
  }

  if (capabilitiesQuery.isLoading || locationsQuery.isLoading) {
    return (
      <div className="mx-auto w-full max-w-2xl space-y-6 p-4 md:p-6">
        <div className="rounded-lg border border-slate-700/50 bg-slate-800/40 px-4 py-3 text-sm text-slate-300">
          Loading organizations and locations...
        </div>
      </div>
    );
  }

  const canCreate = creatableTypes.length > 0;
  const formControlClassName =
    'border-slate-600 bg-slate-950/80 text-slate-100 placeholder:text-slate-500 focus-visible:ring-sky-400 focus-visible:ring-offset-slate-950';
  const textareaClassName = `${formControlClassName} min-h-24`;
  const renderLocationRow = (row: TenantChild, depth = 0, hasChildren = false) => {
    const rowName = displayName(row);
    const rowPermissions = LOCATION_MUTATION_PERMISSIONS[row.level];
    const canUpdate = permissions.has(rowPermissions.update);
    const canDelete = permissions.has(rowPermissions.delete);
    const indentClass = depth === 0 ? '' : depth === 1 ? 'ml-6' : depth === 2 ? 'ml-12' : 'ml-16';
    const expanded = isExpanded(row);

    return (
      <div
        className={`${indentClass} flex flex-wrap items-center gap-3 border-t border-slate-700/50 py-3 first:border-t-0`}
      >
        <Button
          type="button"
          variant="ghost"
          size="icon"
          disabled={!hasChildren}
          onClick={() => toggleExpanded(row)}
          aria-label={`${expanded ? 'Collapse' : 'Expand'} ${rowName}`}
          className="h-8 w-8 shrink-0 text-slate-300 disabled:opacity-20"
        >
          {expanded ? <ChevronDown size={16} /> : <ChevronRight size={16} />}
        </Button>
        <TenantLogo
          name={rowName}
          logoUrl={row.logo}
          className="h-10 w-10 bg-slate-800 text-sm text-slate-200"
        />
        <div className="min-w-0 flex-1">
          <p className="truncate text-sm font-medium text-slate-200">{rowName}</p>
          <p className="text-xs text-slate-500">{TENANT_TYPE_LABELS[row.level]}</p>
        </div>
        <Button
          type="button"
          variant="ghost"
          disabled={!canUpdate}
          onClick={() => startEdit(row)}
          className="h-auto px-2 py-1 text-xs"
        >
          <Pencil size={14} className="mr-1" />
          Edit
        </Button>
        <Button
          type="button"
          variant="ghost"
          disabled={!canDelete}
          onClick={() => setDeleteCandidate(row)}
          className="h-auto px-2 py-1 text-xs text-red-300 hover:bg-red-500/10"
        >
          <Trash2 size={14} className="mr-1" />
          Delete
        </Button>
      </div>
    );
  };
  const renderClass = (row: TenantChild) => (
    <div key={`${row.level}:${row.id}`}>{renderLocationRow(row, 3)}</div>
  );
  const renderCampus = (node: CampusNode, depth = 2) => (
    <div key={`${node.row.level}:${node.row.id}`}>
      {renderLocationRow(node.row, depth, node.classes.length > 0)}
      {isExpanded(node.row) && node.classes.map(renderClass)}
    </div>
  );
  const renderSchool = (node: SchoolNode, depth = 1) => (
    <div key={`${node.row.level}:${node.row.id}`}>
      {renderLocationRow(node.row, depth, node.campuses.length > 0)}
      {isExpanded(node.row) && node.campuses.map((campus) => renderCampus(campus, depth + 1))}
    </div>
  );
  const renderOrganization = (node: OrganizationNode) => (
    <div key={`${node.row.level}:${node.row.id}`}>
      {renderLocationRow(node.row, 0, node.schools.length > 0)}
      {isExpanded(node.row) && node.schools.map((school) => renderSchool(school))}
    </div>
  );

  return (
    <div className="space-y-6 p-4 md:p-6">
      <ModuleHeader
        title="Organizations & Locations"
        description="Manage organizations, schools, campuses, and classes within your scope."
        icon={Building2}
        iconClassName="bg-gradient-to-br from-fuchsia-500 to-fuchsia-700"
      />

      {capabilitiesQuery.data?.canCreateOwnerWithOrganization === true && (
        <div className="rounded-lg border border-sky-500/30 bg-sky-500/10 px-4 py-3 text-sm text-sky-100">
          New organizations are created from owner setup. Go to{' '}
          <Link to={APP_ROUTE_PATHS.users} className="font-semibold underline underline-offset-4">
            Users
          </Link>{' '}
          and create an Owner; the organization is created automatically.
        </div>
      )}

      {(canCreate || editingLocation) && (
      <Card className="border-slate-600/70 bg-slate-900/80 shadow-lg shadow-black/20">
        <CardHeader className="border-b border-slate-700/70">
          <CardTitle className="flex items-center gap-2 text-base text-slate-50">
            <button
              type="button"
              className="flex min-w-0 flex-1 items-center gap-2 text-left"
              aria-expanded={isLocationFormOpen}
              aria-controls="tenant-location-form"
              onClick={() => setIsLocationFormOpen((open) => !open)}
            >
              {editingLocation ? <Pencil size={16} /> : null}
              <span>
                {editingLocation
                  ? `Edit ${TENANT_TYPE_LABELS[editingLocation.level]}`
                  : 'Add new organization'}
              </span>
              <ChevronDown
                size={16}
                className={`ml-auto shrink-0 text-slate-400 transition-transform ${
                  isLocationFormOpen ? 'rotate-180' : ''
                }`}
              />
            </button>
            {editingLocation && (
              <Button
                type="button"
                variant="ghost"
                onClick={resetEdit}
                className="ml-auto h-auto px-2 py-1 text-xs text-slate-400"
              >
                Cancel edit
              </Button>
            )}
          </CardTitle>
        </CardHeader>
        {isLocationFormOpen && (
        <CardContent id="tenant-location-form">
          <form className="space-y-5 pt-6" onSubmit={editingLocation ? handleEditSubmit : handleSubmit}>
            {editingLocation ? (
              <>
                <div className="space-y-1.5">
                  <Label htmlFor="edit-location-type" className="text-slate-100">Type</Label>
                  <NativeSelect
                    id="edit-location-type"
                    value={editingLocation.level}
                    disabled
                    className={formControlClassName}
                  >
                    <option value={editingLocation.level}>{TENANT_TYPE_LABELS[editingLocation.level]}</option>
                  </NativeSelect>
                </div>

                <div className="space-y-1.5">
                  <Label htmlFor="edit-location-name" className="text-slate-100">Name</Label>
                  <Input
                    id="edit-location-name"
                    value={editName}
                    className={formControlClassName}
                    onChange={(event) => setEditName(event.target.value)}
                    required
                  />
                </div>

                <ImageUpload
                  value={editLogo}
                  onChange={setEditLogo}
                  table={TENANT_FILE_TABLE[editingLocation.level]}
                  field="logo"
                  label={`${TENANT_TYPE_LABELS[editingLocation.level]} logo (optional)`}
                />

                {(editingLocation.level === 'school' || editingLocation.level === 'campus') && (
                  <div className="space-y-1.5">
                    <Label htmlFor="edit-location-description" className="text-slate-100">Description</Label>
                    <Textarea
                      id="edit-location-description"
                      value={editDescription}
                      className={textareaClassName}
                      onChange={(event) => setEditDescription(event.target.value)}
                      placeholder={`Short notes about this ${TENANT_TYPE_LABELS[editingLocation.level].toLowerCase()}`}
                    />
                  </div>
                )}

                {(editingLocation.level === 'school' || editingLocation.level === 'campus') && (
                  <div className="rounded-lg border border-slate-600/80 bg-slate-950/45 p-4 space-y-3">
                    <div>
                      <p className="text-sm font-semibold text-slate-100">Contact information</p>
                      <p className="mt-1 text-xs text-slate-300">
                        Public contact details for this {TENANT_TYPE_LABELS[editingLocation.level].toLowerCase()}.
                      </p>
                    </div>
                    <ContactSection
                      idPrefix="edit-location-contact"
                      value={editContact}
                      onChange={setEditContact}
                      inputClassName={formControlClassName}
                    />
                  </div>
                )}
              </>
            ) : (
              <>
            <div className="space-y-1.5">
              <Label htmlFor="tenant-type" className="text-slate-100">Type</Label>
              <NativeSelect
                id="tenant-type"
                value={selectedType}
                className={formControlClassName}
                onChange={(event) => {
                  setType(event.target.value as CreatableTenantType);
                  setStatus(null);
                  setPickedParentId(null);
                  setOrgId('');
                  setLogo(null);
                }}
              >
                {creatableTypes.map((option) => (
                  <option key={option} value={option}>
                    {TENANT_TYPE_LABELS[option]}
                  </option>
                ))}
              </NativeSelect>
            </div>

            {needsOrgSelector && (
              <div className="space-y-1.5">
                <Label htmlFor="org-select" className="text-slate-100">Organization</Label>
                <NativeSelect
                  id="org-select"
                  value={orgId}
                  className={formControlClassName}
                  onChange={(event) => setOrgId(event.target.value)}
                >
                  <option value="">Select organization...</option>
                  {(orgQuery.data?.rows ?? []).map((row) => (
                    <option key={row.id} value={row.id}>
                      {row.name ?? row.id}
                    </option>
                  ))}
                </NativeSelect>
              </div>
            )}

            {needsPicker && requiredParentLevel && selectedType && (
              <TenantParentPicker
                ownTier={tier}
                targetLevel={requiredParentLevel}
                onChange={handlePickerChange}
              />
            )}

            <div className={selectedType === 'school' ? 'rounded-lg border border-slate-600/80 bg-slate-950/45 p-4 space-y-4' : 'space-y-4'}>
              {selectedType === 'school' && (
                <div>
                  <p className="text-sm font-semibold text-slate-100">School details</p>
                  <p className="mt-1 text-xs text-slate-300">
                    These fields create the school record. The first campus is configured separately below.
                  </p>
                </div>
              )}

              <div className="space-y-1.5">
                <Label htmlFor="tenant-name" className="text-slate-100">
                  {selectedType ? TENANT_TYPE_LABELS[selectedType] : 'Location'} name
                </Label>
                <Input
                  id="tenant-name"
                  value={name}
                  className={formControlClassName}
                  onChange={(event) => setName(event.target.value)}
                  required
                />
              </div>

              {(selectedType === 'school' || selectedType === 'campus') && (
                <div className="space-y-1.5">
                  <Label htmlFor="tenant-code" className="text-slate-100">Code</Label>
                  <Input
                    id="tenant-code"
                    value={code}
                    className={formControlClassName}
                    onChange={(event) => setCode(event.target.value)}
                    placeholder="e.g. north-high"
                    required
                  />
                </div>
              )}

              {selectedType && (
                <ImageUpload
                  value={logo}
                  onChange={setLogo}
                  table={TENANT_FILE_TABLE[selectedType]}
                  field="logo"
                  label={
                    selectedType === 'school'
                      ? 'School logo (optional)'
                      : selectedType === 'campus'
                        ? 'Campus logo (optional)'
                        : 'Logo (optional)'
                  }
                />
              )}

              {(selectedType === 'school' || selectedType === 'campus') && (
                <div className="space-y-1.5">
                  <Label htmlFor="tenant-description" className="text-slate-100">Description</Label>
                  <Textarea
                    id="tenant-description"
                    value={description}
                    className={textareaClassName}
                    onChange={(event) => setDescription(event.target.value)}
                    placeholder={`Short notes about this ${TENANT_TYPE_LABELS[selectedType].toLowerCase()}`}
                  />
                </div>
              )}

              {(selectedType === 'school' || selectedType === 'campus') && (
                <div className="space-y-3">
                  <div>
                    <p className="text-sm font-semibold text-slate-100">Contact information</p>
                    <p className="mt-1 text-xs text-slate-300">
                      Public contact details for this {TENANT_TYPE_LABELS[selectedType].toLowerCase()}.
                    </p>
                  </div>
                  <ContactSection
                    idPrefix={`${selectedType}-contact`}
                    value={contact}
                    onChange={setContact}
                    inputClassName={formControlClassName}
                  />
                </div>
              )}
            </div>

            {selectedType === 'campus' && (
              <div className="space-y-1.5">
                <Label htmlFor="tenant-timezone" className="text-slate-100">Timezone</Label>
                <NativeSelect
                  id="tenant-timezone"
                  value={timezone}
                  className={formControlClassName}
                  onChange={(event) => setTimezone(event.target.value)}
                  required
                >
                  {CAMPUS_TIMEZONE_OPTIONS.map((option) => (
                    <option key={option.value} value={option.value}>
                      {option.label}
                    </option>
                  ))}
                </NativeSelect>
              </div>
            )}

            {selectedType === 'school' && (
              <div className="rounded-lg border border-sky-400/50 bg-sky-950/35 p-4 space-y-4">
                <div>
                  <p className="text-sm font-semibold text-slate-100">First campus</p>
                  <p className="mt-1 text-xs text-sky-100/85">
                    Every school needs at least one campus. This campus will be created together with the school and can be edited later.
                  </p>
                </div>
                <div className="space-y-1.5">
                  <Label htmlFor="campus-name" className="text-slate-100">Campus name</Label>
                  <Input
                    id="campus-name"
                    value={campusName}
                    className={formControlClassName}
                    onChange={(event) => setCampusName(event.target.value)}
                    required
                  />
                </div>
                <ImageUpload
                  value={firstCampusLogo}
                  onChange={setFirstCampusLogo}
                  table="campuses"
                  field="logo"
                  label="Campus logo (optional)"
                />
                <div className="space-y-1.5">
                  <Label htmlFor="campus-timezone" className="text-slate-100">Campus timezone</Label>
                  <NativeSelect
                    id="campus-timezone"
                    value={timezone}
                    className={formControlClassName}
                    onChange={(event) => setTimezone(event.target.value)}
                    required
                  >
                    {CAMPUS_TIMEZONE_OPTIONS.map((option) => (
                      <option key={option.value} value={option.value}>
                        {option.label}
                      </option>
                    ))}
                  </NativeSelect>
                </div>
                <div className="space-y-3">
                  <div>
                    <p className="text-sm font-semibold text-slate-100">Campus contact information</p>
                    <p className="mt-1 text-xs text-sky-100/85">
                      These details belong to the first campus, not the school record.
                    </p>
                  </div>
                  <ContactSection
                    idPrefix="first-campus-contact"
                    value={firstCampusContact}
                    onChange={setFirstCampusContact}
                    inputClassName={formControlClassName}
                  />
                </div>
              </div>
            )}
              </>
            )}

            <div className="flex justify-end">
              <Button
                type="submit"
                disabled={editingLocation ? (savingEdit || !editName.trim()) : saving}
              >
                {(editingLocation ? savingEdit : saving) && (
                  <Loader2 size={16} className="mr-2 animate-spin" />
                )}
                {editingLocation ? 'Save changes' : 'Create'}
              </Button>
            </div>
          </form>
        </CardContent>
        )}
      </Card>
      )}

      {!canCreate && (
        <div className="rounded-lg border border-slate-700/50 bg-slate-800/40 px-4 py-3 text-sm text-slate-300">
          You can view this area, but you do not have permission to create organizations or locations.
        </div>
      )}

      {status && (
        <div
          className={`rounded-lg border px-3 py-2 text-sm ${
            status.type === 'success'
              ? 'border-emerald-500/30 bg-emerald-500/10 text-emerald-200'
              : 'border-red-500/30 bg-red-500/10 text-red-200'
          }`}
        >
          {status.text}
        </div>
      )}

      <Card>
        <CardHeader>
          <div className="flex flex-wrap items-center justify-between gap-3">
            <CardTitle className="text-base">Current organizations and locations ({locationTotal})</CardTitle>
            {hierarchy.length > 0 && (
              <p className="text-xs text-slate-400">
                Showing root items {rootStart}-{rootEnd} of {hierarchy.length}
              </p>
            )}
          </div>
        </CardHeader>
        <CardContent>
          {locationsQuery.isError || hasHierarchyError ? (
            <p className="text-sm text-red-200">Could not load organizations and locations.</p>
          ) : rows.length === 0 ? (
            <p className="text-sm text-slate-400">No organizations or locations in this scope.</p>
          ) : (
            <div className="space-y-1">
              {isHierarchyLoading && (
                <div className="flex items-center gap-2 rounded-lg border border-slate-700/50 bg-slate-800/30 px-3 py-2 text-xs text-slate-400">
                  <Loader2 size={14} className="animate-spin" />
                  Loading child locations...
                </div>
              )}
              {pagedHierarchy.map((node) => {
                if ('schools' in node) return renderOrganization(node);
                if ('campuses' in node) return renderSchool(node, 0);
                return renderCampus(node, 0);
              })}
              {hierarchyPageCount > 1 && (
                <div className="mt-4 flex flex-wrap items-center justify-between gap-3 border-t border-slate-700/50 pt-4">
                  <p className="text-xs text-slate-400">
                    Page {locationsPage + 1} of {hierarchyPageCount}
                  </p>
                  <div className="flex items-center gap-2">
                    <Button
                      type="button"
                      variant="outline"
                      size="sm"
                      disabled={locationsPage === 0}
                      onClick={() => setLocationsPage((page) => Math.max(0, page - 1))}
                    >
                      Previous
                    </Button>
                    <Button
                      type="button"
                      variant="outline"
                      size="sm"
                      disabled={locationsPage >= hierarchyPageCount - 1}
                      onClick={() => setLocationsPage((page) => Math.min(hierarchyPageCount - 1, page + 1))}
                    >
                      Next
                    </Button>
                  </div>
                </div>
              )}
            </div>
          )}
        </CardContent>
      </Card>

      {deleteCandidate && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/70 p-4" role="presentation">
          <div
            className="w-full max-w-md rounded-lg border border-slate-700 bg-slate-950 p-5 shadow-2xl"
            role="dialog"
            aria-modal="true"
            aria-labelledby="delete-location-title"
          >
            <div className="flex items-start gap-3">
              <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-red-500/15 text-red-200">
                <Trash2 size={18} />
              </div>
              <div className="min-w-0 flex-1">
                <h2 id="delete-location-title" className="text-lg font-semibold text-slate-100">
                  Delete {TENANT_TYPE_LABELS[deleteCandidate.level].toLowerCase()}?
                </h2>
                <p className="mt-2 text-sm text-slate-300">
                  This removes "{displayName(deleteCandidate)}" from the current scope. Use this only for records created by mistake.
                </p>
              </div>
              <Button
                type="button"
                variant="ghost"
                size="icon"
                onClick={() => setDeleteCandidate(null)}
                aria-label="Close delete confirmation"
              >
                <X size={18} />
              </Button>
            </div>
            <div className="mt-5 flex justify-end gap-2">
              <Button
                type="button"
                variant="ghost"
                onClick={() => setDeleteCandidate(null)}
              >
                Keep
              </Button>
              <Button
                type="button"
                onClick={handleDeleteConfirmed}
                disabled={deleting}
                className="bg-red-600 text-white hover:bg-red-500"
              >
                {deleting && <Loader2 size={16} className="mr-2 animate-spin" />}
                Delete
              </Button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
