import { useEffect } from 'react';
import pluralize from 'pluralize';

import { useAppDispatch, useAppSelector } from '../store';
import { selectSoftwareSummary, selectStatusMeasured } from '../store/hostsSlice/selectors';
import { fetchSoftwareSummary, fetchStatusMeasured } from '../store/hostsSlice/thunks';
import type { HostInfo } from '../types';
import { formatTimestamp } from '../utils/formatTimestamp';
import { HostInfoRow } from './HostInfoRow';

interface Props {
  hostkey: string;
  info: HostInfo;
  isHub: boolean;
}

const formatHostTimestamp = (ts: number | undefined): string =>
  formatTimestamp(ts, { fallback: 'n/a' });



// Normalizes a network address value into a human-readable list.
// Accepts a single address string, an array of addresses, or a Postgres-style
// array literal like "{10.0.0.1,10.0.0.2}". Returns a comma-separated list,
// or "n/a" when the value is empty.
const formatAddresses = (addr: string | string[] | undefined): string => {
  if (!addr) return 'n/a';
  if (Array.isArray(addr)) return addr.join(', ');
  if (typeof addr === 'string' && addr.startsWith('{') && addr.endsWith('}')) {
    return addr.slice(1, -1).split(',').filter(Boolean).join(', ') || 'n/a';
  }
  return addr;
};

const formatPercent = (value: string | number | null | undefined): string => {
  if (value === null || value === undefined || value === '') return 'n/a';
  return `${value}%`;
};

export const HostInfoPanels = ({ hostkey, info, isHub }: Props) => {
  const dispatch = useAppDispatch();
  const software = useAppSelector(state => selectSoftwareSummary(state, hostkey));
  const status = useAppSelector(state => selectStatusMeasured(state, hostkey));

  useEffect(() => {
    if (!hostkey) return;
    dispatch(fetchSoftwareSummary(hostkey));
    dispatch(fetchStatusMeasured(hostkey));
  }, [dispatch, hostkey]);

  const cfengineVersion = (info.CFEngine?.Version as string | undefined) ?? 'n/a';
  const os = (info.System?.OS as string | undefined) ?? 'n/a';
  const ipv4 = formatAddresses(info.Network?.address);
  const collectionInitiator = info.iscallcollected ? 'Client' : 'Hub';
  const interval = info.agentexecutioninterval ?? 'n/a';
  const hostnameForLink = info.hostname || hostkey;

  const installedLink = software
    ? `/reports/report/run?state=${encodeURIComponent(software.installedState)}&title=${encodeURIComponent(`Software installed on ${hostnameForLink}`)}`
    : undefined;
  const availableLink = software
    ? `/reports/report/run?state=${encodeURIComponent(software.availableState)}&title=${encodeURIComponent(`Updates available on ${hostnameForLink}`)}`
    : undefined;

  return (
    <div className="row-fluid host-details">
      <div className="span6">
        <h4>CFEngine</h4>
        <HostInfoRow label="ID">
          <span className="host_id_SE">{hostkey}</span>
        </HostInfoRow>
        <HostInfoRow label="Version">{cfengineVersion}</HostInfoRow>
        <HostInfoRow label="Role">{isHub ? 'Hub' : 'Client'}</HostInfoRow>
        <HostInfoRow label="IP reported from">{info.ip || 'n/a'}</HostInfoRow>
        <HostInfoRow label="Initiated by">{collectionInitiator}</HostInfoRow>
        <HostInfoRow label="Average agent execution interval">
          {typeof interval === 'number' ? pluralize('second', interval, true) : String(interval)}
        </HostInfoRow>
        <HostInfoRow label="Last report">{formatHostTimestamp(info.lastreport)}</HostInfoRow>
        <HostInfoRow label="Last agent run">{formatHostTimestamp(info.lastAgentExecutionTime)}</HostInfoRow>
        <HostInfoRow label="First report">{formatHostTimestamp(info.firstreport)}</HostInfoRow>
      </div>

      <div className="span6">
        <h4>System</h4>
        <HostInfoRow label="OS">{os}</HostInfoRow>
        <HostInfoRow label="Hostname">
          <span className="host_alias">{info.hostname || 'n/a'}</span>
        </HostInfoRow>
        <HostInfoRow label="IPv4 addresses">{ipv4}</HostInfoRow>
        <HostInfoRow label="Installed packages">
          {software && installedLink ? (
            <a href={installedLink}>{software.installedCount}</a>
          ) : (
            '…'
          )}
        </HostInfoRow>
        <HostInfoRow label="Updates available">
          {software && availableLink ? (
            <a className="total_patches_available_SE" href={availableLink}>
              {software.availableCount}
            </a>
          ) : (
            '…'
          )}
        </HostInfoRow>

        <h4 style={{ marginTop: 16 }}>Status</h4>
        <HostInfoRow label="Average load">{formatPercent(status?.load)}</HostInfoRow>
        <HostInfoRow label="Average free disk">{formatPercent(status?.free)}</HostInfoRow>
      </div>
    </div>
  );
};
