import { fireEvent, render, screen } from '@testing-library/react';
import { describe, expect, it, vi } from 'vitest';

import { RecordLink } from '../src/platform/components/RecordLink';
import { createCrmUiFieldComponents, type CrmUiFieldHost } from '../src/ui-field-components';
import { getRecordName } from '../src/platform/infrastructure/api/data/recordUtils';

// Covers two of the three Task detail-page fixes at the unit/render level:
//   #1 the record header title resolves to Subject (the Task name field) rather
//      than the raw record Id.
//   #3 the polymorphic "Related To" (WhatId) renders as a link to the *concrete*
//      target object, using the WhatId_type + display name the record-ui backend
//      now supplies (dialect-sf-crm ui_api.go resolveRecordLookups).
// #2 (Details section order) is metadata-only and asserted in the pingcap pack.
// All values below are synthetic fixtures — no tenant/production data.

const host: CrmUiFieldHost = {
  SearchableLookup: () => null,
  RecordLink,
  decodeHtmlEntities: value => value,
  formatCurrency: value => String(value),
  formatDate: value => value,
  formatDateTime: value => value,
  getRecordValue: (record, fieldName) => record?.[fieldName],
  parseMultipicklistSelections: value => (Array.isArray(value) ? value.map(String) : []),
  joinMultipicklistSelections: values => values.join(';'),
};

const { fieldRenderers } = createCrmUiFieldComponents(host);
const LookupRenderer = fieldRenderers.reference;

const TASK_ID = '00T000000000001';
const OPPORTUNITY_ID = '006000000000001';
const OPPORTUNITY_NAME = 'Acme Expansion Opportunity';
const ACCOUNT_ID = '001000000000001';
const ACCOUNT_NAME = 'Acme Corporation';

describe('Task detail header title (#1: Subject is the name field)', () => {
  // Activity objects (Task/Event) have no Name column — Subject is their name.
  // getRecordName finds the field flagged as the name field (isNameField in the
  // object spec maps to schema.nameField); the fix adds that flag to Subject.
  const taskSchemaWithNameField = {
    fields: [
      { name: 'Subject', nameField: true },
      { name: 'Status' },
      { name: 'WhatId' },
    ],
  } as never;

  it('resolves the title to the Subject value when Subject is the name field', () => {
    const record = { Id: TASK_ID, Subject: 'Discovery Call' };
    expect(getRecordName(record, taskSchemaWithNameField)).toBe('Discovery Call');
  });

  it('regression guard: with no name field it falls back to the raw Id (the reported bug)', () => {
    const taskSchemaNoNameField = {
      fields: [{ name: 'Subject' }, { name: 'Status' }],
    } as never;
    const record = { Id: TASK_ID, Subject: 'Discovery Call' };
    expect(getRecordName(record, taskSchemaNoNameField)).toBe(TASK_ID);
  });
});

describe('Task detail "Related To" polymorphic lookup (#3)', () => {
  it('links WhatId to the concrete Opportunity target via WhatId_type + display name', () => {
    const onNavigate = vi.fn();
    render(
      <LookupRenderer
        field={{
          name: 'WhatId',
          label: 'Related To',
          type: 'reference',
          referenceTo: ['Account', 'Asset', 'Campaign', 'Case', 'Contract', 'Opportunity', 'Order', 'Product2', 'Quote'],
        }}
        value={OPPORTUNITY_ID}
        record={{ WhatId_type: 'Opportunity', WhatId_Display: OPPORTUNITY_NAME }}
        variant="detail"
        onNavigate={onNavigate}
      />,
    );

    const link = screen.getByRole('link', { name: new RegExp(OPPORTUNITY_NAME) });
    expect(link).toHaveClass('text-blue-600');
    expect(link).toHaveAttribute('href', `/object/Opportunity/${OPPORTUNITY_ID}`);

    fireEvent.click(link);
    expect(onNavigate).toHaveBeenCalledWith('Opportunity', OPPORTUNITY_ID);
  });

  it('is generic across targets: an Account-related task links to the Account', () => {
    const onNavigate = vi.fn();
    render(
      <LookupRenderer
        field={{
          name: 'WhatId',
          label: 'Related To',
          type: 'reference',
          referenceTo: ['Account', 'Opportunity', 'Case'],
        }}
        value={ACCOUNT_ID}
        record={{ WhatId_type: 'Account', WhatId_Display: ACCOUNT_NAME }}
        variant="detail"
        onNavigate={onNavigate}
      />,
    );

    const link = screen.getByRole('link', { name: new RegExp(ACCOUNT_NAME) });
    expect(link).toHaveAttribute('href', `/object/Account/${ACCOUNT_ID}`);
  });

  it('regression guard: without WhatId_type (pre-fix backend) it cannot link and shows plain text', () => {
    const onNavigate = vi.fn();
    render(
      <LookupRenderer
        field={{
          name: 'WhatId',
          label: 'Related To',
          type: 'reference',
          referenceTo: ['Account', 'Opportunity', 'Case'],
        }}
        value={OPPORTUNITY_ID}
        record={{}}
        variant="detail"
        onNavigate={onNavigate}
      />,
    );

    expect(screen.queryByRole('link')).toBeNull();
    expect(screen.getByText(OPPORTUNITY_ID)).toBeInTheDocument();
    expect(onNavigate).not.toHaveBeenCalled();
  });
});
