import React from 'react';
import { render, screen } from '@testing-library/react';
import { describe, expect, it } from 'vitest';
import { createCrmUiFieldComponents } from '../src/ui-field-components';
import type { CrmUiFieldPicklistValue } from '../src/ui-field-components';

const ORDINAL_BLUE = { backgroundColor: '#eff6ff', color: '#1e40af' };
const ORDINAL_VIOLET = { backgroundColor: '#f5f3ff', color: '#5b21b6' };
const SEMANTIC_SUCCESS = { backgroundColor: '#ecfdf5', color: '#065f46' };
const SEMANTIC_DANGER = { backgroundColor: '#fef2f2', color: '#991b1b' };

function createRenderers() {
  return createCrmUiFieldComponents({
    SearchableLookup: () => null,
    RecordLink: () => null,
    decodeHtmlEntities: value => value,
    htmlToText: 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(';'),
  }).fieldRenderers;
}

function picklistField(options: CrmUiFieldPicklistValue[]) {
  return { name: 'Stage', type: 'picklist', picklistValues: options };
}

describe('picklist badge style', () => {
  it('assigns ordinal palette colors by option position and wraps past the palette length', () => {
    const options = ['A', 'B', 'C', 'D', 'E', 'F'].map(v => ({ value: v, label: v }));
    const Picklist = createRenderers().picklist;

    render(
      <>
        <Picklist field={picklistField(options)} value="A" />
        <Picklist field={picklistField(options)} value="B" />
        <Picklist field={picklistField(options)} value="F" />
      </>,
    );

    expect(screen.getByText('A')).toHaveStyle(ORDINAL_BLUE);
    expect(screen.getByText('B')).toHaveStyle(ORDINAL_VIOLET);
    expect(screen.getByText('F')).toHaveStyle(ORDINAL_BLUE);
  });

  it('renders semantic styles for presentation-tagged values', () => {
    const options: CrmUiFieldPicklistValue[] = [
      { value: 'Open', label: 'Open' },
      { value: 'Won', label: 'Won', tags: ['presentation:success'] },
      { value: 'Lost', label: 'Lost', tags: ['other-tag', 'presentation:danger'] },
    ];
    const Picklist = createRenderers().picklist;

    render(
      <>
        <Picklist field={picklistField(options)} value="Won" />
        <Picklist field={picklistField(options)} value="Lost" />
      </>,
    );

    expect(screen.getByText('Won')).toHaveStyle(SEMANTIC_SUCCESS);
    expect(screen.getByText('Lost')).toHaveStyle(SEMANTIC_DANGER);
  });

  it('skips unknown presentation tokens and resolves a later valid one', () => {
    const options: CrmUiFieldPicklistValue[] = [
      { value: 'Recover', label: 'Recover', tags: ['presentation:sparkle', 'presentation:danger'] },
    ];
    const Picklist = createRenderers().picklist;

    render(<Picklist field={picklistField(options)} value="Recover" />);

    expect(screen.getByText('Recover')).toHaveStyle(SEMANTIC_DANGER);
  });

  it('does not resolve tokens through the object prototype chain', () => {
    const options: CrmUiFieldPicklistValue[] = [
      { value: 'Proto', label: 'Proto', tags: ['presentation:toString'] },
      { value: 'Ctor', label: 'Ctor', tags: ['presentation:constructor'] },
    ];
    const Picklist = createRenderers().picklist;

    render(
      <>
        <Picklist field={picklistField(options)} value="Proto" />
        <Picklist field={picklistField(options)} value="Ctor" />
      </>,
    );

    expect(screen.getByText('Proto')).toHaveStyle(ORDINAL_BLUE);
    expect(screen.getByText('Ctor')).toHaveStyle(ORDINAL_VIOLET);
  });

  it('gives values missing from the option list a stable on-palette color', () => {
    const options = [{ value: 'Open', label: 'Open' }];
    const Picklist = createRenderers().picklist;

    const first = render(<Picklist field={picklistField(options)} value="Legacy Won" />);
    const firstBackground = screen.getByText('Legacy Won').style.backgroundColor;
    first.unmount();

    render(<Picklist field={picklistField(options)} value="Legacy Won" />);
    expect(screen.getByText('Legacy Won').style.backgroundColor).toBe(firstBackground);
    expect(firstBackground).not.toBe('');
  });

  it('applies the same tiers to multipicklist chips', () => {
    const options: CrmUiFieldPicklistValue[] = [
      { value: 'OLTP', label: 'OLTP' },
      { value: 'HTAP', label: 'HTAP', tags: ['presentation:success'] },
    ];
    const Multi = createRenderers().multipicklist;

    render(
      <Multi
        field={{ name: 'UseCases', type: 'multipicklist', picklistValues: options }}
        value={['OLTP', 'HTAP']}
      />,
    );

    expect(screen.getByText('OLTP')).toHaveStyle(ORDINAL_BLUE);
    expect(screen.getByText('HTAP')).toHaveStyle(SEMANTIC_SUCCESS);
  });
});
