import { useEffect, useState } from 'react';

import { Box, Button, CircularProgress, FormControlLabel, Radio, RadioGroup } from '@mui/material';

import Dialog from '../../common/Dialog';
import { notify } from '../../common/notify';
import * as api from '../store/api';

interface VersionOption {
  label: string;
  version: string;
}

interface Props {
  onClose: () => void;
  onConfirm: (version: string) => void;
  open: boolean;
}

// Mirrors masterfilesVersionService.deriveMasterfilesVersionOptions: pick a
// sensible default masterfiles version based on the hub's CFEngine release and
// offer the alternatives (master / latest / matched release).
const deriveOptions = (
  release: { isAlpha: boolean; version: string },
  versions: Record<string, { latest?: boolean }>
): { options: VersionOption[]; selected: VersionOption } => {
  const latestVersion = Object.keys(versions).find(v => versions[v].latest) ?? '';
  const masterOption: VersionOption = { label: 'Master branch', version: 'master' };
  const latestOption: VersionOption = { label: `Latest (${latestVersion})`, version: latestVersion };

  let selected: VersionOption;
  let fallbacks: VersionOption[];

  if (Object.prototype.hasOwnProperty.call(versions, release.version)) {
    selected = { label: release.version, version: release.version };
    fallbacks = versions[release.version].latest ? [masterOption] : [latestOption, masterOption];
  } else if (release.isAlpha) {
    selected = masterOption;
    fallbacks = [latestOption];
  } else {
    selected = latestOption;
    fallbacks = [masterOption];
  }

  return { selected, options: [selected, ...fallbacks] };
};

export const MasterfilesVersionDialog = ({ open, onClose, onConfirm }: Props) => {
  const [options, setOptions] = useState<VersionOption[]>([]);
  const [selected, setSelected] = useState('');
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    if (!open) return;
    let cancelled = false;
    (async () => {
      setLoading(true);
      try {
        const [info] = await Promise.all([api.getHubInfo(), api.refreshModulesList()]);
        const module = await api.getModule('masterfiles');
        if (cancelled || !info.release) return;
        const derived = deriveOptions(info.release, module.versions ?? {});
        setOptions(derived.options);
        setSelected(derived.selected.version);
      } catch {
        if (!cancelled) notify.error('Unable to load masterfiles versions.');
      } finally {
        if (!cancelled) setLoading(false);
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [open]);

  return (
    <Dialog
      open={open}
      onClose={onClose}
      title="Which version of masterfiles would you like to use?"
      size="sm"
      fullWidth
      actionButtons={
        <>
          <Button onClick={onClose} variant="outlined" color="inherit">
            Close
          </Button>
          <Button onClick={() => onConfirm(selected)} variant="contained" disabled={!selected || loading}>
            Confirm
          </Button>
        </>
      }
    >
      {loading ? (
        <Box sx={{ display: 'flex', justifyContent: 'center', py: 3 }}>
          <CircularProgress />
        </Box>
      ) : (
        <RadioGroup value={selected} onChange={e => setSelected(e.target.value)}>
          {options.map(option => (
            <FormControlLabel key={option.version} value={option.version} control={<Radio />} label={option.label} />
          ))}
        </RadioGroup>
      )}
    </Dialog>
  );
};
