@use '@justeattakeaway/pie-css/scss' as p;

:host {
    // Defined on the host so consumers can override them directly (a declaration on the element
    // takes precedence over these defaults). Setting them on `pie-list` does not work, since the
    // host declaration wins over a value inherited from an ancestor.
    --list-item-inline-padding: var(--dt-spacing-d);
    --list-item-alignment: flex-start;

    // Using contents to remove the host from the box model so that the internal container element fully acts as the component shell
    display: block;
}

// Using an internal container div rather than applying directly to the host due to safari and firefox compat issues
.c-listItem-container {
    --list-item-block-padding: var(--dt-spacing-d);

    padding-inline-start: var(--list-item-inline-padding);
    padding-inline-end: var(--list-item-inline-padding);

    padding-block-start: var(--list-item-block-padding);
    padding-block-end: var(--list-item-block-padding);

    // Layout
    display: flex;
    align-items: var(--list-item-alignment);
    gap: var(--dt-spacing-c);
    min-height: 56px;
}

// When hasDivider is true, show a bottom border and subtract 1px from padding-block-end so the
// total item height is unchanged whether the divider is present or not.
.c-listItem-container.has-divider {
    padding-block-end: calc(var(--list-item-block-padding) - 1px);
    border-bottom: 1px solid var(--dt-color-divider-default);
}

// Two lines of text (primary + secondary) need top-alignment so leading/trailing
// content sits level with the first line, not centred across both lines.
.c-listItem-container:has(.c-listItem-secondaryText) {
    align-items: var(--list-item-alignment);
    min-height: 76px;
}

// Compact items keep their leading, trailing and meta content aligned with the first line of the
// primary text rather than centred across all of its lines.
.c-listItem-container.is-compact {
    // The height of a single line of primary text, used to align content with the first line.
    --list-item-first-line-height: #{p.line-height(--dt-font-body-l-line-height)};
    --list-item-block-padding: var(--dt-spacing-c);

    min-height: 48px;
}

// Overlay rows (link/button): the whole item is a single interactive target. The container is
// positioned so the slotted anchor/button can stretch over it.
.c-listItem-container.is-link,
.c-listItem-container.is-button {
    position: relative;
}

// Interactive row states. When the item is inside a radio/checkbox group the whole row
// is a click target (it forwards the click to the slotted control), so it shows hover and
// active surface tints, matching the control's own interactive states. These are suppressed
// when the slotted control is disabled (the item reflects this as `is-disabled`). The
// defaults use the standard PIE interactive overlay tokens; override `--list-item-hover-bg` /
// `--list-item-active-bg` if design specifies dedicated list tokens.
.c-listItem-container.is-selectable:not(.is-disabled),
.c-listItem-container.is-link,
.c-listItem-container.is-button:not(.is-disabled) {
    --list-item-hover-bg: hsl(var(--dt-color-black-h), var(--dt-color-black-s), var(--dt-color-black-l), var(--dt-color-hover-01));
    --list-item-active-bg: hsl(var(--dt-color-black-h), var(--dt-color-black-s), var(--dt-color-black-l), var(--dt-color-active-01));

    @supports (background-color: color-mix(in srgb, black, white)) {
        --list-item-hover-bg: color-mix(in srgb, var(--dt-color-hover-01-bg) var(--dt-color-hover-01), transparent);
        --list-item-active-bg: color-mix(in srgb, var(--dt-color-active-01-bg) var(--dt-color-active-01), transparent);
    }

    cursor: pointer;

    // Expose the current interaction tint to slotted controls via an inherited custom property (it
    // flows through the `<slot>` into slotted content). This is a generic contract for any control
    // inside an interactive container: a slotted `pie-switch` layers it over its track so the track
    // co-tints with the container; radio/checkbox instead let it show through their transparent
    // fills. Unset when not interacting, so a control outside such a container sees nothing.
    &:hover {
        background-color: var(--list-item-hover-bg);

        --interactive-container-tint: var(--list-item-hover-bg);
    }

    // The pressed tint for a pointer press: the container is an ancestor of the pressed element, so
    // it matches `:active`. (A keyboard press is handled by the `:has()` rule below, because keyboard
    // `:active` does not propagate up to the container.)
    &:active {
        background-color: var(--list-item-active-bg);

        --interactive-container-tint: var(--list-item-active-bg);
    }
}

// Pressed tint for a `button` row's keyboard press. A native `<button>` is `:active` while Space is
// held, but that state does not propagate to the container, so `&:active` above misses it. The
// action button is a real shadow-DOM descendant (not slotted), so `:has()` can react to its
// `:active` directly - no JS needed. A pointer press satisfies both this and `&:active` with the
// same value, so there is no double up.
.c-listItem-container.is-button:has(.c-listItem-action:active) {
    background-color: var(--list-item-active-bg);

    --interactive-container-tint: var(--list-item-active-bg);
}

// Stretch the interactive target over the entire row so the whole block is the click/touch target.
// For a link it is the consumer's slotted anchor; for a button it is the native <button> the item
// renders. Both anchor to the container (positioned above).
slot[name="link"]::slotted(a),
.c-listItem-action {
    position: absolute;
    inset: 0;
    z-index: 1;
    border-radius: inherit; // so the focus ring follows any rounding applied to the row
}

// The action element of a `button` row is a native <button> the item renders. Strip its chrome so
// it is invisible (the row provides the styling); it stays a real, focusable button with native
// pointer/keyboard activation and screen-reader semantics.
.c-listItem-action {
    padding: 0;
    border: none;
    background: transparent;
    appearance: none;
    font: inherit;
    cursor: pointer;
}

// A disabled action button shows the default cursor (it already ignores clicks and is unfocusable
// natively via the `disabled` attribute).
.c-listItem-action:disabled {
    cursor: default;
}

// Standard PIE focus ring. The anchor/action is row-sized, so keyboard focus rings the whole item.
slot[name="link"]::slotted(a:focus-visible),
.c-listItem-action:focus-visible {
    @include p.focus;
}

// Larger slotted media (e.g. pie-thumbnail) reduces the block padding, but only
// when the primary text stands alone (`:only-child` == no secondary text). With
// secondary text the default padding is kept so two lines of text sit correctly.
.c-listItem-container.has-media:has(.c-listItem-primaryText:only-child) {
    --list-item-block-padding: var(--dt-spacing-b);
}

.c-listItem-text {
    flex: 1;
}

slot[name="trailing"]::slotted(*),
.c-listItem-metaText {
    // Add a tiny bit of padding to the flex gap to make up 16px total
    padding-inline-start: var(--dt-spacing-a);
}

// Ensures that empty slots do not create a flex-gap in the container.
.c-listItem-leading, slot[name="leading"],
.c-listItem-trailing, slot[name="trailing"] {
    display: contents;
}

// Vertically stack the text items
.c-listItem-text > * {
    display: block;
}

// Flush trailing content to the end of the list-item
.c-listItem-trailing {
    margin-inline-start: auto;
}

.c-listItem-metaText {
    display: block;
    max-width: calc(100% / 3);
}

::slotted(.c-pieIcon) {
    --icon-size-override: 24px;

    color: var(--dt-color-content-subdued);
}

.c-listItem-container.is-button.is-disabled,
.c-listItem-container.is-selectable.is-disabled {
    .c-listItem-primaryText,
    .c-listItem-secondaryText,
    .c-listItem-metaText {
        color: var(--dt-color-content-disabled);
    }
}

.c-listItem-container.is-button.is-disabled ::slotted(.c-pieIcon),
.c-listItem-container.is-selectable.is-disabled ::slotted(.c-pieIcon) {
    opacity: 0.5;
}

// typography

.c-listItem-primaryText {
    @include p.font-theme('font-body-l');
    color: var(--dt-color-content-default);
}

.c-listItem-container.is-bold .c-listItem-primaryText {
    @include p.font-theme('font-body-strong-l');
}

.c-listItem-secondaryText {
    @include p.font-theme('font-body-s');
    color: var(--dt-color-content-subdued);
}

.c-listItem-metaText {
    @include p.font-theme('font-body-s');
    color: var(--dt-color-content-subdued);
}

// `metaText` uses `font-body-s`, so its line box is 20px rather than the primary text's 24px. In a
// compact row, a one-line-tall centring box sits it on the centre of the first line of primary text
// instead of 2px above it.
.c-listItem-container.is-compact .c-listItem-metaText {
    display: flex;
    align-items: center;
    min-height: var(--list-item-first-line-height);
}
