import {
  Divider,
  FormControl,
  IconButton,
  MenuItem,
  OutlinedInput,
  Select,
  type SelectChangeEvent
} from '@mui/material';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import { makeStyles } from 'tss-react/mui';

import type { Profile } from './types';
import { isTrue } from './utils';

// Sentinel values for the non-profile menu rows. They are never persisted as
// the Select value (the parent only tracks a profile id / null), so picking
// one just fires its action and the displayed value stays put.
const UNCATEGORIZED = '__uncategorized__';
const ADD_NEW = '__add_new__';
const EDIT_SUBSCRIPTIONS = '__edit_subscriptions__';

const useStyles = makeStyles()(theme => ({
  // Match the host-specific-data "Type" select (CmdbCreate): 32px outlined
  // control with the chevron nudged in.
  root: {
    '& .MuiSelect-root.MuiOutlinedInput-root': {
      height: 32
    },
    '& .MuiSelect-icon': {
      right: 8
    }
  },
  rowLabel: {
    flex: 1,
    overflow: 'hidden',
    textOverflow: 'ellipsis',
    whiteSpace: 'nowrap'
  },
  rowAction: {
    opacity: 0,
    color: theme.palette.text.muted,
    '&:hover': {
      color: theme.palette.red[700]
    },
    'li:hover > &': {
      opacity: 1
    }
  }
}));

interface Props {
  profiles: Profile[];
  selectedId: number | string | null;
  disabled?: boolean;
  onSelect: (profile: Profile | null) => void;
  onAddNew: () => void;
  onEditSubscriptions: () => void;
  onEditProfile?: (profile: Profile) => void;
  onDeleteProfile?: (profile: Profile) => void;
}

// Backend returns `shared` / `global` on the list endpoint; some older
// endpoints use `sharedTree` / `globalTree`. Accept either spelling.
const isShared = (p: Profile) => isTrue(p.shared) || isTrue(p.sharedTree);
const isGlobal = (p: Profile) => isTrue(p.global) || isTrue(p.globalTree);

const profileKey = (p: Profile) => `${p.id}::${p.sharedFrom ?? ''}`;

export const ProfileDropdown = ({
  profiles,
  selectedId,
  disabled,
  onSelect,
  onAddNew,
  onEditSubscriptions,
  onEditProfile,
  onDeleteProfile
}: Props) => {
  const { classes, cx } = useStyles();

  const selectedProfile =
    selectedId === null ? null : profiles.find(p => String(p.id) === String(selectedId)) ?? null;
  const value = selectedProfile ? profileKey(selectedProfile) : UNCATEGORIZED;

  const handleChange = (e: SelectChangeEvent) => {
    const v = e.target.value;
    if (v === ADD_NEW) return onAddNew();
    if (v === EDIT_SUBSCRIPTIONS) return onEditSubscriptions();
    if (v === UNCATEGORIZED) return onSelect(null);
    const profile = profiles.find(p => profileKey(p) === v);
    onSelect(profile ?? null);
  };

  return (
    <FormControl fullWidth size="small" className={cx(classes.root, 'categorization-select')}>
      <Select
        value={value}
        disabled={disabled}
        onChange={handleChange}
        displayEmpty
        IconComponent={ExpandMoreIcon}
        input={<OutlinedInput />}
        MenuProps={{
          anchorOrigin: { vertical: 'bottom', horizontal: 'left' },
          transformOrigin: { vertical: 'top', horizontal: 'left' }
        }}
        renderValue={() => (
          <span className="selectedLabel">{selectedProfile?.name ?? 'Uncategorized'}</span>
        )}
      >
        {profiles.map(p => {
          const isOwn = !isShared(p) && !isGlobal(p);
          return (
            <MenuItem key={profileKey(p)} value={profileKey(p)}>
              <i className={isOwn ? 'bi bi-person' : 'bi bi-box-arrow-up-right'} />
              <span className={classes.rowLabel} style={{ marginLeft: 8 }}>
                {p.name}
              </span>
              {isOwn && onEditProfile && (
                <IconButton
                  size="small"
                  className={classes.rowAction}
                  title="Edit categorization"
                  onMouseDown={e => e.stopPropagation()}
                  onClick={e => {
                    e.stopPropagation();
                    onEditProfile(p);
                  }}
                >
                  <i className="bi bi-pencil-fill" />
                </IconButton>
              )}
              {isOwn && onDeleteProfile && (
                <IconButton
                  size="small"
                  className={classes.rowAction}
                  title="Delete categorization"
                  onMouseDown={e => e.stopPropagation()}
                  onClick={e => {
                    e.stopPropagation();
                    onDeleteProfile(p);
                  }}
                >
                  <i className="bi bi-x" />
                </IconButton>
              )}
            </MenuItem>
          );
        })}

        <MenuItem value={UNCATEGORIZED}>Uncategorized</MenuItem>

        <Divider />

        <MenuItem value={ADD_NEW} className="addButton">
          Add new categorization
        </MenuItem>
        <MenuItem value={EDIT_SUBSCRIPTIONS}>Edit subscriptions</MenuItem>
      </Select>
    </FormControl>
  );
};
