/**
 * @vitest-environment jsdom
 */
import React from 'react';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { act, cleanup, render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import '@testing-library/jest-dom/vitest';

// Stable t()/formatters so hooks that list `t` in effect dependencies do not
// re-run on every render (react-i18next's no-instance fallback returns an
// unstable t, which sends ContractWizard's mount effect into a render loop).
vi.mock('@alga-psa/ui/lib/i18n/client', () => {
  const t = (key: string, opts?: string | { defaultValue?: string }) => {
    if (typeof opts === 'string') return opts;
    return typeof opts?.defaultValue === 'string' ? opts.defaultValue : key;
  };
  const translation = { t };
  const formatters = {
    formatDate: (value: unknown) => String(value),
    formatCurrency: (value: number) => `$${value}`,
  };
  return {
    useTranslation: () => translation,
    useFormatters: () => formatters,
  };
});

vi.mock('@alga-psa/ui/components/Dialog', () => ({
  Dialog: ({ isOpen, children, footer }: { isOpen: boolean; children: React.ReactNode; footer?: React.ReactNode }) =>
    isOpen ? (
      <div data-testid="dialog">
        {children}
        {footer}
      </div>
    ) : null,
  DialogContent: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
  DialogFooter: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
  DialogHeader: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
  DialogTitle: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
  DialogDescription: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
  DialogTrigger: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
}));

vi.mock('@alga-psa/ui/components/onboarding/WizardProgress', () => ({
  WizardProgress: ({ currentStep }: { currentStep: number }) => (
    <div data-testid="wizard-progress" data-current-step={String(currentStep)} />
  ),
}));

vi.mock('@alga-psa/ui/components/onboarding/WizardNavigation', () => ({
  WizardNavigation: ({
    onNext,
    onBack,
    onSaveDraft,
    onFinish,
  }: {
    onNext: () => void;
    onBack: () => void;
    onSaveDraft: () => void;
    onFinish: () => void;
  }) => (
    <div>
      <button type="button" onClick={onBack}>
        Back
      </button>
      <button type="button" onClick={onNext}>
        Next
      </button>
      <button type="button" onClick={onSaveDraft}>
        Save Draft
      </button>
      <button type="button" onClick={onFinish}>
        Finish
      </button>
    </div>
  ),
}));

vi.mock('../src/components/billing-dashboard/contracts/wizard-steps/ContractBasicsStep', () => ({
  ContractBasicsStep: ({
    data,
    updateData,
    onTemplateSelect,
  }: {
    data: any;
    updateData: (next: Record<string, unknown>) => void;
    onTemplateSelect?: (templateId: string | null) => void;
  }) => (
    <div
      data-testid="step-contract-basics"
      data-client-id={data.client_id ?? ''}
      data-contract-name={data.contract_name ?? ''}
      data-start-date={data.start_date ?? ''}
      data-end-date={data.end_date ?? ''}
    >
      <button
        type="button"
        onClick={() =>
          updateData({
            client_id: 'client-1',
            contract_name: 'Seeded Contract',
            start_date: '2026-01-01',
            billing_frequency: 'monthly',
            currency_code: 'USD',
            fixed_base_rate: 10000,
            fixed_services: [{ service_id: 'svc-1', quantity: 1 }],
          })
        }
      >
        Seed valid basics
      </button>
      <button type="button" onClick={() => onTemplateSelect?.('template-1')}>
        Apply Template
      </button>
    </div>
  ),
}));

vi.mock('../src/components/billing-dashboard/contracts/wizard-steps/FixedFeeServicesStep', () => ({
  FixedFeeServicesStep: ({
    data,
    updateData,
  }: {
    data: any;
    updateData: (next: Record<string, unknown>) => void;
  }) => (
    <div
      data-testid="step-fixed-fee"
      data-fixed-services-count={String((data.fixed_services ?? []).length)}
      data-cadence-owner={data.cadence_owner ?? 'client'}
      data-billing-timing={data.billing_timing ?? 'arrears'}
      data-enable-proration={String(Boolean(data.enable_proration))}
    >
      <button
        type="button"
        onClick={() => updateData({ enable_proration: !data.enable_proration })}
      >
        Toggle Partial-Period Adjustment
      </button>
    </div>
  ),
}));

vi.mock('../src/components/billing-dashboard/contracts/wizard-steps/ProductsStep', () => ({
  ProductsStep: ({ data }: { data: any }) => (
    <div data-testid="step-products" data-product-services-count={String((data.product_services ?? []).length)} />
  ),
}));

vi.mock('../src/components/billing-dashboard/contracts/wizard-steps/HourlyServicesStep', () => ({
  HourlyServicesStep: ({ data }: { data: any }) => (
    <div data-testid="step-hourly" data-hourly-services-count={String((data.hourly_services ?? []).length)} />
  ),
}));

vi.mock('../src/components/billing-dashboard/contracts/wizard-steps/UsageBasedServicesStep', () => ({
  UsageBasedServicesStep: ({ data }: { data: any }) => (
    <div data-testid="step-usage" data-usage-services-count={String((data.usage_services ?? []).length)} />
  ),
}));

vi.mock('../src/components/billing-dashboard/contracts/wizard-steps/ReviewContractStep', () => ({
  ReviewContractStep: ({ data }: { data: any }) => (
    <div
      data-testid="step-review"
      data-contract-name={data.contract_name ?? ''}
      data-fixed-services-count={String((data.fixed_services ?? []).length)}
      data-product-services-count={String((data.product_services ?? []).length)}
      data-hourly-services-count={String((data.hourly_services ?? []).length)}
      data-usage-services-count={String((data.usage_services ?? []).length)}
      data-cadence-owner={data.cadence_owner ?? 'client'}
      data-billing-timing={data.billing_timing ?? 'arrears'}
    />
  ),
}));

vi.mock('@alga-psa/billing/actions/contractWizardActions', () => ({
  createClientContractFromWizard: vi.fn(),
  listContractTemplatesForWizard: vi.fn(async () => []),
  getContractTemplateSnapshotForClientWizard: vi.fn(),
}));

vi.mock('@alga-psa/billing/actions/billingSettingsActions', () => ({
  getDefaultBillingSettings: vi.fn(async () => ({
    defaultRenewalMode: 'manual',
    defaultNoticePeriodDays: 30,
  })),
}));

describe('ContractWizard resume behavior', () => {
  beforeEach(() => {
    document.body.removeAttribute('data-scroll-locked');
    document.body.removeAttribute('style');
    cleanup();
    vi.clearAllMocks();
  });

  it('starts at Step 1 (Contract Basics) when opened (T033)', async () => {
    const { ContractWizard } = await import('../src/components/billing-dashboard/contracts/ContractWizard');
    render(
      <ContractWizard
        open={true}
        onOpenChange={vi.fn()}
        editingContract={{
          contract_id: 'contract-1',
          is_draft: true,
          client_id: 'client-1',
          contract_name: 'Draft Alpha',
          start_date: '2026-01-01',
          billing_frequency: 'monthly',
          currency_code: 'USD',
          enable_proration: false,
          fixed_services: [],
          product_services: [],
          hourly_services: [],
          usage_services: [],
        }}
      />,
    );

    await waitFor(() => {
      expect(screen.getByTestId('step-contract-basics')).toBeInTheDocument();
    });
    expect(screen.queryByTestId('step-fixed-fee')).not.toBeInTheDocument();
  });

  it('step 1 shows pre-populated client selection from draft (T034)', async () => {
    const { ContractWizard } = await import('../src/components/billing-dashboard/contracts/ContractWizard');
    render(
      <ContractWizard
        open={true}
        onOpenChange={vi.fn()}
        editingContract={{
          contract_id: 'contract-1',
          is_draft: true,
          client_id: 'client-99',
          contract_name: 'Draft Alpha',
          start_date: '2026-01-01',
          billing_frequency: 'monthly',
          currency_code: 'USD',
          enable_proration: false,
          fixed_services: [],
          product_services: [],
          hourly_services: [],
          usage_services: [],
        }}
      />,
    );

    const step = await screen.findByTestId('step-contract-basics');
    expect(step).toHaveAttribute('data-client-id', 'client-99');
  });

  it('step 1 shows pre-populated contract name from draft (T035)', async () => {
    const { ContractWizard } = await import('../src/components/billing-dashboard/contracts/ContractWizard');
    render(
      <ContractWizard
        open={true}
        onOpenChange={vi.fn()}
        editingContract={{
          contract_id: 'contract-1',
          is_draft: true,
          client_id: 'client-1',
          contract_name: 'Draft Name',
          start_date: '2026-01-01',
          billing_frequency: 'monthly',
          currency_code: 'USD',
          enable_proration: false,
          fixed_services: [],
          product_services: [],
          hourly_services: [],
          usage_services: [],
        }}
      />,
    );

    const step = await screen.findByTestId('step-contract-basics');
    expect(step).toHaveAttribute('data-contract-name', 'Draft Name');
  });

  it('step 1 shows pre-populated dates from draft (T036)', async () => {
    const { ContractWizard } = await import('../src/components/billing-dashboard/contracts/ContractWizard');
    render(
      <ContractWizard
        open={true}
        onOpenChange={vi.fn()}
        editingContract={{
          contract_id: 'contract-1',
          is_draft: true,
          client_id: 'client-1',
          contract_name: 'Draft Alpha',
          start_date: '2026-01-01',
          end_date: '2026-12-31',
          billing_frequency: 'monthly',
          currency_code: 'USD',
          enable_proration: false,
          fixed_services: [],
          product_services: [],
          hourly_services: [],
          usage_services: [],
        }}
      />,
    );

    const step = await screen.findByTestId('step-contract-basics');
    expect(step).toHaveAttribute('data-start-date', '2026-01-01');
    expect(step).toHaveAttribute('data-end-date', '2026-12-31');
  });

  it('step 2 (Fixed Fee) shows pre-populated services from draft (T037)', async () => {
    const { ContractWizard } = await import('../src/components/billing-dashboard/contracts/ContractWizard');
    render(
      <ContractWizard
        open={true}
        onOpenChange={vi.fn()}
        editingContract={{
          contract_id: 'contract-1',
          is_draft: true,
          client_id: 'client-1',
          contract_name: 'Draft Alpha',
          start_date: '2026-01-01',
          billing_frequency: 'monthly',
          currency_code: 'USD',
          enable_proration: false,
          fixed_base_rate: 10000,
          fixed_services: [
            { service_id: 'svc-1', quantity: 1 },
            { service_id: 'svc-2', quantity: 2 },
          ],
          product_services: [],
          hourly_services: [],
          usage_services: [],
        }}
      />,
    );

    await screen.findByTestId('step-contract-basics');
    const user = userEvent.setup();
    await act(async () => {
      await user.click(screen.getByText('Next'));
    });

    const step = await screen.findByTestId('step-fixed-fee');
    expect(step).toHaveAttribute('data-fixed-services-count', '2');
  });

  it('preserves cadence_owner from resumed drafts across fixed-fee step transitions (T113)', async () => {
    const { ContractWizard } = await import('../src/components/billing-dashboard/contracts/ContractWizard');
    render(
      <ContractWizard
        open={true}
        onOpenChange={vi.fn()}
        editingContract={{
          contract_id: 'contract-1',
          is_draft: true,
          client_id: 'client-1',
          contract_name: 'Draft Alpha',
          start_date: '2026-01-01',
          billing_frequency: 'monthly',
          currency_code: 'USD',
          cadence_owner: 'contract',
          billing_timing: 'advance',
          enable_proration: false,
          fixed_base_rate: 10000,
          fixed_services: [{ service_id: 'svc-1', quantity: 1 }],
          product_services: [],
          hourly_services: [],
          usage_services: [],
        }}
      />,
    );

    await screen.findByTestId('step-contract-basics');
    const user = userEvent.setup();
    await act(async () => {
      await user.click(screen.getByText('Next'));
    });

    const fixedStep = await screen.findByTestId('step-fixed-fee');
    expect(fixedStep).toHaveAttribute('data-cadence-owner', 'contract');

    await act(async () => {
      await user.click(screen.getByText('Next'));
    });
    await act(async () => {
      await user.click(screen.getByText('Back'));
    });

    expect(await screen.findByTestId('step-fixed-fee')).toHaveAttribute('data-cadence-owner', 'contract');
  });

  it('step 3 (Products) shows pre-populated products from draft (T038)', async () => {
    const { ContractWizard } = await import('../src/components/billing-dashboard/contracts/ContractWizard');
    render(
      <ContractWizard
        open={true}
        onOpenChange={vi.fn()}
        editingContract={{
          contract_id: 'contract-1',
          is_draft: true,
          client_id: 'client-1',
          contract_name: 'Draft Alpha',
          start_date: '2026-01-01',
          billing_frequency: 'monthly',
          currency_code: 'USD',
          enable_proration: false,
          fixed_services: [],
          product_services: [
            { service_id: 'prod-1', quantity: 1 },
            { service_id: 'prod-2', quantity: 2 },
          ],
          hourly_services: [],
          usage_services: [],
        }}
      />,
    );

    await screen.findByTestId('step-contract-basics');
    const user = userEvent.setup();
    await act(async () => {
      await user.click(screen.getByText('Next'));
    });
    await act(async () => {
      await user.click(screen.getByText('Next'));
    });

    const step = await screen.findByTestId('step-products');
    expect(step).toHaveAttribute('data-product-services-count', '2');
  });

  it('step 4 (Hourly) shows pre-populated hourly services from draft (T039)', async () => {
    const { ContractWizard } = await import('../src/components/billing-dashboard/contracts/ContractWizard');
    render(
      <ContractWizard
        open={true}
        onOpenChange={vi.fn()}
        editingContract={{
          contract_id: 'contract-1',
          is_draft: true,
          client_id: 'client-1',
          contract_name: 'Draft Alpha',
          start_date: '2026-01-01',
          billing_frequency: 'monthly',
          currency_code: 'USD',
          enable_proration: false,
          fixed_services: [],
          product_services: [],
          hourly_services: [
            { service_id: 'hr-1' },
            { service_id: 'hr-2' },
          ],
          usage_services: [],
        }}
      />,
    );

    await screen.findByTestId('step-contract-basics');
    const user = userEvent.setup();
    await act(async () => {
      await user.click(screen.getByText('Next'));
    });
    await act(async () => {
      await user.click(screen.getByText('Next'));
    });
    await act(async () => {
      await user.click(screen.getByText('Next'));
    });

    const step = await screen.findByTestId('step-hourly');
    expect(step).toHaveAttribute('data-hourly-services-count', '2');
  });

  it('step 5 (Usage) shows pre-populated usage services from draft (T040)', async () => {
    const { ContractWizard } = await import('../src/components/billing-dashboard/contracts/ContractWizard');
    render(
      <ContractWizard
        open={true}
        onOpenChange={vi.fn()}
        editingContract={{
          contract_id: 'contract-1',
          is_draft: true,
          client_id: 'client-1',
          contract_name: 'Draft Alpha',
          start_date: '2026-01-01',
          billing_frequency: 'monthly',
          currency_code: 'USD',
          enable_proration: false,
          fixed_services: [],
          product_services: [],
          hourly_services: [],
          usage_services: [
            { service_id: 'u-1' },
            { service_id: 'u-2' },
            { service_id: 'u-3' },
          ],
        }}
      />,
    );

    await screen.findByTestId('step-contract-basics');
    const user = userEvent.setup();
    for (let i = 0; i < 4; i++) {
      await act(async () => {
        await user.click(screen.getByText('Next'));
      });
    }

    const step = await screen.findByTestId('step-usage');
    expect(step).toHaveAttribute('data-usage-services-count', '3');
  });

  it('step 6 (Review) shows complete draft data for review (T041)', async () => {
    const { ContractWizard } = await import('../src/components/billing-dashboard/contracts/ContractWizard');
    render(
      <ContractWizard
        open={true}
        onOpenChange={vi.fn()}
        editingContract={{
          contract_id: 'contract-1',
          is_draft: true,
          client_id: 'client-1',
          contract_name: 'Draft Alpha',
          start_date: '2026-01-01',
          billing_frequency: 'monthly',
          currency_code: 'USD',
          enable_proration: false,
          fixed_base_rate: 10000,
          fixed_services: [{ service_id: 'svc-1', quantity: 1 }],
          product_services: [{ service_id: 'prod-1', quantity: 1 }],
          hourly_services: [{ service_id: 'hr-1' }],
          usage_services: [{ service_id: 'u-1' }],
        }}
      />,
    );

    await screen.findByTestId('step-contract-basics');
    const user = userEvent.setup();
    for (let i = 0; i < 5; i++) {
      await act(async () => {
        await user.click(screen.getByText('Next'));
      });
    }

    const step = await screen.findByTestId('step-review');
    expect(step).toHaveAttribute('data-contract-name', 'Draft Alpha');
    expect(step).toHaveAttribute('data-fixed-services-count', '1');
    expect(step).toHaveAttribute('data-product-services-count', '1');
    expect(step).toHaveAttribute('data-hourly-services-count', '1');
    expect(step).toHaveAttribute('data-usage-services-count', '1');
  });

  it('clicking Save Draft in resumed wizard updates existing draft (T042)', async () => {
    const { createClientContractFromWizard } = await import('@alga-psa/billing/actions/contractWizardActions');
    (createClientContractFromWizard as any).mockResolvedValue({ contract_id: 'contract-1' });

    const { ContractWizard } = await import('../src/components/billing-dashboard/contracts/ContractWizard');
    render(
      <ContractWizard
        open={true}
        onOpenChange={vi.fn()}
        editingContract={{
          contract_id: 'contract-1',
          is_draft: true,
          client_id: 'client-1',
          contract_name: 'Draft Alpha',
          start_date: '2026-01-01',
          billing_frequency: 'monthly',
          currency_code: 'USD',
          enable_proration: false,
          fixed_services: [],
          product_services: [],
          hourly_services: [],
          usage_services: [],
        }}
      />,
    );

    await screen.findByTestId('step-contract-basics');
    const user = userEvent.setup();
    await act(async () => {
      await user.click(screen.getByText('Save Draft'));
    });

    await waitFor(() => {
      expect(createClientContractFromWizard).toHaveBeenCalled();
    });

    const [submission, options] = (createClientContractFromWizard as any).mock.calls[0];
    expect(submission.contract_id).toBe('contract-1');
    expect(options).toEqual({ isDraft: true });
  });

  it('resaving a resumed draft preserves cadence_owner and partial-period defaults in the emitted draft payload', async () => {
    const { createClientContractFromWizard } = await import('@alga-psa/billing/actions/contractWizardActions');
    (createClientContractFromWizard as any).mockResolvedValue({ contract_id: 'contract-1' });

    const onComplete = vi.fn();
    const { ContractWizard } = await import('../src/components/billing-dashboard/contracts/ContractWizard');
    render(
      <ContractWizard
        open={true}
        onOpenChange={vi.fn()}
        onComplete={onComplete}
        editingContract={{
          contract_id: 'contract-1',
          is_draft: true,
          client_id: 'client-1',
          contract_name: 'Draft Alpha',
          start_date: '2026-01-01',
          billing_frequency: 'monthly',
          currency_code: 'USD',
          cadence_owner: 'contract',
          billing_timing: 'advance',
          enable_proration: false,
          fixed_base_rate: 10000,
          fixed_services: [{ service_id: 'svc-1', quantity: 1 }],
          product_services: [],
          hourly_services: [],
          usage_services: [],
        }}
      />,
    );

    await screen.findByTestId('step-contract-basics');
    const user = userEvent.setup();
    await act(async () => {
      await user.click(screen.getByText('Next'));
    });

    const fixedStep = await screen.findByTestId('step-fixed-fee');
    expect(fixedStep).toHaveAttribute('data-cadence-owner', 'contract');
    expect(fixedStep).toHaveAttribute('data-billing-timing', 'advance');
    expect(fixedStep).toHaveAttribute('data-enable-proration', 'false');

    await act(async () => {
      await user.click(screen.getByText('Toggle Partial-Period Adjustment'));
      await user.click(screen.getByText('Save Draft'));
    });

    await waitFor(() => {
      expect(onComplete).toHaveBeenCalled();
    });

    const [draftPayload] = onComplete.mock.calls.at(-1)!;
    expect(draftPayload).toMatchObject({
      contract_id: 'contract-1',
      is_draft: true,
      cadence_owner: 'contract',
      billing_timing: 'advance',
      enable_proration: true,
    });
  });

  it('applies template-authored cadence_owner and billing_timing to the client contract submission payload (T236)', async () => {
    const {
      createClientContractFromWizard,
      getContractTemplateSnapshotForClientWizard,
    } = await import('@alga-psa/billing/actions/contractWizardActions');
    (createClientContractFromWizard as any).mockResolvedValue({ contract_id: 'contract-template' });
    (getContractTemplateSnapshotForClientWizard as any).mockResolvedValue({
      contract_name: 'Template Contract',
      billing_frequency: 'monthly',
      cadence_owner: 'contract',
      billing_timing: 'advance',
      enable_proration: false,
      fixed_base_rate: 10000,
      fixed_services: [{ service_id: 'svc-template', quantity: 1 }],
    });

    const { ContractWizard } = await import('../src/components/billing-dashboard/contracts/ContractWizard');
    render(<ContractWizard open={true} onOpenChange={vi.fn()} />);

    await screen.findByTestId('step-contract-basics');
    const user = userEvent.setup();
    await act(async () => {
      await user.click(screen.getByText('Seed valid basics'));
      await user.click(screen.getByText('Apply Template'));
    });

    await waitFor(() => {
      expect(getContractTemplateSnapshotForClientWizard).toHaveBeenCalledWith('template-1');
    });

    await act(async () => {
      await user.click(screen.getByText('Next'));
    });

    const fixedStep = await screen.findByTestId('step-fixed-fee');
    expect(fixedStep).toHaveAttribute('data-cadence-owner', 'contract');
    expect(fixedStep).toHaveAttribute('data-billing-timing', 'advance');

    await act(async () => {
      await user.click(screen.getByText('Save Draft'));
    });

    await waitFor(() => {
      expect(createClientContractFromWizard).toHaveBeenCalledTimes(1);
    });

    const [submission, options] = (createClientContractFromWizard as any).mock.calls[0];
    expect(options).toEqual({ isDraft: true });
    expect(submission).toMatchObject({
      template_id: 'template-1',
      cadence_owner: 'contract',
      billing_timing: 'advance',
      enable_proration: false,
      fixed_services: [{ service_id: 'svc-template', quantity: 1 }],
    });
  });

  it('save draft does not create a duplicate contract (T043)', async () => {
    const { createClientContractFromWizard } = await import('@alga-psa/billing/actions/contractWizardActions');
    (createClientContractFromWizard as any).mockResolvedValue({ contract_id: 'contract-99' });

    const { ContractWizard } = await import('../src/components/billing-dashboard/contracts/ContractWizard');
    render(
      <ContractWizard
        open={true}
        onOpenChange={vi.fn()}
        editingContract={{
          contract_id: 'contract-99',
          is_draft: true,
          client_id: 'client-1',
          contract_name: 'Draft Alpha',
          start_date: '2026-01-01',
          billing_frequency: 'monthly',
          currency_code: 'USD',
          enable_proration: false,
          fixed_services: [],
          product_services: [],
          hourly_services: [],
          usage_services: [],
        }}
      />,
    );

    await screen.findByTestId('step-contract-basics');
    const user = userEvent.setup();
    await act(async () => {
      await user.click(screen.getByText('Save Draft'));
    });

    await waitFor(() => {
      expect(createClientContractFromWizard).toHaveBeenCalledTimes(1);
    });

    const [submission] = (createClientContractFromWizard as any).mock.calls[0];
    expect(submission.contract_id).toBe('contract-99');
  });

  it('save draft preserves the original contract_id (T044)', async () => {
    const { createClientContractFromWizard } = await import('@alga-psa/billing/actions/contractWizardActions');
    (createClientContractFromWizard as any).mockResolvedValue({ contract_id: 'contract-1' });

    const onComplete = vi.fn();
    const { ContractWizard } = await import('../src/components/billing-dashboard/contracts/ContractWizard');
    render(
      <ContractWizard
        open={true}
        onOpenChange={vi.fn()}
        onComplete={onComplete}
        editingContract={{
          contract_id: 'contract-1',
          is_draft: true,
          client_id: 'client-1',
          contract_name: 'Draft Alpha',
          start_date: '2026-01-01',
          billing_frequency: 'monthly',
          currency_code: 'USD',
          enable_proration: false,
          fixed_services: [],
          product_services: [],
          hourly_services: [],
          usage_services: [],
        }}
      />,
    );

    await screen.findByTestId('step-contract-basics');
    const user = userEvent.setup();
    await act(async () => {
      await user.click(screen.getByText('Save Draft'));
    });

    await waitFor(() => {
      expect(onComplete).toHaveBeenCalled();
    });

    const [data] = onComplete.mock.calls[0];
    expect(data.contract_id).toBe('contract-1');
  });

  it("completing resumed wizard sets contract status to 'active' (T045)", async () => {
    const { createClientContractFromWizard } = await import('@alga-psa/billing/actions/contractWizardActions');
    (createClientContractFromWizard as any).mockResolvedValue({ contract_id: 'contract-1' });

    const { ContractWizard } = await import('../src/components/billing-dashboard/contracts/ContractWizard');
    render(
      <ContractWizard
        open={true}
        onOpenChange={vi.fn()}
        editingContract={{
          contract_id: 'contract-1',
          is_draft: true,
          client_id: 'client-1',
          contract_name: 'Draft Alpha',
          start_date: '2026-01-01',
          billing_frequency: 'monthly',
          currency_code: 'USD',
          enable_proration: false,
          fixed_base_rate: 10000,
          fixed_services: [{ service_id: 'svc-1', quantity: 1 }],
          product_services: [],
          hourly_services: [],
          usage_services: [],
        }}
      />,
    );

    await screen.findByTestId('step-contract-basics');
    const user = userEvent.setup();
    for (let i = 0; i < 5; i++) {
      await act(async () => {
        await user.click(screen.getByText('Next'));
      });
    }
    await screen.findByTestId('step-review');

    await act(async () => {
      await user.click(screen.getByText('Finish'));
    });

    await waitFor(() => {
      expect(createClientContractFromWizard).toHaveBeenCalled();
    });

    const [submission, options] = (createClientContractFromWizard as any).mock.calls[0];
    expect(submission.contract_id).toBe('contract-1');
    expect(options).toBeUndefined();
  });

  it('completing resumed wizard sets is_active to true (T046)', async () => {
    const { createClientContractFromWizard } = await import('@alga-psa/billing/actions/contractWizardActions');
    (createClientContractFromWizard as any).mockResolvedValue({ contract_id: 'contract-1' });

    const { ContractWizard } = await import('../src/components/billing-dashboard/contracts/ContractWizard');
    render(
      <ContractWizard
        open={true}
        onOpenChange={vi.fn()}
        editingContract={{
          contract_id: 'contract-1',
          is_draft: true,
          client_id: 'client-1',
          contract_name: 'Draft Alpha',
          start_date: '2026-01-01',
          billing_frequency: 'monthly',
          currency_code: 'USD',
          enable_proration: false,
          fixed_base_rate: 10000,
          fixed_services: [{ service_id: 'svc-1', quantity: 1 }],
          product_services: [],
          hourly_services: [],
          usage_services: [],
        }}
      />,
    );

    await screen.findByTestId('step-contract-basics');
    const user = userEvent.setup();
    for (let i = 0; i < 5; i++) {
      await act(async () => {
        await user.click(screen.getByText('Next'));
      });
    }
    await screen.findByTestId('step-review');

    await act(async () => {
      await user.click(screen.getByText('Finish'));
    });

    await waitFor(() => {
      expect(createClientContractFromWizard).toHaveBeenCalled();
    });

    const [_submission, options] = (createClientContractFromWizard as any).mock.calls[0];
    expect(options).toBeUndefined();
  });

  it('submits the client cadence default for newly created recurring lines (T112)', async () => {
    const { createClientContractFromWizard } = await import('@alga-psa/billing/actions/contractWizardActions');
    (createClientContractFromWizard as any).mockResolvedValue({ contract_id: 'contract-new' });

    const { ContractWizard } = await import('../src/components/billing-dashboard/contracts/ContractWizard');
    render(<ContractWizard open={true} onOpenChange={vi.fn()} />);

    await screen.findByTestId('step-contract-basics');
    const user = userEvent.setup();
    await act(async () => {
      await user.click(screen.getByText('Seed valid basics'));
    });

    for (let i = 0; i < 5; i++) {
      await act(async () => {
        await user.click(screen.getByText('Next'));
      });
    }

    expect(await screen.findByTestId('step-review')).toHaveAttribute('data-cadence-owner', 'client');

    await act(async () => {
      await user.click(screen.getByText('Finish'));
    });

    await waitFor(() => {
      expect(createClientContractFromWizard).toHaveBeenCalledTimes(1);
    });

    const [submission] = (createClientContractFromWizard as any).mock.calls[0];
    expect(submission.cadence_owner).toBe('client');
  });
});
