import { FunctionComponent } from 'react';
import { render, screen } from '@testing-library/react';
import { ThemeProvider } from '../../theme';
import { formatIrrToToman } from '@/utils';
import type { CancellationPolicyPreview } from '@/services/refunds/types';

jest.mock('next-intl', () => ({
  useTranslations: () => (key: string) => key,
  useLocale: () => 'en',
}));

import CancellationPolicyDisclosure, {
  CancellationPolicyDisclosureProps,
} from './CancellationPolicyDisclosure';

const ComponentToTest: FunctionComponent<CancellationPolicyDisclosureProps> = (props) => (
  <ThemeProvider>
    <CancellationPolicyDisclosure {...props} />
  </ThemeProvider>
);

// Multi-session, free tier: two un-started (refundable) + one completed (locked). refund + fee = total.
const PREVIEW: CancellationPolicyPreview = {
  bookingId: 5003,
  cancellable: true,
  cancellationPolicyCode: 'free_24h',
  refundPercentageApplied: 1,
  feePercentage: 0,
  refundAmountIrr: '17600000',
  feeAmountIrr: '0',
  refundableAmountIrr: '17600000',
  platformFeeRefundedIrr: '2400000',
  nursePayoutRefundedIrr: '15200000',
  appliesTo: 'remaining_sessions',
  leadTimeLabel: 'gt_24h',
  refundChannel: 'psp_card',
  expectedCustomerRefundEta: null,
  refundableSessionIds: [70032, 70033],
  sessions: [
    { bookingSessionId: 70031, sessionIndex: 1, scheduledDate: '2026-08-01', refundable: false, reasonCode: 'completed' },
    { bookingSessionId: 70032, sessionIndex: 2, scheduledDate: '2026-08-05', refundable: true, reasonCode: 'un_started' },
    { bookingSessionId: 70033, sessionIndex: 3, scheduledDate: '2026-08-07', refundable: true, reasonCode: 'un_started' },
  ],
};

describe('<CancellationPolicyDisclosure/> component', () => {
  it('renders the tier label off the policy code (never the raw code) and the fee %', () => {
    const { container } = render(<ComponentToTest preview={PREVIEW} />);
    expect(container.querySelector('[data-policy-code="free_24h"]')).toBeInTheDocument();
    expect(screen.getByText('policy_free_24h')).toBeInTheDocument();
    expect(screen.getByText('fee_percent')).toBeInTheDocument();
  });

  it('renders a refund-vs-fee breakdown that reconciles to the refundable total', () => {
    const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
    const { container } = render(<ComponentToTest preview={PREVIEW} />);
    expect(container.querySelector('[data-row="refund"]')).toBeInTheDocument();
    expect(container.querySelector('[data-row="fee"]')).toBeInTheDocument();
    expect(container.querySelector('[data-row="total"]')).toBeInTheDocument();
    // Free tier: the full refundable amount is returned, so it appears on both the refund row and the total.
    expect(screen.getAllByText(new RegExp(formatIrrToToman('17600000', 'en'))).length).toBeGreaterThanOrEqual(1);
    // No reconciliation warning — refund + fee equals the refundable total.
    expect(errorSpy).not.toHaveBeenCalled();
    errorSpy.mockRestore();
  });

  it('marks un-started sessions refundable and completed sessions locked', () => {
    const { container } = render(<ComponentToTest preview={PREVIEW} />);
    expect(container.querySelector('[data-session-id="70031"][data-refundable="false"]')).toBeInTheDocument();
    expect(container.querySelector('[data-session-id="70032"][data-refundable="true"]')).toBeInTheDocument();
    expect(screen.getByText('reason_completed')).toBeInTheDocument();
    expect(screen.getAllByText('session_refundable').length).toBe(2);
  });

  it('shows the admin-approval explainer and the channel ETA banner', () => {
    render(<ComponentToTest preview={PREVIEW} />);
    expect(screen.getByTestId('admin-approval-explainer')).toBeInTheDocument();
    expect(screen.getByTestId('refund-eta-banner')).toBeInTheDocument();
  });
});
