import {
  IconArrowBackUp,
  IconEdit,
  IconInfoCircle,
} from '@material-hu/icons/tabler';
import Stack from '@material-hu/mui/Stack';
import { type Theme } from '@material-hu/mui/styles';
import Typography from '@material-hu/mui/Typography/Typography';

import Alert from '@material-hu/components/design-system/Alert';
import Avatar from '@material-hu/components/design-system/Avatar';
import Button from '@material-hu/components/design-system/Buttons/Button';
import CardContainer from '@material-hu/components/design-system/CardContainer';
import InputClassic from '@material-hu/components/design-system/Inputs/Classic';
import Pills from '@material-hu/components/design-system/Pills';
import HuStepper from '@material-hu/components/design-system/Stepper';
import Title from '@material-hu/components/design-system/Title';
import Tooltip from '@material-hu/components/design-system/Tooltip';

import { useAuth } from 'src/contexts/JWTContext';
import useFormatDate from 'src/hooks/useFormatDate';
import usePermissions from 'src/hooks/usePermissions';
import {
  type ApprovalRequest,
  TimeTrackingCategorizedHourStatus,
} from 'src/types/timeTracking';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { UserPermissions } from 'src/utils/permissions';
import { displayHoursAndMinutes, pairEntries } from 'src/utils/timeTracking';
import { getInitials } from 'src/utils/userUtils';

import {
  type ApproverStepItem,
  Approvers,
  ApproversAccordion,
} from 'src/components/dashboard/approvers';

import {
  getReadOnlyResponseCommentItems,
  getStepperActiveStep,
} from '../utils';

import ApprovalDetailDrawerSkeleton from './ApprovalDetailDrawerSkeleton';
import EntryPairs from './EntryPairs';
import ResponseReasonCard from './ResponseReasonCard';

type Props = {
  categorizedHour?: ApprovalRequest;
  isLoading: boolean;
  isEditing: boolean;
  canEditResponse: boolean;
  hasLastReviewedStep?: boolean;
  responseText: string;
  onEditResponse: () => void;
  onCancelEdit: () => void;
  onResponseTextChange: (value: string) => void;
  /** Optional approval steps to show "Responsibles" block (avatars + drawer with accordions) */
  approverSteps?: ApproverStepItem[];
  /** True when the logged user is a potential approver of the current active step */
  isCurrentStepApprover?: boolean;
  /** True when the logged user has already approved one of the steps of this request */
  isApprovedByLoggedUser?: boolean;
  /** Another approver advanced the workflow while this drawer was open (socket / shared view). */
  showSupersededByOtherApprover?: boolean;
  supersededStepPosition?: number;
};

const CARD_STYLE = {
  backgroundColor: (theme: Theme) => theme.palette.new.background.elements.grey,
  borderColor: (theme: Theme) => theme.palette.new.background.elements.grey,
};

const ApprovalDetailDrawer = ({
  categorizedHour,
  isLoading,
  isEditing,
  canEditResponse,
  hasLastReviewedStep = false,
  responseText,
  onEditResponse,
  onCancelEdit,
  onResponseTextChange,
  approverSteps,
  isCurrentStepApprover = false,
  isApprovedByLoggedUser = false,
  showSupersededByOtherApprover = false,
  supersededStepPosition,
}: Props) => {
  const { t } = useLokaliseTranslation(['time_tracker', 'approval_requests']);
  const { formatDate } = useFormatDate();
  const { user } = useAuth();
  const { hasAll: canManageTimeTracking } = usePermissions([
    UserPermissions.MANAGE_TIME_TRACKING,
  ]);

  if (isLoading) {
    return <ApprovalDetailDrawerSkeleton />;
  }

  if (!categorizedHour) {
    return null;
  }

  const status = categorizedHour.status;
  const requestType = categorizedHour.hourCategoryName;

  const isCancelled =
    status === TimeTrackingCategorizedHourStatus.CANCELLED ||
    status === TimeTrackingCategorizedHourStatus.CANCELED_BY_MODIFICATION;

  const isRevoked =
    status === TimeTrackingCategorizedHourStatus.REJECTED &&
    categorizedHour.statusOverride != null;

  const entryPairs = pairEntries(categorizedHour.entries, 'ASC');

  // Format date
  const formattedDate = categorizedHour.dateString
    ? formatDate(
        `${categorizedHour.dateString}T12:00:00`,
        'dd/MMM/yyyy',
      ).toUpperCase()
    : '';

  const formattedHours = displayHoursAndMinutes(
    categorizedHour.hours ?? 0,
    false,
    true,
  );

  const showStepper = approverSteps != null && approverSteps.length > 1;
  const activeStep = getStepperActiveStep(approverSteps, status);
  const supersededAlertStep =
    supersededStepPosition ?? (activeStep > 0 ? activeStep : 1);

  const readOnlyCommentItems = getReadOnlyResponseCommentItems(
    categorizedHour.approvalSteps,
    categorizedHour.note,
    t('approval_requests:no_comments'),
    categorizedHour.statusOverride,
    status,
  );
  const showResponseComments =
    !isEditing && !isCancelled && readOnlyCommentItems.length > 0;
  const canActOnCurrentStep = canManageTimeTracking || isCurrentStepApprover;
  const showEditableResponseSection =
    !isCancelled &&
    (isEditing ||
      (status === TimeTrackingCategorizedHourStatus.PENDING &&
        canActOnCurrentStep));

  const statusPillConfig: Partial<
    Record<
      TimeTrackingCategorizedHourStatus,
      {
        type: 'success' | 'error' | 'neutral' | 'info' | 'warning' | 'disabled';
        label: string;
      }
    >
  > = {
    [TimeTrackingCategorizedHourStatus.PENDING]: {
      type: isCurrentStepApprover ? ('warning' as const) : ('info' as const),
      label: isCurrentStepApprover
        ? t('general:pending')
        : t('time_tracker:overtime_request_detail.status.in_process'),
    },
    [TimeTrackingCategorizedHourStatus.APPROVED]: {
      type: 'success',
      label: t('approval_requests:approved'),
    },
    [TimeTrackingCategorizedHourStatus.AUTO_APPROVED]: {
      type: 'success',
      label: t('approval_requests:approved'),
    },
    [TimeTrackingCategorizedHourStatus.REJECTED]: isRevoked
      ? { type: 'disabled', label: t('approval_requests:revoked') }
      : { type: 'error', label: t('approval_requests:rejected') },
    [TimeTrackingCategorizedHourStatus.CANCELLED]: {
      type: 'neutral',
      label: t('approval_requests:cancelled'),
    },
    [TimeTrackingCategorizedHourStatus.CANCELED_BY_MODIFICATION]: {
      type: 'neutral',
      label: t('approval_requests:cancelled'),
    },
  };

  const errorSteps = approverSteps
    ?.filter(step => step.state === 'rejected')
    .map(step => Number(step.position - 1));

  const editResolutionButtonText = isEditing
    ? t('general:exit_without_saving')
    : t('approvals.edit_response');
  const supersededAlertDescriptionKey = isCurrentStepApprover
    ? 'approval_requests:step_already_reviewed_description_pending'
    : 'approval_requests:step_already_reviewed_description_in_process';

  return (
    <Stack
      sx={{
        flex: 1,
        gap: 2,
        pb: 2,
      }}
    >
      {showStepper && (
        <HuStepper
          steps={approverSteps.map(step => ({
            id: step.id.toString(),
            title: t(`general:step_positions.step_${step.position}`),
          }))}
          errorSteps={errorSteps}
          currentStep={activeStep}
        />
      )}
      {/* Requested by */}
      <CardContainer
        sx={CARD_STYLE}
        fullWidth
      >
        <Stack sx={{ flexDirection: 'row', alignItems: 'center', gap: 1 }}>
          <Avatar
            color="primary"
            text={getInitials(categorizedHour.fullName)}
            src={categorizedHour.profilePicture || undefined}
          />
          <Stack>
            <Typography variant="globalXXS">
              {t('approval_requests:requested_by')}
            </Typography>
            <Typography
              variant="globalM"
              sx={{ fontWeight: 'fontWeightSemiBold' }}
            >
              {categorizedHour.fullName}
            </Typography>
          </Stack>
        </Stack>
      </CardContainer>
      {/* Request date */}
      <CardContainer
        fullWidth
        sx={CARD_STYLE}
      >
        <Title
          variant="M"
          copetin={t('approval_requests:request.date')}
          title={formattedDate}
        />
      </CardContainer>
      {/* Request type */}
      <CardContainer
        fullWidth
        sx={CARD_STYLE}
      >
        <Stack sx={{ gap: 0.5 }}>
          <Typography variant="globalXXS">
            {t('approval_requests:request.type')}
          </Typography>
          <Pills
            type="info"
            label={requestType}
            sx={{ width: 'fit-content' }}
            size="small"
            hasIcon={false}
          />
        </Stack>
      </CardContainer>
      {/* Approvers */}
      {approverSteps && approverSteps.length > 0 && (
        <CardContainer
          fullWidth
          sx={CARD_STYLE}
        >
          <Approvers
            steps={approverSteps}
            drawerTitle={t('approval_requests:response_responsible_other')}
            isAdmin={canManageTimeTracking}
          >
            {approverSteps.map(step => (
              <ApproversAccordion
                key={step.id}
                step={step}
                viewerUserId={user?.id}
              />
            ))}
          </Approvers>
        </CardContainer>
      )}
      {/* Request Status */}
      <CardContainer
        sx={CARD_STYLE}
        fullWidth
      >
        <Stack
          sx={{
            flexDirection: 'row',
            justifyContent: 'space-between',
            alignItems: 'center',
          }}
        >
          <Stack sx={{ gap: 0.5 }}>
            <Typography
              variant="globalXXS"
              sx={{
                color: theme => theme.palette.new.text.neutral.lighter,
              }}
            >
              {t('approval_requests:request.status')}
            </Typography>
            <Stack sx={{ flexDirection: 'row', gap: 0.5 }}>
              {statusPillConfig[status] && (
                <Pills
                  type={statusPillConfig[status]?.type}
                  label={statusPillConfig[status]?.label ?? ''}
                  hasIcon={false}
                  sx={{ width: 'fit-content' }}
                  size="small"
                />
              )}
              {isApprovedByLoggedUser && !isCancelled && !isRevoked && (
                <Pills
                  type="success"
                  label={t('approval_requests:approved_by_me')}
                  hasIcon={false}
                  sx={{ width: 'fit-content' }}
                  size="small"
                />
              )}
            </Stack>
          </Stack>
          {canEditResponse &&
            !isCancelled &&
            hasLastReviewedStep &&
            (!isRevoked || canManageTimeTracking) && (
              <Button
                variant="secondary"
                endIcon={!isEditing ? <IconEdit size={16} /> : undefined}
                startIcon={
                  isEditing ? <IconArrowBackUp size={16} /> : undefined
                }
                size="small"
                onClick={isEditing ? onCancelEdit : onEditResponse}
              >
                {editResolutionButtonText}
              </Button>
            )}
          {isCancelled && (
            <Button
              variant="secondary"
              startIcon={
                <Tooltip
                  title={t('approval_requests:about_cancellation_description')}
                  direction="bottom"
                >
                  <IconInfoCircle size={16} />
                </Tooltip>
              }
              size="small"
            >
              {t('approval_requests:about_cancellation')}
            </Button>
          )}
        </Stack>
        {showSupersededByOtherApprover && (
          <Alert
            severity="info"
            title={t('approval_requests:step_already_reviewed_title', {
              step: supersededAlertStep,
            })}
            description={t(supersededAlertDescriptionKey)}
            sx={{ mt: 2 }}
          />
        )}
      </CardContainer>
      {/* Response reason - read only (approval step comments in order, else legacy note) */}
      {showResponseComments && (
        <ResponseReasonCard items={readOnlyCommentItems} />
      )}
      {/* Hours to approve */}
      <CardContainer
        fullWidth
        sx={CARD_STYLE}
      >
        <Title
          variant="M"
          copetin={t('approvals.hours_to_approve')}
          title={formattedHours}
        />
      </CardContainer>
      {/* Work schedule */}
      {categorizedHour?.workTimeSlots?.length > 0 && (
        <CardContainer
          fullWidth
          sx={CARD_STYLE}
        >
          <Stack sx={{ gap: 0.5 }}>
            <Typography variant="globalXXS">
              {t('approvals.work_schedule')}
            </Typography>
            <Stack
              sx={{
                flexDirection: 'row',
                alignItems: 'center',
                gap: 1,
                flexWrap: 'wrap',
              }}
            >
              {categorizedHour.workTimeSlots.map((slot, index) => (
                <Pills
                  key={index}
                  type="neutral"
                  label={`${slot.startTime} - ${slot.endTime}`}
                  hasIcon={false}
                />
              ))}
            </Stack>
          </Stack>
        </CardContainer>
      )}
      {/* Entries */}
      {entryPairs.length > 0 && (
        <CardContainer
          fullWidth
          sx={CARD_STYLE}
        >
          <Stack sx={{ gap: 0.5 }}>
            <Typography variant="globalXXS">{t('trackings')}</Typography>
            <EntryPairs entryPairs={entryPairs} />
          </Stack>
        </CardContainer>
      )}
      {/* Response reason - editable */}
      {showEditableResponseSection && (
        <CardContainer
          fullWidth
          sx={CARD_STYLE}
        >
          <Stack sx={{ gap: 1 }}>
            <Typography
              variant="globalS"
              sx={{ fontWeight: 'fontWeightSemiBold' }}
            >
              {t('approval_requests:response_reason')}
            </Typography>
            <InputClassic
              maxRows={4}
              value={responseText}
              placeholder={t(
                'time_tracker:approvals.write_comments_placeholder',
              )}
              onChange={onResponseTextChange}
              fullWidth
              multiline
            />
          </Stack>
        </CardContainer>
      )}
    </Stack>
  );
};

export default ApprovalDetailDrawer;
