import { useEffect, useMemo, useRef } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';

import Stack from '@material-hu/mui/Stack';
import { type Theme } from '@material-hu/mui/styles';

import { useAuth } from 'src/contexts/JWTContext';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { getCurrentLocale } from 'src/utils/locale';

import { useActiveCollaboratorLoanPlan } from '../hooks/useActiveCollaboratorLoanPlan';
import { useCollaboratorPayments } from '../hooks/useCollaboratorPayments';
import { microloansRoutes } from '../routes';
import { trackLoanStatusViewed } from '../track';
import {
  buildMicroloansStatusViewModel,
  type MicroloanPlanStatus,
} from '../utils/buildMicroloansStatusViewModel';
import { resolvePeriodicity } from '../utils/periodicity';

import ActivePlanStatusContent from './status/ActivePlanStatusContent';
import PlanLoadErrorState from './status/PlanLoadErrorState';
import PlanNoActiveState from './status/PlanNoActiveState';
import PlanPausedState from './status/PlanPausedState';
import PlanPendingDisbursementState from './status/PlanPendingDisbursementState';
import StatusLoadingState from './status/StatusLoadingState';

export type {
  MicroloanPlanStatus,
  ScheduleRow,
} from '../utils/buildMicroloansStatusViewModel';

export const PLAN_STATUS_LABEL_KEYS: Record<MicroloanPlanStatus, string> = {
  ON_TRACK: 'status.on_track',
  OVERDUE: 'status.overdue',
  PAUSED: 'status.paused',
  PENDING_DISBURSEMENT: 'status.pending_disbursement',
};

export const PLAN_STATUS_STYLES: Record<
  MicroloanPlanStatus,
  { progressFill: (theme: Theme) => string }
> = {
  ON_TRACK: {
    progressFill: theme =>
      theme.palette.new.action.button.background.primary.default,
  },
  OVERDUE: {
    progressFill: theme =>
      theme.palette.new.action.button.background.error.default,
  },
  PAUSED: {
    progressFill: theme =>
      theme.palette.new.action.button.background.primary.default,
  },
  PENDING_DISBURSEMENT: {
    progressFill: theme =>
      theme.palette.new.action.button.background.primary.default,
  },
};

const Status = () => {
  const navigate = useNavigate();
  const location = useLocation();
  const { t } = useLokaliseTranslation('loans');
  const { user } = useAuth();
  const locale = useMemo(() => getCurrentLocale(user), [user]);
  useEffect(() => {
    trackLoanStatusViewed();
  }, []);
  const {
    data: planData,
    isLoading: planLoading,
    isError: planError,
    refetch: refetchPlan,
  } = useActiveCollaboratorLoanPlan();
  const {
    data: paymentsData,
    isLoading: paymentsLoading,
    isError: paymentsError,
    refetch: refetchPayments,
  } = useCollaboratorPayments();

  const isFirstNavigation = useRef(true);

  useEffect(() => {
    if (isFirstNavigation.current) {
      isFirstNavigation.current = false;
      return;
    }
    void refetchPlan();
    void refetchPayments();
  }, [location.key]);

  if (planLoading) {
    return <StatusLoadingState />;
  }

  if (planError) {
    return (
      <PlanLoadErrorState
        onRetry={() => {
          refetchPlan();
          refetchPayments();
        }}
      />
    );
  }

  if (!planData) {
    return (
      <Stack sx={{ width: '100%' }}>
        <PlanNoActiveState
          onRequestOffer={() => navigate(microloansRoutes.requestOffer())}
        />
      </Stack>
    );
  }

  if (planData.status === 'PAUSED') {
    return (
      <Stack sx={{ width: '100%' }}>
        <PlanPausedState />
      </Stack>
    );
  }

  if (planData.status === 'PENDING') {
    return (
      <Stack sx={{ width: '100%' }}>
        <PlanPendingDisbursementState />
      </Stack>
    );
  }

  if (paymentsError) {
    return (
      <PlanLoadErrorState
        onRetry={() => {
          refetchPlan();
          refetchPayments();
        }}
      />
    );
  }

  if (paymentsLoading) {
    return <StatusLoadingState />;
  }

  const vm = buildMicroloansStatusViewModel(
    planData,
    paymentsData ?? [],
    t,
    locale,
    resolvePeriodicity(planData.periodicity),
  );
  const planStyles = PLAN_STATUS_STYLES[vm.planStatus];
  const planStatusLabel = t(PLAN_STATUS_LABEL_KEYS[vm.planStatus]);
  return (
    <ActivePlanStatusContent
      vm={vm}
      planStyles={planStyles}
      planStatusLabel={planStatusLabel}
    />
  );
};

export default Status;
