'use client';
import { useState } from 'react';
import { useParams, useRouter } from 'next/navigation';
import { useLocale, useTranslations } from 'next-intl';
import { Checkbox, FormControlLabel, MenuItem, Paper, Stack, TextField, Typography } from '@mui/material';
import AppButton from '@/components/common/AppButton';
import AppAlert from '@/components/common/AppAlert';
import AppLoading from '@/components/common/AppLoading';
import Money from '@/components/common/Money';
import StepperHeader from '@/components/StepperHeader';
import CancellationPolicyDisclosure from '@/components/CancellationPolicyDisclosure';
import { ApiError } from '@/lib/api/errors';
import { bookingRefundStatusPath, ROUTES } from '@/constants';
import { useCancelBooking, useCancellationPolicyPreview } from '@/services/refunds';
import type { CancelReasonCategory } from '@/services/refunds/types';

const REASON_CATEGORIES: CancelReasonCategory[] = [
  'changed_mind',
  'schedule_conflict',
  'found_other_care',
  'other',
];

/** Maps the cancel mutation's `409` code to a user-facing message; anything else is the generic failure. */
function cancelErrorKey(error: unknown): string {
  if (error instanceof ApiError) {
    if (error.code === 'not_cancellable') return 'err_not_cancellable';
    if (error.code === 'nothing_refundable' || error.code === 'session_not_refundable') {
      return 'err_nothing_refundable';
    }
  }
  return 'err_generic';
}

/**
 * Cancellation flow (f10) — the trust-first exit. Step 1 **discloses** the resolved policy tier, the
 * refund % + fee %, and the concrete Toman amounts (refunded vs kept) **before** anything is submitted;
 * the confirm button is gated behind an explicit acknowledgement. Step 2 restates the numbers and submits
 * via `useCancelBooking` (which invalidates the booking + primes the refund cache), then routes to the
 * refund status. Refunds are admin-approved — the copy makes clear the request is *submitted* and
 * *processed by the team*, never self-issued.
 */
export default function CancelBookingPage() {
  const params = useParams<{ id: string }>();
  const router = useRouter();
  const locale = useLocale();
  const t = useTranslations('refunds');
  const tc = useTranslations('common');

  const rawId = Number(params.id);
  const bookingId = Number.isInteger(rawId) && rawId > 0 ? rawId : undefined;

  const { data: preview, isLoading, isError } = useCancellationPolicyPreview(bookingId);
  const cancel = useCancelBooking();

  const [step, setStep] = useState<0 | 1>(0);
  const [acknowledged, setAcknowledged] = useState(false);
  const [reasonCategory, setReasonCategory] = useState<CancelReasonCategory>('changed_mind');
  const [reasonNotes, setReasonNotes] = useState('');

  const bookingHref = `/${locale}${ROUTES.BOOKINGS}/${bookingId}`;

  if (isLoading) return <AppLoading />;

  if (isError || !preview || bookingId == null) {
    return (
      <Stack sx={{ gap: 2, maxWidth: 640, mx: 'auto', width: '100%', py: 2 }}>
        <AppAlert severity="error" variant="outlined" sx={{ marginY: 0 }}>
          <Stack sx={{ gap: 0.5 }}>
            <Typography variant="subtitle2" sx={{ fontWeight: 700 }}>
              {t('error_title')}
            </Typography>
            <Typography variant="body2">{t('error_body')}</Typography>
          </Stack>
        </AppAlert>
      </Stack>
    );
  }

  if (!preview.cancellable) {
    return (
      <Stack sx={{ gap: 2, maxWidth: 640, mx: 'auto', width: '100%', py: 2 }}>
        <AppAlert severity="info" variant="outlined" sx={{ marginY: 0 }}>
          <Stack sx={{ gap: 0.5 }}>
            <Typography variant="subtitle2" sx={{ fontWeight: 700 }}>
              {t('not_cancellable_title')}
            </Typography>
            <Typography variant="body2">{t('not_cancellable_body')}</Typography>
          </Stack>
        </AppAlert>
        <Stack direction="row" sx={{ gap: 1, flexWrap: 'wrap' }}>
          <AppButton
            variant="contained"
            color="primary"
            onClick={() => router.push(`/${locale}${bookingRefundStatusPath(bookingId)}`)}
          >
            {t('view_refund_status')}
          </AppButton>
          <AppButton variant="text" color="inherit" onClick={() => router.push(bookingHref)}>
            {t('back_to_booking')}
          </AppButton>
        </Stack>
      </Stack>
    );
  }

  const submit = () =>
    cancel.mutate(
      {
        bookingId,
        sessionIds: preview.refundableSessionIds,
        reasonCategory,
        reasonNotes: reasonNotes.trim() || undefined,
      },
      { onSuccess: () => router.push(`/${locale}${bookingRefundStatusPath(bookingId)}`) },
    );

  return (
    <Stack sx={{ gap: 3, maxWidth: 640, mx: 'auto', width: '100%', py: 2 }}>
      <Typography variant="h5" component="h1" sx={{ fontWeight: 800 }}>
        {t('cancel_title')}
      </Typography>
      <StepperHeader steps={[t('step_review'), t('step_confirm')]} activeStep={step} />

      {step === 0 ? (
        <>
          <CancellationPolicyDisclosure preview={preview} />

          <TextField
            select
            label={t('reason_field_label')}
            value={reasonCategory}
            onChange={(event) => setReasonCategory(event.target.value as CancelReasonCategory)}
            fullWidth
          >
            {REASON_CATEGORIES.map((category) => (
              <MenuItem key={category} value={category}>
                {t(`reason_cat_${category}`)}
              </MenuItem>
            ))}
          </TextField>
          <TextField
            label={t('reason_notes_label')}
            value={reasonNotes}
            onChange={(event) => setReasonNotes(event.target.value)}
            multiline
            minRows={2}
            fullWidth
          />
          <FormControlLabel
            control={<Checkbox checked={acknowledged} onChange={(event) => setAcknowledged(event.target.checked)} />}
            label={t('acknowledge_label')}
          />

          <Stack direction="row" sx={{ gap: 1, justifyContent: 'space-between', flexWrap: 'wrap' }}>
            <AppButton variant="text" color="inherit" onClick={() => router.push(bookingHref)}>
              {t('back_to_booking')}
            </AppButton>
            <AppButton
              variant="contained"
              color="primary"
              disabled={!acknowledged}
              onClick={() => setStep(1)}
            >
              {t('continue_cta')}
            </AppButton>
          </Stack>
        </>
      ) : (
        <>
          <Paper elevation={0} sx={{ p: 2.5, border: '1px solid', borderColor: 'divider', borderRadius: 2 }}>
            <Typography variant="subtitle1" sx={{ fontWeight: 800, mb: 1 }}>
              {t('confirm_title')}
            </Typography>
            <Typography variant="body2" component="div">
              {t.rich('confirm_restate', {
                refund: () => (
                  <Money amountIrr={preview.refundAmountIrr} size="sm" sx={{ fontWeight: 700 }} />
                ),
                fee: () => <Money amountIrr={preview.feeAmountIrr} size="sm" sx={{ fontWeight: 700 }} />,
              })}
            </Typography>
          </Paper>

          {cancel.isError && (
            <AppAlert severity="error" variant="outlined" sx={{ marginY: 0 }}>
              {t(cancelErrorKey(cancel.error))}
            </AppAlert>
          )}

          <Stack direction="row" sx={{ gap: 1, justifyContent: 'space-between', flexWrap: 'wrap' }}>
            <AppButton
              variant="text"
              color="inherit"
              onClick={() => setStep(0)}
              disabled={cancel.isPending}
            >
              {tc('back')}
            </AppButton>
            <AppButton
              variant="contained"
              color="error"
              onClick={submit}
              disabled={cancel.isPending}
            >
              {cancel.isPending ? t('submitting') : t('confirm_cta')}
            </AppButton>
          </Stack>
        </>
      )}
    </Stack>
  );
}
