/**
 * @license
 * Copyright (c) 2025 - 2026 Vaadin Ltd.
 * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
 */
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';

export interface MasterDetailLayoutCustomEventMap {
  'backdrop-click': Event;

  'detail-escape-press': Event;
}

export interface MasterDetailLayoutEventMap extends HTMLElementEventMap, MasterDetailLayoutCustomEventMap {}

/**
 * `<vaadin-master-detail-layout>` is a web component for building UIs with a master
 * (or primary) area and a detail (or secondary) area that is displayed next to, or
 * overlaid on top of, the master area, depending on configuration and viewport size.
 *
 * ### Slots
 *
 * The component has two main content areas: the master area (default slot)
 * and the detail area (`detail` slot). When the detail doesn't fit next to
 * the master, it is shown as an overlay on top of the master area:
 *
 * ```html
 * <vaadin-master-detail-layout>
 *   <div>Master content</div>
 *   <div slot="detail">Detail content</div>
 * </vaadin-master-detail-layout>
 * ```
 *
 * The component also supports a `detail-placeholder` slot for content shown
 * in the detail area when no detail is selected. Unlike the `detail` slot,
 * the placeholder is simply hidden when it doesn't fit next to the master area,
 * rather than shown as an overlay:
 *
 * ```html
 * <vaadin-master-detail-layout>
 *   <div>Master content</div>
 *   <div slot="detail-placeholder">Select an item</div>
 * </vaadin-master-detail-layout>
 * ```
 *
 * ### Styling
 *
 * The following shadow DOM parts are available for styling:
 *
 * Part name             | Description
 * ----------------------|----------------------
 * `backdrop`            | Backdrop covering the master area in the overlay mode
 * `master`              | The master area
 * `detail`              | The detail area
 * `detail-placeholder`  | The detail placeholder area
 *
 * The following state attributes are available for styling:
 *
 * Attribute                 | Description
 * --------------------------|----------------------
 * `expand-master`           | Set when the master area expands to fill available space.
 * `expand-detail`           | Set when the detail area expands to fill available space.
 * `orientation`             | Set to `horizontal` or `vertical` depending on the orientation.
 * `has-detail`              | Set when the detail content is provided and visible.
 * `has-detail-placeholder`  | Set when the detail placeholder content is provided.
 * `overlay`                 | Set when columns don't fit and the detail is shown as an overlay.
 * `overlay-containment`     | Set to `layout` or `page`.
 *
 * The following custom CSS properties are available for styling:
 *
 * Custom CSS property                                  |
 * :----------------------------------------------------|
 * | `--vaadin-master-detail-layout-border-color`       |
 * | `--vaadin-master-detail-layout-border-width`       |
 * | `--vaadin-master-detail-layout-detail-background`  |
 * | `--vaadin-master-detail-layout-detail-shadow`      |
 * | `--vaadin-overlay-backdrop-background`             |
 *
 * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
 *
 * @fires {CustomEvent} backdrop-click - Fired when the user clicks the backdrop in the overlay mode.
 * @fires {CustomEvent} detail-escape-press - Fired when the user presses Escape in the detail area.
 */
declare class MasterDetailLayout extends ThemableMixin(ElementMixin(HTMLElement)) {
  /**
   * Size (in CSS length units) to be set on the detail area in
   * the CSS grid layout. When there is not enough space to show
   * master and detail areas next to each other, the detail area
   * is shown as an overlay.
   * <p>
   * If not specified, the size is determined automatically by measuring
   * the detail content in a `min-content` CSS grid column when it first
   * becomes visible, and then caching the resulting intrinsic size. To
   * recalculate the cached intrinsic size, use the `recalculateLayout`
   * method.
   *
   * @attr {string} detail-size
   */
  detailSize: string | null | undefined;

  /**
   * Size (in CSS length units) to be set on the master area in
   * the CSS grid layout. If there is not enough space to show
   * master and detail areas next to each other, the detail area
   * is shown as an overlay. Defaults to 30em.
   *
   * @attr {string} master-size
   */
  masterSize: string | null | undefined;

  /**
   * Size (in CSS length units) for the detail area when shown as an
   * overlay. When not set, falls back to `detailSize`. Set to `100%`
   * to make the detail cover the full layout.
   *
   * @attr {string} overlay-size
   */
  overlaySize: string | null | undefined;

  /**
   * Define how master and detail areas are shown next to each other,
   * and the way how size and min-size properties are applied to them.
   * Possible values are: `horizontal` or `vertical`.
   * Defaults to horizontal.
   */
  orientation: 'horizontal' | 'vertical';

  /**
   * Defines the containment of the detail area when the layout is in
   * overlay mode. When set to `layout`, the overlay is confined to the
   * layout. When set to `page`, the overlay is confined to the
   * browser's viewport. Defaults to `layout`.
   *
   * @attr {string} overlay-containment
   */
  overlayContainment: 'layout' | 'page';

  /**
   * When true, the master area grows to fill the available space.
   * If `expandDetail` is also true, both areas share the available
   * space equally.
   *
   * @attr {boolean} expand-master
   */
  expandMaster: boolean;

  /**
   * When true, the detail area grows to fill the available space.
   * If `expandMaster` is also true, both areas share the available
   * space equally.
   *
   * @attr {boolean} expand-detail
   */
  expandDetail: boolean;

  /**
   * When true, the layout does not use animated transitions for the detail area.
   *
   * @attr {boolean} no-animation
   */
  noAnimation: boolean;

  /**
   * When true, the layout forces the detail area to be shown as an overlay,
   * even if there is enough space for master and detail to be shown next to
   * each other using the default (split) mode.
   *
   * @attr {boolean} force-overlay
   */
  forceOverlay: boolean;

  /**
   * When `detailSize` is not explicitly set, re-measures the cached intrinsic size of
   * the detail content by placing it in a min-content CSS grid column, then repeats
   * this process for ancestor master-detail layouts without an explicit `detailSize`,
   * if any, so that their detail areas also adapt.
   *
   * Call this method after changing the detail content in a way that affects its intrinsic
   * size — for example, when opening a detail in a nested master-detail layout that was
   * not previously visible.
   *
   * NOTE: This method can be expensive in large layouts as it triggers consecutive
   * synchronous DOM reads and writes.
   */
  recalculateLayout(): void;

  addEventListener<K extends keyof MasterDetailLayoutEventMap>(
    type: K,
    listener: (this: MasterDetailLayout, ev: MasterDetailLayoutEventMap[K]) => void,
    options?: AddEventListenerOptions | boolean,
  ): void;

  removeEventListener<K extends keyof MasterDetailLayoutEventMap>(
    type: K,
    listener: (this: MasterDetailLayout, ev: MasterDetailLayoutEventMap[K]) => void,
    options?: EventListenerOptions | boolean,
  ): void;
}

declare global {
  interface HTMLElementTagNameMap {
    'vaadin-master-detail-layout': MasterDetailLayout;
  }
}

export { MasterDetailLayout };
