import { useMemo, useState } from 'react';
import {
  AlertTriangle,
  Bell,
  Calendar,
  Clock,
  Pencil,
  Save,
  Trash2,
  Users,
  XCircle,
} from 'lucide-react';
import type { LucideIcon } from 'lucide-react';

import {
  useCancelCommunicationEvent,
  useCommunicationEvents,
  useCreateCommunicationEvent,
  useDeleteCommunicationEvent,
  useUpdateCommunicationEvent,
} from '@/business/communications/hooks';
import {
  toCommunicationEventType,
} from '@/business/communications/selectors';
import { useTenantChildren } from '@/business/scope/queries';
import { useScopeContext } from '@/contexts/scope-context';
import { usePermissions } from '@/hooks/usePermissions';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { NativeSelect } from '@/components/ui/native-select';
import { StatePanel } from '@/components/ui/state-panel';
import {
  COMMUNICATION_EVENT_ICON_BACKGROUNDS,
  COMMUNICATION_EVENT_TYPE_COLORS,
  COMMUNICATION_EVENT_TYPES,
} from '@/shared/constants/communications';
import { getOptionalErrorMessage } from '@/shared/errors/errorMessages';
import type {
  CommunicationEventTargetDto,
  CommunicationEventTargetLevel,
  CommunicationEventType,
} from '@/shared/types/communications';
import type { TenantChild, TenantLevel } from '@/shared/types/scope';
import type { CurrentUser } from '@/shared/types/auth';

const typeIcons: Record<CommunicationEventType, LucideIcon> = {
  meeting: Users,
  drill: AlertTriangle,
  event: Calendar,
  deadline: Clock,
};

type AudienceMode = CommunicationEventTargetLevel;
type AlertAction = 'cancel' | 'delete';

interface PendingAlertAction {
  readonly action: AlertAction;
  readonly eventId: string;
  readonly title: string;
}

function firstId(items: readonly TenantChild[]): string {
  return items[0]?.id ?? '';
}

function selectedIdOrFirst(selectedId: string, items: readonly TenantChild[]): string {
  return items.some((item) => item.id === selectedId) ? selectedId : firstId(items);
}

function defaultAudienceMode(tier: string, level: TenantLevel | null): AudienceMode {
  if (tier === 'global' && !level) return 'system';
  if (level === 'organization' || level === 'school' || level === 'campus') return level;
  return 'campus';
}

function buildTargets(
  mode: AudienceMode,
  effectiveTenantLevel: TenantLevel | null,
  effectiveTenantId: string | null,
  selectedOrganizationId: string,
  selectedSchoolId: string,
  selectedCampusId: string,
): readonly CommunicationEventTargetDto[] {
  if (mode === 'system' || mode === 'all') {
    return [{ level: mode, id: null }];
  }
  if (mode === 'organization') {
    return [{ level: 'organization', id: effectiveTenantLevel === 'organization' ? effectiveTenantId : selectedOrganizationId }];
  }
  if (mode === 'school') {
    return [{ level: 'school', id: effectiveTenantLevel === 'school' ? effectiveTenantId : selectedSchoolId }];
  }
  return [{ level: 'campus', id: effectiveTenantLevel === 'campus' ? effectiveTenantId : selectedCampusId }];
}

interface InternalAlertsModuleProps {
  readonly user: CurrentUser | null;
}

export function InternalAlertsModule({ user }: InternalAlertsModuleProps) {
  const permissions = usePermissions();
  const { tier, effectiveTenant } = useScopeContext();
  const canCreateEvents = permissions.has('MANAGE_INTERNAL_COMM');
  const [newEventTitle, setNewEventTitle] = useState('');
  const [newEventDate, setNewEventDate] = useState('');
  const [newEventType, setNewEventType] = useState<CommunicationEventType>('meeting');
  const [editingEventId, setEditingEventId] = useState<string | null>(null);
  const [editTitle, setEditTitle] = useState('');
  const [editDate, setEditDate] = useState('');
  const [editType, setEditType] = useState<CommunicationEventType>('meeting');
  const [pendingAction, setPendingAction] = useState<PendingAlertAction | null>(null);
  const [cancelReason, setCancelReason] = useState('');
  const [audienceMode, setAudienceMode] = useState<AudienceMode>(
    defaultAudienceMode(tier, effectiveTenant?.level ?? null),
  );
  const [selectedOrganizationId, setSelectedOrganizationId] = useState('');
  const [selectedSchoolId, setSelectedSchoolId] = useState('');
  const [selectedCampusId, setSelectedCampusId] = useState('');
  const eventsQuery = useCommunicationEvents();
  const createEventMutation = useCreateCommunicationEvent();
  const updateEventMutation = useUpdateCommunicationEvent();
  const deleteEventMutation = useDeleteCommunicationEvent();
  const cancelEventMutation = useCancelCommunicationEvent();
  const visibleEvents = eventsQuery.data ?? [];
  const errorMessage = getOptionalErrorMessage(eventsQuery.error)
    ?? getOptionalErrorMessage(createEventMutation.error)
    ?? getOptionalErrorMessage(updateEventMutation.error)
    ?? getOptionalErrorMessage(deleteEventMutation.error)
    ?? getOptionalErrorMessage(cancelEventMutation.error);
  const isPlatformScope = tier === 'global' && !effectiveTenant;
  const effectiveTenantId = effectiveTenant?.id ?? null;
  const canManageEvents = permissions.has('MANAGE_INTERNAL_COMM');
  const audienceOptions = useMemo(() => {
    if (isPlatformScope) {
      return [
        { value: 'system', label: 'System admins' },
        { value: 'all', label: 'All users' },
        { value: 'organization', label: 'Organization leadership' },
      ] as const;
    }
    if (effectiveTenant?.level === 'organization') {
      return [
        { value: 'organization', label: 'Organization leadership' },
        { value: 'school', label: 'Selected school leadership' },
        { value: 'campus', label: 'Selected campus staff' },
      ] as const;
    }
    if (effectiveTenant?.level === 'school') {
      return [
        { value: 'school', label: 'School leadership' },
        { value: 'campus', label: 'Selected campus staff' },
      ] as const;
    }
    return [
      { value: 'campus', label: 'Campus staff' },
    ] as const;
  }, [effectiveTenant?.level, isPlatformScope]);
  const activeAudienceMode = audienceOptions.some((option) => option.value === audienceMode)
    ? audienceMode
    : audienceOptions[0].value;
  const needsSchoolPicker = effectiveTenant?.level === 'organization'
    && (activeAudienceMode === 'school' || activeAudienceMode === 'campus');
  const needsCampusPicker = activeAudienceMode === 'campus'
    && (effectiveTenant?.level === 'organization' || effectiveTenant?.level === 'school');
  const rootChildrenQuery = useTenantChildren(null, {
    enabled: canCreateEvents && isPlatformScope,
  });
  const schoolChildrenQuery = useTenantChildren(
    effectiveTenant?.level === 'organization'
      ? { level: 'organization', id: effectiveTenant.id }
      : null,
    { enabled: canCreateEvents && needsSchoolPicker },
  );
  const organizations = rootChildrenQuery.data?.rows ?? [];
  const schools = schoolChildrenQuery.data?.rows ?? [];
  const targetOrganizationId = selectedIdOrFirst(selectedOrganizationId, organizations);
  const targetSchoolId = selectedIdOrFirst(selectedSchoolId, schools);
  const campusParent = needsCampusPicker && effectiveTenant?.level === 'school'
    ? { level: 'school', id: effectiveTenant.id }
    : needsCampusPicker && targetSchoolId
      ? { level: 'school', id: targetSchoolId }
      : null;
  const campusChildrenQuery = useTenantChildren(
    campusParent,
    { enabled: canCreateEvents && needsCampusPicker && Boolean(campusParent) },
  );
  const campuses = campusChildrenQuery.data?.rows ?? [];
  const targetCampusId = selectedIdOrFirst(selectedCampusId, campuses);

  const addEvent = async () => {
    if (!newEventTitle || !newEventDate) return;
    const targets = buildTargets(
      activeAudienceMode,
      effectiveTenant?.level ?? null,
      effectiveTenantId,
      targetOrganizationId,
      targetSchoolId,
      targetCampusId,
    );
    if (targets.some((target) => !target.id && target.level !== 'system' && target.level !== 'all')) return;
    await createEventMutation.mutateAsync({
      title: newEventTitle,
      date: newEventDate,
      type: newEventType,
      targets,
    });
    setNewEventTitle('');
    setNewEventDate('');
  };

  const startEdit = (event: (typeof visibleEvents)[number]) => {
    setEditingEventId(event.id);
    setEditTitle(event.title);
    setEditDate(event.date);
    setEditType(event.type);
  };

  const saveEdit = async () => {
    if (!editingEventId || !editTitle || !editDate) return;
    await updateEventMutation.mutateAsync({
      id: editingEventId,
      title: editTitle,
      date: editDate,
      type: editType,
    });
    setEditingEventId(null);
  };

  const openActionDialog = (action: AlertAction, event: (typeof visibleEvents)[number]) => {
    setPendingAction({ action, eventId: event.id, title: event.title });
    setCancelReason('');
  };

  const closeActionDialog = () => {
    setPendingAction(null);
    setCancelReason('');
  };

  const confirmAction = async () => {
    if (!pendingAction) return;
    if (pendingAction.action === 'delete') {
      await deleteEventMutation.mutateAsync(pendingAction.eventId);
    } else {
      await cancelEventMutation.mutateAsync({
        id: pendingAction.eventId,
        reason: cancelReason.trim() || undefined,
      });
    }
    closeActionDialog();
  };

  const canMutateEvent = (event: (typeof visibleEvents)[number]) =>
    event.createdById === user?.id || canManageEvents;

  return (
    <div className="space-y-6">
      <div>
        <h2 className="text-2xl font-bold text-slate-100 flex items-center gap-3">
          <div className="w-10 h-10 rounded-xl bg-gradient-to-br from-rose-400 to-rose-600 flex items-center justify-center"><Bell size={20} className="text-white" /></div>
          Internal Communication & Alerts
        </h2>
        <p className="text-sm text-slate-400 mt-1">Smart notifications and event reminders</p>
      </div>
      {canCreateEvents && (
        <div className="rounded-2xl border border-slate-700/70 bg-slate-900/80 p-5 shadow-lg shadow-black/10">
          <h3 className="mb-4 font-semibold text-slate-100">Schedule New Alert</h3>
          <div className="grid grid-cols-1 gap-3 lg:grid-cols-12">
            <Input
              type="text"
              value={newEventTitle}
              onChange={(event) => setNewEventTitle(event.target.value)}
              placeholder="Event title..."
              aria-label="Alert title"
              className="h-12 rounded-xl border-slate-700 bg-slate-950/80 px-4 text-base text-slate-100 placeholder:text-slate-500 focus-visible:ring-2 focus-visible:ring-rose-400 focus-visible:ring-offset-0 lg:col-span-6"
            />
            <Input
              type="date"
              value={newEventDate}
              onChange={(event) => setNewEventDate(event.target.value)}
              aria-label="Alert date"
              className="h-12 rounded-xl border-slate-700 bg-slate-950/80 px-4 text-sm text-slate-100 [color-scheme:dark] focus-visible:ring-2 focus-visible:ring-rose-400 focus-visible:ring-offset-0 lg:col-span-2"
            />
            <NativeSelect
              value={newEventType}
              onChange={(event) => setNewEventType(toCommunicationEventType(event.target.value))}
              aria-label="Alert type"
              className="h-12 rounded-xl border-slate-700 bg-slate-950/80 px-4 text-sm text-slate-100 focus-visible:ring-2 focus-visible:ring-rose-400 focus-visible:ring-offset-0 lg:col-span-2"
            >
              {COMMUNICATION_EVENT_TYPES.map((type) => (
                <option key={type} value={type}>{type.charAt(0).toUpperCase() + type.slice(1)}</option>
              ))}
            </NativeSelect>
            <NativeSelect
              value={activeAudienceMode}
              onChange={(event) => setAudienceMode(event.target.value as AudienceMode)}
              aria-label="Alert audience"
              className="h-12 rounded-xl border-slate-700 bg-slate-950/80 px-4 text-sm text-slate-100 focus-visible:ring-2 focus-visible:ring-rose-400 focus-visible:ring-offset-0 lg:col-span-2"
            >
              {audienceOptions.map((option) => (
                <option key={option.value} value={option.value}>{option.label}</option>
              ))}
            </NativeSelect>
            {activeAudienceMode === 'organization' && isPlatformScope && (
              <NativeSelect
                value={targetOrganizationId}
                onChange={(event) => setSelectedOrganizationId(event.target.value)}
                aria-label="Target organization"
                className="h-12 rounded-xl border-slate-700 bg-slate-950/80 px-4 text-sm text-slate-100 focus-visible:ring-2 focus-visible:ring-rose-400 focus-visible:ring-offset-0 lg:col-span-2"
              >
                {organizations.map((organization) => (
                  <option key={organization.id} value={organization.id}>{organization.name ?? 'Organization'}</option>
                ))}
              </NativeSelect>
            )}
            {(activeAudienceMode === 'school' || (activeAudienceMode === 'campus' && effectiveTenant?.level === 'organization')) && (
              <NativeSelect
                value={targetSchoolId}
                onChange={(event) => {
                  setSelectedSchoolId(event.target.value);
                  setSelectedCampusId('');
                }}
                aria-label="Target school"
                className="h-12 rounded-xl border-slate-700 bg-slate-950/80 px-4 text-sm text-slate-100 focus-visible:ring-2 focus-visible:ring-rose-400 focus-visible:ring-offset-0 lg:col-span-2"
              >
                {schools.map((school) => (
                  <option key={school.id} value={school.id}>{school.name ?? 'School'}</option>
                ))}
              </NativeSelect>
            )}
            {activeAudienceMode === 'campus' && effectiveTenant?.level !== 'campus' && (
              <NativeSelect
                value={targetCampusId}
                onChange={(event) => setSelectedCampusId(event.target.value)}
                aria-label="Target campus"
                className="h-12 rounded-xl border-slate-700 bg-slate-950/80 px-4 text-sm text-slate-100 focus-visible:ring-2 focus-visible:ring-rose-400 focus-visible:ring-offset-0 lg:col-span-2"
              >
                {campuses.map((campus) => (
                  <option key={campus.id} value={campus.id}>{campus.name ?? 'Campus'}</option>
                ))}
              </NativeSelect>
            )}
            <Button
              type="button"
              onClick={() => { void addEvent(); }}
              disabled={createEventMutation.isPending}
              loading={createEventMutation.isPending}
              loadingLabel="Adding..."
              className="h-12 rounded-xl bg-gradient-to-r from-rose-500 to-pink-500 px-5 text-sm font-semibold text-white transition-all hover:shadow-lg hover:shadow-rose-500/20 disabled:opacity-50 lg:col-span-2"
            >
              Add Alert
            </Button>
          </div>
        </div>
      )}
      {errorMessage && (
        <div className="bg-red-50 border border-red-200 rounded-xl p-4 flex items-center gap-3">
          <AlertTriangle size={18} className="text-red-600" />
          <p className="text-sm text-red-700 font-medium">{errorMessage}</p>
        </div>
      )}
      {eventsQuery.isLoading ? (
        <StatePanel tone="red" alignment="center" loading>
          Loading alerts...
        </StatePanel>
      ) : (
        <div className="space-y-3">
          {visibleEvents.map((event) => {
            const TypeIcon = typeIcons[event.type];
            const isEditing = editingEventId === event.id;
            const isCancellationNotice = Boolean(event.canceledEventId);
            const canMutate = !isCancellationNotice && canMutateEvent(event);

            return (
              <div
                key={event.id}
                className={`rounded-2xl border bg-slate-900/75 p-4 shadow-sm transition-colors ${
                  COMMUNICATION_EVENT_TYPE_COLORS[event.type]
                }`}
              >
                <div className="flex items-center justify-between gap-4">
                <div className="flex items-center gap-3">
                  <div className={`w-10 h-10 rounded-xl flex items-center justify-center ${COMMUNICATION_EVENT_ICON_BACKGROUNDS[event.type]}`}>
                    <TypeIcon size={14} />
                  </div>
                  {isEditing ? (
                    <div className="grid grid-cols-1 gap-2 sm:grid-cols-[minmax(220px,1fr)_160px_140px]">
                      <Input
                        type="text"
                        value={editTitle}
                        onChange={(inputEvent) => setEditTitle(inputEvent.target.value)}
                        aria-label="Edit alert title"
                        className="h-10 rounded-lg border-slate-700 bg-slate-950/80 text-sm text-slate-100"
                      />
                      <Input
                        type="date"
                        value={editDate}
                        onChange={(inputEvent) => setEditDate(inputEvent.target.value)}
                        aria-label="Edit alert date"
                        className="h-10 rounded-lg border-slate-700 bg-slate-950/80 text-sm text-slate-100 [color-scheme:dark]"
                      />
                      <NativeSelect
                        value={editType}
                        onChange={(inputEvent) => setEditType(toCommunicationEventType(inputEvent.target.value))}
                        aria-label="Edit alert type"
                        className="h-10 rounded-lg border-slate-700 bg-slate-950/80 text-sm text-slate-100"
                      >
                        {COMMUNICATION_EVENT_TYPES.map((type) => (
                          <option key={type} value={type}>{type.charAt(0).toUpperCase() + type.slice(1)}</option>
                        ))}
                      </NativeSelect>
                    </div>
                  ) : (
                    <div>
                      <h4 className="font-semibold text-sm text-slate-100">{event.title}</h4>
                      <p className="text-xs text-slate-400">{new Date(event.date).toLocaleDateString('en-US', { weekday: 'long', month: 'long', day: 'numeric', year: 'numeric' })}</p>
                      {isCancellationNotice && (
                        <p className="mt-1 text-xs font-medium text-rose-200">Cancellation notice</p>
                      )}
                    </div>
                  )}
                </div>
                <div className="flex shrink-0 flex-wrap items-center justify-end gap-2">
                  {isEditing ? (
                    <>
                      <Button type="button" onClick={() => { void saveEdit(); }} loading={updateEventMutation.isPending} className="flex items-center gap-1.5 rounded-lg bg-emerald-500/15 px-3 py-1.5 text-xs font-medium text-emerald-100 hover:bg-emerald-500/25">
                        <Save size={12} />
                        Save
                      </Button>
                      <Button type="button" onClick={() => setEditingEventId(null)} className="flex items-center gap-1.5 rounded-lg bg-slate-800 px-3 py-1.5 text-xs font-medium text-slate-300 hover:bg-slate-700">
                        <XCircle size={12} />
                        Close
                      </Button>
                    </>
                  ) : (
                    <>
                      {canMutate && (
                        <>
                          <Button type="button" onClick={() => startEdit(event)} className="flex items-center gap-1.5 rounded-lg bg-slate-800 px-3 py-1.5 text-xs font-medium text-slate-300 hover:bg-slate-700">
                            <Pencil size={12} />
                            Edit
                          </Button>
                          <Button type="button" onClick={() => openActionDialog('cancel', event)} loading={cancelEventMutation.isPending} className="flex items-center gap-1.5 rounded-lg bg-amber-500/15 px-3 py-1.5 text-xs font-medium text-amber-100 hover:bg-amber-500/25">
                            <XCircle size={12} />
                            Cancel
                          </Button>
                          <Button type="button" onClick={() => openActionDialog('delete', event)} loading={deleteEventMutation.isPending} className="flex items-center gap-1.5 rounded-lg bg-rose-500/15 px-3 py-1.5 text-xs font-medium text-rose-100 hover:bg-rose-500/25">
                            <Trash2 size={12} />
                            Delete
                          </Button>
                        </>
                      )}
                    </>
                  )}
                </div>
                </div>
              </div>
            );
          })}
        </div>
      )}
      {pendingAction && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-slate-950/75 px-4 backdrop-blur-sm">
          <div
            role="dialog"
            aria-modal="true"
            aria-labelledby="alert-action-title"
            className="w-full max-w-lg rounded-2xl border border-slate-700 bg-slate-900 p-5 shadow-2xl shadow-black/40"
          >
            <div className="flex items-start gap-3">
              <div className={`mt-0.5 flex h-10 w-10 shrink-0 items-center justify-center rounded-xl ${
                pendingAction.action === 'delete'
                  ? 'bg-rose-500/15 text-rose-100'
                  : 'bg-amber-500/15 text-amber-100'
              }`}
              >
                {pendingAction.action === 'delete' ? <Trash2 size={18} /> : <XCircle size={18} />}
              </div>
              <div className="min-w-0">
                <h3 id="alert-action-title" className="text-lg font-semibold text-slate-100">
                  {pendingAction.action === 'delete' ? 'Delete alert' : 'Cancel alert'}
                </h3>
                <p className="mt-1 text-sm text-slate-400">
                  {pendingAction.action === 'delete'
                    ? 'Delete this wrongly-created alert without notifying users.'
                    : 'Create a cancellation notification for the same audience and remove the original alert.'}
                </p>
                <p className="mt-3 truncate rounded-lg border border-slate-700 bg-slate-950/70 px-3 py-2 text-sm font-medium text-slate-200">
                  {pendingAction.title}
                </p>
              </div>
            </div>
            {pendingAction.action === 'cancel' && (
              <div className="mt-4">
                <label htmlFor="cancel-alert-reason" className="mb-2 block text-sm font-medium text-slate-200">
                  Cancellation reason
                </label>
                <Input
                  id="cancel-alert-reason"
                  type="text"
                  value={cancelReason}
                  onChange={(event) => setCancelReason(event.target.value)}
                  placeholder="Optional reason..."
                  className="h-11 rounded-xl border-slate-700 bg-slate-950/80 px-4 text-sm text-slate-100 placeholder:text-slate-500 focus-visible:ring-2 focus-visible:ring-amber-400 focus-visible:ring-offset-0"
                />
              </div>
            )}
            <div className="mt-5 flex flex-col-reverse gap-2 sm:flex-row sm:justify-end">
              <Button
                type="button"
                onClick={closeActionDialog}
                className="rounded-xl bg-slate-800 px-4 py-2 text-sm font-semibold text-slate-200 hover:bg-slate-700"
              >
                Keep alert
              </Button>
              <Button
                type="button"
                onClick={() => { void confirmAction(); }}
                loading={pendingAction.action === 'delete' ? deleteEventMutation.isPending : cancelEventMutation.isPending}
                className={`rounded-xl px-4 py-2 text-sm font-semibold text-white ${
                  pendingAction.action === 'delete'
                    ? 'bg-rose-600 hover:bg-rose-500'
                    : 'bg-amber-600 hover:bg-amber-500'
                }`}
              >
                {pendingAction.action === 'delete' ? 'Delete alert' : 'Cancel alert'}
              </Button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
