import { useEffect, useMemo, useState } from 'react';
import { Sidebar } from '../../layout/components/Sidebar';
import { Topbar } from '../../layout/components/Topbar';
import type { NotificationInterface } from '../../../mvvm/models/notification.interface';
import type { NotificationSettingInterface } from '../../../mvvm/models/notification-setting.interface';
import type { OccupationCategorizationInterface, SubAreaInterface } from '../../../mvvm/models/occupation-categorization.interface';
import type { OccupationInterface } from '../../../mvvm/models/occupation.interface';
import { AiJobAgentViewModel } from '../../../mvvm/viewmodels/AiJobAgentViewModel';

interface AiJobAgentPageProps {
  onLogout: () => Promise<void>;
  onNavigate: (key: 'dashboard' | 'cv' | 'jobs' | 'beskeder' | 'ai-jobagent' | 'ai-agent' | 'simulator' | 'abonnement') => void;
  onOpenJob: (jobId: string, fromJobnet: boolean) => void;
}

type OccupationTree = OccupationCategorizationInterface[];

const PAGE_LIMIT = 20;

function createEmptySetting(): NotificationSettingInterface {
  return {
    id: null,
    jobAgentName: '',
    workTimeDay: false,
    workTimeEvening: false,
    workTimeNight: false,
    workTimeWeekend: false,
    workTypePermanent: false,
    workTypeFreelance: false,
    workTypePartTime: false,
    workTypeSubstitute: false,
    workTypeTemporary: false,
    workDistance: 50,
    distanceCenterName: '',
    latitude: null,
    longitude: null,
    partTimeHours: null,
    notifyOnPush: false,
    notifyOnSms: false,
    searchText: '',
    escoIds: [],
  };
}

function normalizeSetting(setting: NotificationSettingInterface): NotificationSettingInterface {
  return {
    ...createEmptySetting(),
    ...setting,
    id: setting.id ?? null,
    jobAgentName: setting.jobAgentName ?? '',
    distanceCenterName: setting.distanceCenterName ?? '',
    searchText: setting.searchText ?? '',
    escoIds: Array.isArray(setting.escoIds) ? setting.escoIds : [],
    workDistance: typeof setting.workDistance === 'number' ? setting.workDistance : 50,
  };
}

function mapTree(source: OccupationCategorizationInterface[]): OccupationTree {
  return source.map((area) => ({
    ...area,
    expanded: Boolean(area.expanded),
    activated: Boolean(area.activated),
    someIsActive: Boolean(area.someIsActive),
    subAreas: area.subAreas.map((subArea) => ({
      ...subArea,
      expanded: Boolean(subArea.expanded),
      activated: Boolean(subArea.activated),
      someIsActive: Boolean(subArea.someIsActive),
      occupations: subArea.occupations.map((occupation) => ({
        ...occupation,
        activated: Boolean(occupation.activated),
      })),
    })),
  }));
}

function applySelectedEscos(tree: OccupationTree, escoIds: number[]): OccupationTree {
  const selected = new Set(escoIds);
  return tree.map((area) => {
    const subAreas = area.subAreas.map((subArea) => {
      const occupations = subArea.occupations.map((occupation) => ({
        ...occupation,
        activated: selected.has(occupation.id),
      }));
      const activeCount = occupations.filter((occ) => occ.activated).length;
      return {
        ...subArea,
        occupations,
        activated: activeCount > 0 && activeCount === occupations.length,
        someIsActive: activeCount > 0 && activeCount < occupations.length,
      };
    });

    const allActive = subAreas.length > 0 && subAreas.every((item) => item.activated);
    const someActive = subAreas.some((item) => item.activated || item.someIsActive);
    return {
      ...area,
      subAreas,
      activated: allActive,
      someIsActive: someActive && !allActive,
    };
  });
}

function collectSelectedEscos(tree: OccupationTree): number[] {
  const ids: number[] = [];
  for (const area of tree) {
    for (const subArea of area.subAreas) {
      for (const occupation of subArea.occupations) {
        if (occupation.activated) {
          ids.push(occupation.id);
        }
      }
    }
  }
  return ids;
}

function formatDate(value: Date | string): string {
  const date = value instanceof Date ? value : new Date(value);
  if (Number.isNaN(date.getTime())) {
    return '';
  }
  return date.toLocaleDateString('da-DK', {
    day: '2-digit',
    month: 'short',
    year: 'numeric',
  });
}

function companyInitial(value: string | null | undefined): string {
  if (!value?.trim()) {
    return 'Ar';
  }
  return value.trim().slice(0, 1).toUpperCase();
}

function hasAnyActiveJobAgent(settings: NotificationSettingInterface[]): boolean {
  return settings.some((setting) => (setting.escoIds?.length ?? 0) > 0);
}

export function AiJobAgentPage({ onLogout, onNavigate, onOpenJob }: AiJobAgentPageProps) {
  const [sidebarCollapsed, setSidebarCollapsed] = useState(() => window.localStorage.getItem('arbejd.sidebar.collapsed') === '1');
  const [showSettings, setShowSettings] = useState(false);
  const [showWorkAreas, setShowWorkAreas] = useState(false);
  const [isLoadingSettings, setIsLoadingSettings] = useState(true);
  const [isLoadingNotifications, setIsLoadingNotifications] = useState(true);
  const [isLoadingMoreNotifications, setIsLoadingMoreNotifications] = useState(false);
  const [isSavingSetting, setIsSavingSetting] = useState(false);
  const [isSearchingPlaces, setIsSearchingPlaces] = useState(false);
  const [hasMoreNotifications, setHasMoreNotifications] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [notificationSettings, setNotificationSettings] = useState<NotificationSettingInterface[]>([]);
  const [notifications, setNotifications] = useState<NotificationInterface[]>([]);
  const [selectedJobAgentId, setSelectedJobAgentId] = useState<number | 'new'>('new');
  const [editingSetting, setEditingSetting] = useState<NotificationSettingInterface>(createEmptySetting());
  const [occupationTree, setOccupationTree] = useState<OccupationTree>([]);
  const [searchOccupationWord, setSearchOccupationWord] = useState('');
  const [placeSuggestions, setPlaceSuggestions] = useState<Array<{ place_id?: string; description?: string }>>([]);
  const viewModel = useMemo(() => new AiJobAgentViewModel(), []);

  useEffect(() => {
    let active = true;

    async function bootstrap() {
      setError(null);
      setIsLoadingSettings(true);
      setIsLoadingNotifications(true);
      try {
        const [settings, rawTree, firstNotifications] = await Promise.all([
          viewModel.getNotificationSettings(),
          viewModel.getOccupationTree(),
          viewModel.getNotifications(0, PAGE_LIMIT),
        ]);

        if (!active) {
          return;
        }

        const normalizedSettings = settings.map(normalizeSetting);
        const mappedTree = mapTree(rawTree);
        const initialSetting = normalizedSettings[0] ?? createEmptySetting();
        const initialId = normalizedSettings[0]?.id ?? 'new';

        setNotificationSettings(normalizedSettings);
        setSelectedJobAgentId(initialId);
        setEditingSetting(initialSetting);
        setOccupationTree(applySelectedEscos(mappedTree, initialSetting.escoIds));
        setNotifications(firstNotifications);
        setHasMoreNotifications(firstNotifications.length === PAGE_LIMIT);
      } catch (loadError) {
        if (!active) {
          return;
        }
        setError(loadError instanceof Error ? loadError.message : 'Kunne ikke indlæse AI JobAgent.');
      } finally {
        if (active) {
          setIsLoadingSettings(false);
          setIsLoadingNotifications(false);
        }
      }
    }

    void bootstrap();
    return () => {
      active = false;
    };
  }, [viewModel]);

  useEffect(() => {
    const query = editingSetting.distanceCenterName?.trim() ?? '';
    if (!showSettings || query.length < 3) {
      setPlaceSuggestions([]);
      return;
    }

    const timeout = window.setTimeout(() => {
      setIsSearchingPlaces(true);
      void viewModel
        .searchPlaces(query)
        .then((suggestions) => {
          setPlaceSuggestions(suggestions);
        })
        .catch(() => {
          setPlaceSuggestions([]);
        })
        .finally(() => setIsSearchingPlaces(false));
    }, 350);

    return () => window.clearTimeout(timeout);
  }, [editingSetting.distanceCenterName, showSettings, viewModel]);

  const filteredOccupations = useMemo(() => {
    const query = searchOccupationWord.trim().toLowerCase();
    if (!query) {
      return [];
    }
    const list: Array<{ areaCode: number; subAreaCode: number; occupation: OccupationInterface }> = [];
    for (const area of occupationTree) {
      for (const subArea of area.subAreas) {
        for (const occupation of subArea.occupations) {
          if (occupation.name.toLowerCase().includes(query)) {
            list.push({ areaCode: area.areaCode, subAreaCode: subArea.subAreaCode, occupation });
          }
        }
      }
    }
    return list.slice(0, 40);
  }, [occupationTree, searchOccupationWord]);

  const selectedEscoCount = useMemo(() => collectSelectedEscos(occupationTree).length, [occupationTree]);
  const unseenCount = useMemo(
    () => notifications.filter((notification) => !notification.seenByUser).length,
    [notifications],
  );

  function selectJobAgent(value: number | 'new') {
    setSelectedJobAgentId(value);
    setShowWorkAreas(false);
    setSearchOccupationWord('');

    if (value === 'new') {
      const empty = createEmptySetting();
      setEditingSetting(empty);
      setOccupationTree((prev) => applySelectedEscos(prev, []));
      return;
    }

    const setting = notificationSettings.find((item) => item.id === value);
    const normalized = normalizeSetting(setting ?? createEmptySetting());
    setEditingSetting(normalized);
    setOccupationTree((prev) => applySelectedEscos(prev, normalized.escoIds));
  }

  function updateTreeByArea(areaCode: number, active: boolean) {
    setOccupationTree((prev) =>
      prev.map((area) => {
        if (area.areaCode !== areaCode) {
          return area;
        }
        const subAreas = area.subAreas.map((subArea) => ({
          ...subArea,
          activated: active,
          someIsActive: false,
          occupations: subArea.occupations.map((occupation) => ({
            ...occupation,
            activated: active,
          })),
        }));
        return {
          ...area,
          subAreas,
          activated: active,
          someIsActive: false,
        };
      }),
    );
  }

  function updateTreeBySubArea(areaCode: number, subAreaCode: number, active: boolean) {
    setOccupationTree((prev) =>
      prev.map((area) => {
        if (area.areaCode !== areaCode) {
          return area;
        }

        const subAreas = area.subAreas.map((subArea) => {
          if (subArea.subAreaCode !== subAreaCode) {
            return subArea;
          }
          return {
            ...subArea,
            activated: active,
            someIsActive: false,
            occupations: subArea.occupations.map((occupation) => ({
              ...occupation,
              activated: active,
            })),
          };
        });

        const allActive = subAreas.length > 0 && subAreas.every((item) => item.activated);
        const someActive = subAreas.some((item) => item.activated || item.someIsActive);

        return {
          ...area,
          subAreas,
          activated: allActive,
          someIsActive: someActive && !allActive,
        };
      }),
    );
  }

  function updateTreeByOccupation(areaCode: number, subAreaCode: number, occupationId: number) {
    setOccupationTree((prev) =>
      prev.map((area) => {
        if (area.areaCode !== areaCode) {
          return area;
        }

        const subAreas = area.subAreas.map((subArea) => {
          if (subArea.subAreaCode !== subAreaCode) {
            return subArea;
          }

          const occupations = subArea.occupations.map((occupation) =>
            occupation.id === occupationId
              ? { ...occupation, activated: !occupation.activated }
              : occupation,
          );

          const activeCount = occupations.filter((occupation) => occupation.activated).length;
          return {
            ...subArea,
            occupations,
            activated: activeCount > 0 && activeCount === occupations.length,
            someIsActive: activeCount > 0 && activeCount < occupations.length,
          };
        });

        const allActive = subAreas.length > 0 && subAreas.every((item) => item.activated);
        const someActive = subAreas.some((item) => item.activated || item.someIsActive);
        return {
          ...area,
          subAreas,
          activated: allActive,
          someIsActive: someActive && !allActive,
        };
      }),
    );
  }

  async function saveSetting() {
    if (!editingSetting.jobAgentName?.trim()) {
      return;
    }
    setIsSavingSetting(true);
    setError(null);
    try {
      const payload: NotificationSettingInterface = {
        ...editingSetting,
        jobAgentName: editingSetting.jobAgentName.trim(),
        searchText: editingSetting.searchText?.trim() || null,
        distanceCenterName: editingSetting.distanceCenterName?.trim() || null,
        escoIds: collectSelectedEscos(occupationTree),
      };

      await viewModel.saveNotificationSetting(selectedJobAgentId, payload);
      const settings = (await viewModel.getNotificationSettings()).map(normalizeSetting);
      setNotificationSettings(settings);

      if (selectedJobAgentId === 'new') {
        const created = settings.find((item) => item.jobAgentName === payload.jobAgentName) ?? settings[0];
        if (created?.id != null) {
          setSelectedJobAgentId(created.id);
          setEditingSetting(created);
          setOccupationTree((prev) => applySelectedEscos(prev, created.escoIds));
        }
      } else {
        const updated = settings.find((item) => item.id === selectedJobAgentId);
        if (updated) {
          setEditingSetting(updated);
          setOccupationTree((prev) => applySelectedEscos(prev, updated.escoIds));
        }
      }

      setShowSettings(false);
      setShowWorkAreas(false);
    } catch (saveError) {
      setError(saveError instanceof Error ? saveError.message : 'Kunne ikke gemme jobagent indstillinger.');
    } finally {
      setIsSavingSetting(false);
    }
  }

  async function deleteCurrentSetting() {
    if (selectedJobAgentId === 'new') {
      return;
    }
    setIsSavingSetting(true);
    setError(null);
    try {
      await viewModel.deleteNotificationSetting(selectedJobAgentId);
      const settings = (await viewModel.getNotificationSettings()).map(normalizeSetting);
      setNotificationSettings(settings);
      const next = settings[0] ?? createEmptySetting();
      setSelectedJobAgentId(settings[0]?.id ?? 'new');
      setEditingSetting(next);
      setOccupationTree((prev) => applySelectedEscos(prev, next.escoIds));
    } catch (deleteError) {
      setError(deleteError instanceof Error ? deleteError.message : 'Kunne ikke slette jobagent.');
    } finally {
      setIsSavingSetting(false);
    }
  }

  async function selectPlaceSuggestion(placeId: string) {
    const details = await viewModel.getPlaceDetails(placeId);
    if (!details) {
      return;
    }
    setEditingSetting((prev) => ({
      ...prev,
      distanceCenterName: details.address,
      latitude: details.latitude,
      longitude: details.longitude,
    }));
    setPlaceSuggestions([]);
  }

  async function openNotificationJob(notification: NotificationInterface) {
    if (!notification.seenByUser) {
      void viewModel.markNotificationSeen(notification.id);
      setNotifications((prev) =>
        prev.map((item) => (item.id === notification.id ? { ...item, seenByUser: true } : item)),
      );
    }

    const fromJobnet = Boolean(notification.jobnetPostingId);
    const jobId = fromJobnet ? notification.jobnetPostingId : notification.jobPostingId;
    if (jobId) {
      onOpenJob(jobId, fromJobnet);
    }
  }

  async function toggleNotificationBookmark(notification: NotificationInterface) {
    const save = !notification.saved;
    try {
      await viewModel.toggleNotificationBookmark(notification, save);
      setNotifications((prev) =>
        prev.map((item) => (item.id === notification.id ? { ...item, saved: save } : item)),
      );
    } catch {
      setError('Kunne ikke opdatere gemt status på notifikation.');
    }
  }

  async function loadMoreNotifications() {
    if (!hasMoreNotifications || isLoadingMoreNotifications) {
      return;
    }
    setIsLoadingMoreNotifications(true);
    setError(null);
    try {
      const next = await viewModel.getNotifications(notifications.length, PAGE_LIMIT);
      setNotifications((prev) => [...prev, ...next]);
      setHasMoreNotifications(next.length === PAGE_LIMIT);
    } catch (loadError) {
      setError(loadError instanceof Error ? loadError.message : 'Kunne ikke indlæse flere notifikationer.');
    } finally {
      setIsLoadingMoreNotifications(false);
    }
  }

  return (
    <section className="dashboard-layout">
      <Sidebar
        collapsed={sidebarCollapsed}
        activeKey="ai-jobagent"
        onToggle={() => setSidebarCollapsed((prev) => { const next = !prev; window.localStorage.setItem('arbejd.sidebar.collapsed', next ? '1' : '0'); return next; })}
        onSelect={(key) => {
          if (key === 'dashboard' || key === 'cv' || key === 'jobs' || key === 'beskeder' || key === 'ai-jobagent' || key === 'ai-agent' || key === 'simulator' || key === 'abonnement') {
            onNavigate(key);
          }
        }}
      />

      <main className="dashboard-main">
        <Topbar title="AI JobAgent" userName="Anders Jensen" planLabel="Jobseeker Pro" onLogout={onLogout} />

        <div className="dashboard-scroll">
          {error ? <p className="status error">{error}</p> : null}

          <article className="glass-panel dash-card jobagent-hero-card">
            <div className="jobagent-hero-top">
              <div>
                <span className="jobagent-kicker">AI JobAgent</span>
                <h3>Automatisk jobmatch med dit CV</h3>
                <p>
                  Jobagenten følger nye opslag og fremhæver relevante job baseret på dine valgte områder,
                  arbejdstype og afstand.
                </p>
              </div>
              <button
                type="button"
                className="primary-btn"
                onClick={() => setShowSettings((prev) => !prev)}
                disabled={isLoadingSettings}
              >
                {showSettings ? 'Luk indstillinger' : 'Åbn indstillinger'}
              </button>
            </div>

            {!isLoadingSettings ? (
              <div className="jobagent-hero-metrics">
                <div className="jobagent-metric-pill">
                  <span>Jobagenter</span>
                  <strong>{notificationSettings.length}</strong>
                </div>
                <div className="jobagent-metric-pill">
                  <span>Aktive filtre</span>
                  <strong>{selectedEscoCount}</strong>
                </div>
                <div className="jobagent-metric-pill">
                  <span>Nye notifikationer</span>
                  <strong>{unseenCount}</strong>
                </div>
                <p className="jobagent-summary-note">
                  {hasAnyActiveJobAgent(notificationSettings)
                    ? 'Mindst én jobagent er aktiv.'
                    : 'Vælg stillingstyper og områder for at aktivere en jobagent.'}
                </p>
              </div>
            ) : (
              <p className="jobagent-summary-note">Indlæser jobagenter...</p>
            )}
          </article>

          <section className="jobagent-layout-grid">
            {showSettings ? (
              <article className="glass-panel dash-card jobagent-settings-card">
                <div className="jobagent-settings-top">
                  <div>
                    <span className="jobagent-kicker">Opsaetning</span>
                    <h4>Jobagent indstillinger</h4>
                  </div>
                  <div className="jobagent-settings-actions">
                    {selectedJobAgentId !== 'new' ? (
                      <button type="button" className="secondary-btn danger" onClick={() => void deleteCurrentSetting()} disabled={isSavingSetting}>
                        Slet
                      </button>
                    ) : null}
                    <button type="button" className="primary-btn" onClick={() => void saveSetting()} disabled={isSavingSetting || !editingSetting.jobAgentName?.trim()}>
                      {isSavingSetting ? 'Gemmer...' : 'Gem'}
                    </button>
                  </div>
                </div>

                <div className="jobagent-settings-grid">
                  <label className="jobagent-field">
                    <span>Vælg jobagent</span>
                    <select
                      className="field-input"
                      value={selectedJobAgentId === 'new' ? 'new' : String(selectedJobAgentId)}
                      onChange={(event) => {
                        const value = event.target.value;
                        selectJobAgent(value === 'new' ? 'new' : Number(value));
                      }}
                    >
                      {notificationSettings.map((setting) => (
                        <option key={setting.id ?? Math.random()} value={String(setting.id)}>
                          {setting.jobAgentName?.trim() || 'Uden navn'}
                        </option>
                      ))}
                      <option value="new">Opret ny jobagent</option>
                    </select>
                  </label>

                  <label className="jobagent-field">
                    <span>Jobagent navn</span>
                    <input
                      className="field-input"
                      value={editingSetting.jobAgentName ?? ''}
                      onChange={(event) => setEditingSetting((prev) => ({ ...prev, jobAgentName: event.target.value }))}
                      placeholder="Fx. Min jobagent"
                    />
                  </label>

                  <label className="jobagent-field">
                    <span>Søgetekst</span>
                    <input
                      className="field-input"
                      value={editingSetting.searchText ?? ''}
                      onChange={(event) => setEditingSetting((prev) => ({ ...prev, searchText: event.target.value }))}
                      placeholder="Fritekst til søgning"
                    />
                  </label>

                  <div className="jobagent-field">
                    <span>Arbejdsområder</span>
                    <button type="button" className="secondary-btn" onClick={() => setShowWorkAreas((prev) => !prev)}>
                      {showWorkAreas ? 'Luk arbejdsområder' : 'Åbn arbejdsområder'}
                    </button>
                  </div>

                  <div className="jobagent-field">
                    <span>Arbejdstype</span>
                    <div className="jobagent-toggle-row">
                      <button
                        type="button"
                        className={editingSetting.workTypePermanent ? 'tab-btn active' : 'tab-btn'}
                        onClick={() => setEditingSetting((prev) => ({ ...prev, workTypePermanent: !prev.workTypePermanent }))}
                      >
                        Fast
                      </button>
                      <button
                        type="button"
                        className={editingSetting.workTypePartTime ? 'tab-btn active' : 'tab-btn'}
                        onClick={() => setEditingSetting((prev) => ({ ...prev, workTypePartTime: !prev.workTypePartTime }))}
                      >
                        Deltid
                      </button>
                    </div>
                    {editingSetting.workTypePartTime ? (
                      <input
                        type="number"
                        min={0}
                        max={37}
                        className="field-input"
                        value={editingSetting.partTimeHours ?? ''}
                        onChange={(event) =>
                          setEditingSetting((prev) => ({
                            ...prev,
                            partTimeHours: event.target.value ? Number(event.target.value) : null,
                          }))
                        }
                        placeholder="Timer pr. uge"
                      />
                    ) : null}
                  </div>

                  <div className="jobagent-field jobagent-location-field">
                    <span>Center for afstand</span>
                    <input
                      className="field-input"
                      value={editingSetting.distanceCenterName ?? ''}
                      onChange={(event) =>
                        setEditingSetting((prev) => ({
                          ...prev,
                          distanceCenterName: event.target.value,
                          latitude: null,
                          longitude: null,
                        }))
                      }
                      placeholder="Søg adresse"
                    />
                    {isSearchingPlaces ? <small>Søger adresser...</small> : null}
                    {placeSuggestions.length > 0 ? (
                      <div className="jobagent-place-suggestions glass-panel">
                        {placeSuggestions.map((suggestion) => (
                          <button
                            key={`${suggestion.place_id}-${suggestion.description}`}
                            type="button"
                            onClick={() => suggestion.place_id && void selectPlaceSuggestion(suggestion.place_id)}
                          >
                            {suggestion.description}
                          </button>
                        ))}
                      </div>
                    ) : null}
                  </div>

                  <div className="jobagent-field jobagent-distance-field">
                    <span>Arbejdsafstand: {editingSetting.workDistance ?? 50} km</span>
                    <input
                      type="range"
                      min={0}
                      max={500}
                      value={editingSetting.workDistance ?? 50}
                      onChange={(event) => setEditingSetting((prev) => ({ ...prev, workDistance: Number(event.target.value) }))}
                    />
                  </div>
                </div>

                {showWorkAreas ? (
                  <section className="jobagent-workareas-card">
                    <div className="jobagent-workareas-top">
                      <h5>Arbejdsområder</h5>
                      <span>{selectedEscoCount} valgt</span>
                    </div>
                    <div className="jobagent-workareas">
                      <input
                        className="field-input"
                        value={searchOccupationWord}
                        onChange={(event) => setSearchOccupationWord(event.target.value)}
                        placeholder="Søg arbejdsområde"
                      />

                      {searchOccupationWord.trim() && filteredOccupations.length > 0 ? (
                        <div className="jobagent-workareas-search-list">
                          {filteredOccupations.map((entry) => (
                            <label key={`${entry.areaCode}-${entry.subAreaCode}-${entry.occupation.id}`} className="jobagent-checkline">
                              <input
                                type="checkbox"
                                checked={Boolean(entry.occupation.activated)}
                                onChange={() => updateTreeByOccupation(entry.areaCode, entry.subAreaCode, entry.occupation.id)}
                              />
                              <span>{entry.occupation.name}</span>
                            </label>
                          ))}
                        </div>
                      ) : (
                        <div className="jobagent-workareas-tree">
                          {occupationTree.map((area) => (
                            <div key={area.areaCode} className="jobagent-workarea-node">
                              <div className="jobagent-workarea-row">
                                <button type="button" className="jobagent-expand-btn" onClick={() =>
                                  setOccupationTree((prev) => prev.map((item) => item.areaCode === area.areaCode ? { ...item, expanded: !item.expanded } : item))
                                }>
                                  {area.expanded ? '▾' : '▸'}
                                </button>
                                <label className="jobagent-checkline">
                                  <input
                                    type="checkbox"
                                    checked={area.activated || area.someIsActive}
                                    onChange={() => updateTreeByArea(area.areaCode, !(area.activated || area.someIsActive))}
                                  />
                                  <span>{area.areaName}</span>
                                </label>
                              </div>

                              {area.expanded ? (
                                <div className="jobagent-workarea-children">
                                  {area.subAreas.map((subArea: SubAreaInterface) => (
                                    <div key={`${area.areaCode}-${subArea.subAreaCode}`} className="jobagent-workarea-node">
                                      <div className="jobagent-workarea-row">
                                        <button type="button" className="jobagent-expand-btn" onClick={() =>
                                          setOccupationTree((prev) =>
                                            prev.map((item) =>
                                              item.areaCode === area.areaCode
                                                ? {
                                                    ...item,
                                                    subAreas: item.subAreas.map((child) =>
                                                      child.subAreaCode === subArea.subAreaCode ? { ...child, expanded: !child.expanded } : child,
                                                    ),
                                                  }
                                                : item,
                                            ),
                                          )
                                        }>
                                          {subArea.expanded ? '▾' : '▸'}
                                        </button>
                                        <label className="jobagent-checkline">
                                          <input
                                            type="checkbox"
                                            checked={subArea.activated || subArea.someIsActive}
                                            onChange={() => updateTreeBySubArea(area.areaCode, subArea.subAreaCode, !(subArea.activated || subArea.someIsActive))}
                                          />
                                          <span>{subArea.subAreaName}</span>
                                        </label>
                                      </div>

                                      {subArea.expanded ? (
                                        <div className="jobagent-workarea-children">
                                          {subArea.occupations.map((occupation) => (
                                            <label key={occupation.id} className="jobagent-checkline">
                                              <input
                                                type="checkbox"
                                                checked={Boolean(occupation.activated)}
                                                onChange={() => updateTreeByOccupation(area.areaCode, subArea.subAreaCode, occupation.id)}
                                              />
                                              <span>{occupation.name}</span>
                                            </label>
                                          ))}
                                        </div>
                                      ) : null}
                                    </div>
                                  ))}
                                </div>
                              ) : null}
                            </div>
                          ))}
                        </div>
                      )}
                    </div>
                  </section>
                ) : null}
              </article>
            ) : null}

            <article className="glass-panel dash-card jobagent-notifications-card">
              <div className="jobagent-notifications-top">
                <div>
                  <span className="jobagent-kicker">Live feed</span>
                  <h4>Notifikationer</h4>
                </div>
                <span className="jobagent-notification-count">{notifications.length}</span>
              </div>
              {isLoadingNotifications ? <p>Indlæser notifikationer...</p> : null}

              {!isLoadingNotifications && notifications.length === 0 ? (
                <p>Ingen notifikationer endnu.</p>
              ) : null}

              <div className="jobagent-notification-list">
                <div className="jobs-results-grid jobagent-results-grid">
                  {notifications.map((notification) => (
                    <article
                      key={notification.id}
                      className={notification.seenByUser ? 'glass-panel jobs-result-card jobagent-result-card' : 'glass-panel jobs-result-card jobagent-result-card unseen'}
                      role="button"
                      tabIndex={0}
                      onClick={() => void openNotificationJob(notification)}
                      onKeyDown={(event) => {
                        if (event.key === 'Enter' || event.key === ' ') {
                          event.preventDefault();
                          void openNotificationJob(notification);
                        }
                      }}
                    >
                      <div className="jobs-result-top">
                        <div className="jobs-result-brand">
                          {notification.logoUrl ? (
                            <img className="jobs-result-logo-img" src={notification.logoUrl} alt={notification.companyName || 'Virksomhed'} />
                          ) : (
                            <div className="jobs-result-logo">{companyInitial(notification.companyName)}</div>
                          )}
                          <div>
                            <p className="jobs-result-company">{notification.companyName || 'Ukendt virksomhed'}</p>
                            <p className="jobs-result-address">
                              {notification.city ? `${notification.city} ${notification.zip || ''}` : 'Ukendt lokation'}
                            </p>
                          </div>
                        </div>
                        <button
                          type="button"
                          className={notification.saved ? 'jobs-bookmark-icon active' : 'jobs-bookmark-icon'}
                          onMouseDown={(event) => event.stopPropagation()}
                          onClickCapture={(event) => event.stopPropagation()}
                          onClick={() => void toggleNotificationBookmark(notification)}
                          aria-label={notification.saved ? 'Fjern gemt job' : 'Gem job'}
                          title={notification.saved ? 'Fjern gemt' : 'Gem job'}
                        >
                          {notification.saved ? '★' : '☆'}
                        </button>
                      </div>

                      <h5 className="jobs-result-title">{notification.jobTitle || 'Jobagent match'}</h5>
                      <p className="jobs-result-occupation">{notification.escoTitle || 'AI JobAgent forslag'}</p>
                      <p className="jobs-result-description">
                        {notification.seenByUser ? 'Match fra din jobagent baseret på dine valgte filtre.' : 'Nyt match fra din jobagent.'}
                      </p>

                      <div className="jobs-result-tags">
                        <span className="chip">{formatDate(notification.notificationDate)}</span>
                        {notification.distance ? <span className="chip">{Number(notification.distance).toFixed(1)} km</span> : null}
                        <span className="chip">{notification.seenByUser ? 'Set' : 'Ny'}</span>
                      </div>

                      <div className="jobs-result-footer">
                        <button
                          type="button"
                          className="primary-btn jobs-card-primary-btn"
                          onClick={(event) => {
                            event.stopPropagation();
                            void openNotificationJob(notification);
                          }}
                        >
                          Åbn job
                        </button>
                      </div>
                    </article>
                  ))}
                </div>
              </div>

              {hasMoreNotifications ? (
                <button type="button" className="secondary-btn jobagent-load-more" onClick={() => void loadMoreNotifications()} disabled={isLoadingMoreNotifications}>
                  {isLoadingMoreNotifications ? 'Indlæser...' : 'Indlæs flere'}
                </button>
              ) : null}
            </article>
          </section>
        </div>
      </main>
    </section>
  );
}
