import { useState } from 'react';

import { IconExternalLink } from '@material-hu/icons/tabler';
import Button from '@material-hu/mui/Button';
import IconButton from '@material-hu/mui/IconButton';
import Stack from '@material-hu/mui/Stack';
import { useTheme } from '@material-hu/mui/styles';
import Typography from '@material-hu/mui/Typography';

import Link from '@material-hu/components/design-system/Link';
import Title from '@material-hu/components/design-system/Title';

import useFormatDate from 'src/hooks/useFormatDate';
import { useLokaliseTranslation } from 'src/utils/i18n';

import {
  type FieldDto,
  type JobApplicationFormFieldAnswer,
  JobApplicationFormFieldInputType,
} from '../../../../types';
import {
  getApplicationFormFieldLabel,
  getApplicationFormSelectOptionLabel,
} from '../../../utils';
import { FIELD_DISPLAY_RULES } from '../../constants/profileDisplayRules';

type ProfileFieldValueProps = {
  field: FieldDto;
  sectionCode: string;
  answer: JobApplicationFormFieldAnswer | null;
};

export const ProfileFieldValue = ({
  field,
  sectionCode,
  answer,
}: ProfileFieldValueProps) => {
  const { t } = useLokaliseTranslation(['ats', 'careers_site']);
  const { formatDate } = useFormatDate();
  const theme = useTheme();
  const [expanded, setExpanded] = useState(false);
  const sxAnswer = {
    '& .MuiTypography-globalS': {
      fontSize: theme.typography.globalXS?.fontSize,
    },
  };
  const label = getApplicationFormFieldLabel(field, t, sectionCode);
  const displayRule = FIELD_DISPLAY_RULES[field.code];

  if (
    displayRule === 'file-link' ||
    field.inputType === JobApplicationFormFieldInputType.FILE
  ) {
    const fileAsset =
      answer?.value != null &&
      typeof answer.value === 'object' &&
      'url' in (answer.value as object)
        ? (answer.value as { url: string; name: string })
        : null;
    const fileUrl = fileAsset?.url ?? null;
    const fileName = fileAsset?.name ?? field.label;
    if (!fileUrl) {
      return (
        <Title
          copetin={label}
          title="—"
          variant="S"
          sx={sxAnswer}
        />
      );
    }
    return (
      <Stack
        sx={{
          flexDirection: 'row',
          alignItems: 'flex-end',
          justifyContent: 'space-between',
        }}
      >
        <Title
          copetin={label}
          title={
            <Link
              href={fileUrl}
              target="_blank"
              rel="noopener noreferrer"
              sx={{
                '&:visited': {
                  color: theme =>
                    theme.palette.new.action.button.background.primary.default,
                },
              }}
            >
              {fileName}
            </Link>
          }
          variant="S"
          withEllipsis
          sx={sxAnswer}
        />
        <IconButton
          size="small"
          onClick={() => window.open(fileUrl, '_blank', 'noopener,noreferrer')}
          aria-label={fileName}
        >
          <IconExternalLink size={24} />
        </IconButton>
      </Stack>
    );
  }

  if (field.inputType === JobApplicationFormFieldInputType.DATE) {
    const formatted = answer?.value
      ? formatDate(String(answer.value), 'dd/MM/yyyy')
      : '—';
    return (
      <Title
        copetin={label}
        title={formatted}
        variant="S"
        sx={sxAnswer}
      />
    );
  }

  if (field.inputType === JobApplicationFormFieldInputType.TEXT_AREA) {
    const text = answer?.value ? String(answer.value) : null;
    if (!text) {
      return (
        <Title
          copetin={label}
          title="—"
          variant="S"
          sx={sxAnswer}
        />
      );
    }
    const isLong = text.length > 80;
    return (
      <Stack sx={{ gap: 0.25, minWidth: 0 }}>
        <Stack
          sx={{
            flexDirection: 'row',
            alignItems: 'center',
            justifyContent: 'space-between',
          }}
        >
          <Typography
            variant="globalXXS"
            sx={{ color: theme => theme.palette.new.text.neutral.lighter }}
          >
            {label}
          </Typography>
          {isLong && (
            <Button
              variant="text"
              size="small"
              sx={{
                flexShrink: 0,
                p: 0,
                minWidth: 0,
                minHeight: 0,
                height: 'fit-content',
              }}
              onClick={() => setExpanded(prev => !prev)}
            >
              {expanded ? t('general:see_less') : t('general:see_more')}
            </Button>
          )}
        </Stack>
        {isLong && !expanded && (
          <Typography
            variant="globalS"
            noWrap
            sx={{
              fontSize: theme.typography.globalXS?.fontSize,
              fontWeight: 600,
            }}
          >
            {text}
          </Typography>
        )}
        {(!isLong || expanded) && (
          <Title
            title={text}
            variant="S"
            sx={[
              sxAnswer,
              { '& .MuiTypography-globalS': { whiteSpace: 'pre-wrap' } },
            ]}
            slotProps={{
              title: {
                sx: { fontSize: theme.typography.globalXS?.fontSize },
              },
            }}
          />
        )}
      </Stack>
    );
  }

  if (field.inputType === JobApplicationFormFieldInputType.SELECT) {
    const selectedId = typeof answer?.value === 'number' ? answer.value : null;
    const option = field.options?.find(o => o.id === selectedId) ?? null;
    const optionLabel = option
      ? getApplicationFormSelectOptionLabel({
          optionCode: option.code,
          fieldCode: field.code,
          t,
          defaultValue: option.label,
        })
      : '—';
    return (
      <Title
        copetin={label}
        title={optionLabel}
        variant="S"
        sx={sxAnswer}
      />
    );
  }

  if (field.inputType === JobApplicationFormFieldInputType.SELECT_MULTIPLE) {
    const selectedIds = new Set(answer?.selectedOptionIds ?? []);
    const optionLabels = (field.options ?? [])
      .filter(o => selectedIds.has(o.id))
      .sort((a, b) => a.sortOrder - b.sortOrder)
      .map(option =>
        getApplicationFormSelectOptionLabel({
          optionCode: option.code,
          fieldCode: field.code,
          t,
          defaultValue: option.label,
        }),
      )
      .join(', ');
    return (
      <Title
        copetin={label}
        title={optionLabels || '—'}
        variant="S"
        sx={sxAnswer}
      />
    );
  }

  return (
    <Title
      copetin={label}
      title={answer?.value != null ? String(answer.value) : '—'}
      variant="S"
      sx={sxAnswer}
    />
  );
};
