import React from 'react';
import { describe, expect, it, vi } from 'vitest';
import {
  CRM_DASHBOARD_OBJECT_API_NAME,
  CRM_REPORT_OBJECT_API_NAME,
  createCrmObjectViewRouteCapabilities,
} from '../src/object-view-route-capabilities';
import {
  CRM_OBJECT_CREATE_PARENT_CONTEXT_PARAMS,
  resolveCrmParentBackRoute,
  resolveCrmRecordDefaultsParentContext,
  type CrmObjectViewSObjectDescribe,
} from '../src/object-view-route-policy';

function createContext(overrides: Partial<Parameters<NonNullable<ReturnType<typeof createCrmObjectViewRouteCapabilities>[string]['onCreateNew']>>[0]> = {}) {
  return {
    objectApiName: '',
    normalizedObjectApiName: '',
    navigate: vi.fn(),
    navigateToObjectList: vi.fn(),
    openCreateModal: vi.fn(),
    ...overrides,
  };
}

describe('CRM object-view route capabilities', () => {
  it('owns ObjectView parent-context create routing policy in app-packs source', () => {
    const metadata = {
      fields: [{
        name: 'OpportunityId',
        type: 'reference',
        referenceTo: ['Opportunity'],
      }],
    } as unknown as CrmObjectViewSObjectDescribe;
    const params = new URLSearchParams({
      OpportunityId: 'OPP-1',
      [CRM_OBJECT_CREATE_PARENT_CONTEXT_PARAMS.OBJECT_API_NAME]: 'Opportunity',
      [CRM_OBJECT_CREATE_PARENT_CONTEXT_PARAMS.RECORD_ID]: 'OPP-1',
    });

    expect(resolveCrmParentBackRoute(metadata, params)).toBe('/object/Opportunity/OPP-1');
    expect(resolveCrmRecordDefaultsParentContext(metadata, params)).toEqual({
      parentFieldApiName: 'OpportunityId',
      parentRecordId: 'OPP-1',
    });
  });

  it('owns dashboard create and detail routing policy in app-packs source', () => {
    const capabilities = createCrmObjectViewRouteCapabilities({
      buildAppNavigationPath: (appId, capability) => `/${appId}/${capability}`,
    });
    const dashboard = capabilities[CRM_DASHBOARD_OBJECT_API_NAME];
    const context = createContext({
      currentFrontendAppId: 'crm-app',
      recordId: 'dash-1',
    });

    expect(dashboard.shouldFetchRecord?.(context)).toBe(false);
    dashboard.onCreateNew?.(context);
    expect(context.navigate).toHaveBeenCalledWith('/crm-app/dashboardList');

    const detail = dashboard.renderDetail?.(context);
    expect(React.isValidElement(detail)).toBe(true);
    expect((detail as React.ReactElement).props.dashboardId).toBe('dash-1');
  });

  it('owns report create/detail and execution-result fetch policy in app-packs source', () => {
    const capabilities = createCrmObjectViewRouteCapabilities({
      buildAppNavigationPath: () => undefined,
    });
    const report = capabilities[CRM_REPORT_OBJECT_API_NAME];
    const reportExecutionResult = { Id: '00O-report' };
    const context = createContext({
      recordId: '00O-report',
      recordData: { Id: 'record-data' },
      locationState: { reportExecutionResult },
    });

    expect(report.shouldFetchRecord?.(context)).toBe(false);
    expect(report.shouldFetchRecord?.({ ...context, locationState: undefined })).toBe(true);
    report.onCreateNew?.(context);
    expect(context.openCreateModal).toHaveBeenCalledTimes(1);

    const detail = report.renderDetail?.(context);
    expect(React.isValidElement(detail)).toBe(true);
    expect((detail as React.ReactElement).props.record).toBe(reportExecutionResult);
    expect((detail as React.ReactElement).props.reportId).toBe('00O-report');

    const createModal = report.renderCreateModal?.({ isOpen: true, onClose: vi.fn() });
    expect(React.isValidElement(createModal)).toBe(true);
    expect((createModal as React.ReactElement).props.isOpen).toBe(true);
  });
});
