@use '../abstracts/functions';
@use 'sass:map';
@use '../abstracts/variables';
@use '../abstracts/mixins/breakpoints' as *;
@use '../abstracts/mixins/container-queries' as *;
@use '../abstracts/mixins/typography';

$-module-name: 'pkt-fileupload';

pkt-fileupload {
  display: block;
}

.pkt-fileupload-component {
  display: block;
}

.pkt-fileupload {
  display: block;
  width: min(100%, 31rem);
  --fg-color: var(--pkt-color-text-body-default);

  // Visually hide file input but keep it accessible for screen readers
  input[type='file'] {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }

  // ============================================
  // COMPONENT MODIFIERS
  // ============================================

  &--full-width {
    width: 100%;

    .pkt-fileupload__drop-zone,
    .pkt-fileupload__queue-display,
    .pkt-fileupload__queue-display__item {
      width: 100%;
    }
  }

  &--error {
    .pkt-fileupload__drop-zone {
      border-color: functions.color-token('input-border-error');
    }

    .pkt-alert--error.pkt-fileupload__error-alert {
      margin-block-end: 1rem;
      width: 100%;
    }
  }

  &--disabled {
    pointer-events: none;
    --fg-color: var(--pkt-color-text-action-disabled);

    .pkt-fileupload__drop-zone__placeholder__icon svg {
      --fg-color: var(--pkt-color-text-action-disabled);
    }

    p,
    label,
    button,
    input[type='text'] {
      color: var(--pkt-color-text-action-disabled);
    }

    .pkt-fileupload__drop-zone {
      cursor: not-allowed;
      border-color: var(--pkt-color-input-border-disabled);
      background: var(--pkt-color-input-background-disabled);

      &__placeholder__title,
      &__placeholder__title__open-file-dialog {
        color: var(--pkt-color-text-action-disabled);
        text-decoration: underline;
      }
    }
  }

  // ============================================
  // DROP ZONE
  // ============================================

  &__drop-zone {
    border: 1px dashed var(--pkt-color-input-border-normal);
    color: var(--pkt-color-text-action-normal);
    cursor: pointer;
    padding: 2rem;
    text-align: center;
    margin-block-end: 1rem;
    font-size: 14px;

    &:hover {
      border-color: var(--pkt-color-input-border-hover);
    }

    &:active,
    &--drag-active {
      background-color: var(--pkt-color-surface-default-default);
      border: 2px dashed var(--pkt-color-input-border-active);
      padding: calc(2rem - 1px);
    }

    &:focus-within {
      border-color: var(--pkt-color-input-border-active);
      outline: 2px solid var(--pkt-color-border-states-focus);
      outline-offset: 0;
    }

    &:hover &__placeholder__icon svg,
    &:focus-within &__placeholder__icon svg {
      --fg-color: var(--pkt-color-text-action-hover);
    }

    &:hover &__placeholder__title,
    &:hover &__placeholder__title__open-file-dialog,
    &:focus-within &__placeholder__title,
    &:focus-within &__placeholder__title__open-file-dialog {
      color: var(--pkt-color-text-action-hover);
    }

    &__placeholder {
      text-align: left;
      display: grid;
      grid-template-areas:
        'left top'
        'left bottom';
      grid-template-columns: 24px auto;
      grid-template-rows: auto auto;
      grid-column-gap: 1rem;
      width: fit-content;
      margin: auto;
      line-height: 22px;
      pointer-events: none;

      p {
        margin: 0;
      }

      &__icon {
        width: 24px;
        height: 24px;
        grid-area: left;
        align-self: center;
        justify-self: center;

        svg {
          --fg-color: var(--pkt-color-input-border-normal);
        }
      }

      &__title {
        @include typography.get-text('pkt-txt-14-light');
        grid-area: top;

        &__open-file-dialog {
          pointer-events: auto;
          cursor: pointer;
          color: var(--pkt-color-text-action-normal);
          text-decoration: underline;
          background: none;
          border: none;
          padding: 0;
          font: inherit;

          &:hover {
            color: var(--pkt-color-text-action-hover);
          }

          &:focus-visible {
            outline: 2px solid var(--pkt-color-border-states-focus);
            outline-offset: 2px;
          }
        }
      }

      &__formats {
        @include typography.get-text('pkt-txt-12-light');
        color: var(--pkt-color-text-placeholder);
        grid-area: bottom;
      }
    }
  }

  // ============================================
  // QUEUE DISPLAY
  // ============================================

  &__queue-display {
    display: flex;
    flex-direction: column;
    padding: 0;
    margin-block-start: 0;
    margin-block-end: 1rem;
    row-gap: map.get(variables.$spacing, 'size-8');

    container-type: inline-size;
    container-name: queue-item;

    &__item__rename-input {
      // Bruker <input>, og ikke <PktInput> for å ikke måtte resette masse stiler fra PktInput. Så må settes manuelt.
      border: 2px solid var(--pkt-color-input-border-normal);
      color: var(--pkt-color-text-body-default);
      background-color: var(--pkt-color-background-default);
      border-radius: 0;
      margin: 0;
      width: 100%;

      &:hover {
        border-color: var(--pkt-color-input-border-hover);
      }

      &:focus-visible,
      &:focus,
      &:active {
        border-color: var(--pkt-color-input-border-active);
      }
    }

    // Thumbnail grid layout (when thumbnails are present)
    // In-progress and error items are always full width (not in grid)
    &:is(:has(.pkt-fileupload__queue-display__item__thumbnail)) {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
      gap: 1rem;
      max-width: 100%;

      // Successfully uploaded thumbnails become grid items
      .pkt-fileupload__queue-display__item:is(:has(.pkt-fileupload__queue-display__item__thumbnail)) {
        border: 2px solid var(--pkt-color-border-subtle);
        display: flex;
        flex-direction: column;
        padding: map.get(variables.$spacing, 'size-8');
        min-width: 0;
        overflow: hidden;
        justify-content: end;
      }

      // In-progress items span full width
      .pkt-fileupload__queue-display__item--in-progress {
        grid-column: 1 / -1;
      }

      // Error items span full width
      .pkt-fileupload__queue-display__item--error {
        grid-column: 1 / -1;
      }

      .pkt-fileupload__queue-display__item__thumbnail {
        width: 100%;
        min-width: 0; // Allow truncation to work
      }

      .pkt-fileupload__queue-display__item__actions {
        display: flex;
        flex-direction: column;
        width: 100%;
        padding-inline-start: 0;
        align-items: flex-start;
        gap: 0.5rem;
      }
    }

    // ----------------------------------------
    // Queue Item (base styles)
    // ----------------------------------------

    &__item {
      display: grid;
      grid-template-columns: auto minmax(0, 1fr);
      align-items: center;
      gap: 0.5rem;
      padding: map.get(variables.$spacing, 'size-16');
      border: 2px solid var(--pkt-color-border-subtle);

      // ----------------------------------------
      // Queue Item Elements
      // ----------------------------------------

      &__icon {
        grid-column: 1;
        grid-row: 1;
        align-self: center;
        justify-self: center;
        color: functions.color-token('text-placeholder');
      }

      &__title {
        @include typography.get-text('pkt-txt-16-light');
        grid-column: 2;
        grid-row: 1;
        min-width: 0;
        max-width: 100%;
        align-self: center;
        margin: 0;
        display: flex;
        align-items: baseline;
        flex-wrap: nowrap;
        overflow: hidden;
      }

      &__actions {
        grid-column: 1/-1;
        grid-row: 2;
        align-self: center;
        justify-self: flex-start;
        display: flex;
        gap: 1rem;
        flex-wrap: wrap;
      }

      &__filesize {
        @include typography.get-text('pkt-txt-14-light');
        color: var(--pkt-color-text-placeholder);
        flex: 0 0 auto;
        white-space: nowrap;
        padding-inline-start: 0.5rem;
      }

      &__cancel-button {
        @include typography.get-text('pkt-txt-14-light');
        cursor: pointer;
        color: inherit;
        text-decoration: underline;
        background: none;
        border: none;
        padding: 0;

        &:hover {
          color: var(--pkt-color-text-action-hover);
        }

        &:focus-visible {
          outline: 2px solid var(--pkt-color-border-states-focus);
          outline-offset: 2px;
        }
      }

      &__operation {
        @include typography.get-text('pkt-txt-14-light');
        cursor: pointer;
        color: var(--pkt-color-text-action-normal);
        text-decoration: underline;
        background: none;
        border: none;
        padding: 0;

        &:hover {
          color: var(--pkt-color-text-action-hover);
        }

        &:focus-visible {
          outline: 2px solid var(--pkt-color-border-states-focus);
          outline-offset: 2px;
        }
      }

      &__inline-ui {
        grid-column: 2 / -1; // Span to end to fill space when actions are hidden
        grid-row: 1;
        display: flex;
        align-items: center;
        gap: 0.5rem;

        .pkt-input,
        input[type='text'] {
          flex: 1;
          min-width: 0;
          padding: 0 map.get(variables.$spacing, 'size-8');
          border: 2px solid var(--pkt-color-input-border-normal);
          font: inherit;

          &:focus {
            outline: none;
            border-color: var(--pkt-color-input-border-active);
          }
        }

        .pkt-btn {
          height: map.get(variables.$spacing, 'size-32');
          min-height: 0;
        }
      }

      &__operation-content {
        grid-column: 1 / -1;
        padding: 0.75rem 1rem;
        background: var(--pkt-color-surface-default-default);
        margin-block-start: 0.5rem;

        &:empty {
          display: none;
        }
      }

      &__expanded-operation-ui {
        grid-column: 1 / -1;
        display: grid;
        grid-template-columns: auto 1fr;
        align-items: flex-start;
        gap: 0.5rem;

        .pkt-btn {
          grid-row: 3;
        }
      }

      &__comment-label {
        grid-column: 1/-1;

        grid-row: 1;

        @include typography.get-text('pkt-txt-16-medium');
      }

      &__comment-input {
        grid-column: 1/-1;
        grid-row: 2;
        width: 100%;
        font: inherit;
        @include typography.get-text('pkt-txt-14');

        &:focus {
          outline: none;
          border-color: var(--pkt-color-input-border-active);
        }

        &::placeholder {
          color: var(--pkt-color-text-placeholder);
        }
      }

      &__comment {
        display: flex;
        justify-content: space-between;
        align-items: flex-start;
        gap: 1rem;
        color: var(--pkt-color-text-body-default);

        &__content {
          flex: 1;
        }

        &__text {
          @include typography.get-text('pkt-txt-16-light');
          display: block;
        }

        &__time {
          @include typography.get-text('pkt-txt-12-medium');
          display: block;
          margin-block-start: 0.25rem;
        }

        &__actions {
          display: flex;
          gap: 0.5rem;
          flex-shrink: 0;

          .pkt-icon svg {
            --fg-color: currentColor;
          }
        }

        &__action {
          background: none;
          border: none;
          padding: 0;
          cursor: pointer;
          color: var(--pkt-color-text-body-default);
          display: flex;
          align-items: center;
          justify-content: center;

          &:hover {
            color: var(--pkt-color-text-action-hover);
          }

          &:focus-visible {
            outline: 2px solid var(--pkt-color-border-states-focus);
            outline-offset: 2px;
          }

          .pkt-icon {
            width: 12px;
            height: 15px;
          }
        }
      }

      &__thumbnail {
        min-width: 0;

        // Same element as React: .thumbnail__image-wrapper and .pkt-btn on one <button>
        &__image-wrapper.pkt-btn {
          position: relative;
          display: block;
          width: 100%;
          height: max-content;
          min-height: 0;
          padding: 0;
          border: 0;
          background: none;
          cursor: pointer;

          .pkt-btn__text {
            display: block;
            width: 100%;
            line-height: 0;
          }

          img {
            display: block;
            width: 100%;
            aspect-ratio: 1;
            object-fit: cover;
          }

          &:hover,
          &:focus-visible {
            .pkt-fileupload__queue-display__item__thumbnail__expand-icon {
              background-color: var(--pkt-color-text-action-hover);
              svg {
                --fg-color: var(--pkt-color-text-body-light);
              }
            }
          }
        }

        &__expand-icon {
          position: absolute;
          top: 0.25rem;
          right: 0.25rem;
          width: 30px;
          height: 30px;
          z-index: 2;
          background-color: var(--pkt-color-background-subtle);
          pointer-events: none;
          padding: 2px;
        }

        &__title {
          @include typography.get-text('pkt-txt-14');
          margin-block-start: 0.5rem;
          margin-block-end: 0.25rem;
          min-width: 0;
          max-width: 100%;
          overflow: hidden;
          white-space: nowrap;
          overflow-wrap: anywhere;
          word-break: break-word;
          -webkit-line-clamp: 2;
          line-clamp: 2;
        }

        &--fallback {
          .pkt-fileupload__queue-display__item__thumbnail__title {
            @include typography.get-text('pkt-txt-14');
          }
        }
      }

      // ----------------------------------------
      // Queue Item State Modifiers
      // ----------------------------------------

      &--canceled {
        opacity: 0.6;
      }

      // Shared styles for transfer states
      &--in-progress,
      &--error {
        border: none;
        grid-template-columns: auto 1fr auto;
        padding: 1rem;
        row-gap: 0.5rem;

        .pkt-fileupload__queue-display__item__icon {
          grid-column: 1;
          grid-row: 1;

          svg {
            --fg-color: currentColor;
          }
        }

        .pkt-fileupload__queue-display__item__title {
          @include typography.get-text('pkt-txt-16-medium');
          grid-column: 2;
          grid-row: 1;
          margin: 0;
        }

        .pkt-fileupload__queue-display__item__cancel-button {
          grid-column: 3;
          grid-row: 1;
          margin-inline-start: 1rem;
        }

        .pkt-fileupload__queue-display__item__error-message {
          @include typography.get-text('pkt-txt-12');
          grid-column: 2;
          grid-row: 2;
        }

        .pkt-progressbar__bar-wrapper {
          height: map.get(variables.$spacing, 'size-4');
        }
      }

      // Error state (indeterminate - no progress bar)
      &--error {
        background-color: var(--pkt-color-surface-default-faded-red);
        color: var(--pkt-color-text-body-dark);

        .pkt-fileupload__queue-display__item__icon {
          align-self: center;
        }

        .pkt-fileupload__queue-display__item__cancel-button:hover {
          color: var(--pkt-color-brand-warm-blue-1000);
        }

        .pkt-progressbar__bar-wrapper {
          background-color: var(--pkt-color-surface-default-gray);
        }

        // Error state with progress bar (determinate upload that failed)
        &:is(:has(.pkt-fileupload__queue-display__item__progress--error)) {
          background-color: var(--pkt-color-surface-default-faded-red);
          grid-template-rows: auto auto auto;

          .pkt-fileupload__queue-display__item__progress {
            grid-column: 1 / -1;
            grid-row: 2;
            margin: 0;

            // Override progress bar fill to red
            .pkt-progressbar__bar {
              background-color: var(--pkt-color-brand-red-1000);
            }
          }

          .pkt-fileupload__queue-display__item__error-message {
            grid-column: 2 / -1;
            grid-row: 3;
            text-align: right;
          }
        }
      }

      // In-progress state
      &--in-progress {
        background-color: var(--pkt-color-surface-default-default);
        color: var(--pkt-color-text-body-default);
        grid-template-rows: auto auto auto;

        .pkt-fileupload__queue-display__item__progress {
          grid-column: 1 / -1;
          grid-row: 2;
          margin: 0;
        }

        .pkt-fileupload__queue-display__item__percentage {
          @include typography.get-text('pkt-txt-12');
          grid-column: 3;
          grid-row: 3;
          text-align: right;
        }

        .pkt-fileupload__queue-display__item__loading-text {
          @include typography.get-text('pkt-txt-12');
          grid-column: 2;
          grid-row: 2;

          &::after {
            content: '...';
            display: inline-block;
            overflow: hidden;
            vertical-align: baseline;
            width: 0;
            animation: pkt-fileupload-loading-dots 1.2s steps(4, end) infinite;
          }
        }
      }
    }
  }
}

@keyframes pkt-fileupload-loading-dots {
  0%,
  100% {
    width: 0;
  }
  33% {
    width: 0.4em;
  }
  66% {
    width: 0.8em;
  }
  99% {
    width: 1.2em;
  }
}

@media (prefers-reduced-motion: reduce) {
  .pkt-fileupload__queue-display__item__loading-text::after {
    animation: none;
    width: 1.2em; // show the three dots at rest rather than stepping
  }
}

// Middle-truncation for long filenames — head shrinks, tail and filesize stay fixed.
.pkt-fileupload__queue-display__item__title__head {
  min-width: 0;
  flex: 0 1 auto;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.pkt-fileupload__queue-display__item__title__tail {
  flex: 0 0 auto;
  white-space: nowrap;
}

[data-pkt-truncate-part='first']:not(.pkt-fileupload__queue-display__item__title__head) {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.pkt-fileupload__queue-display__item__thumbnail__title:is(:has(> .pkt-fileupload__queue-display__item__title__tail)) {
  display: flex;
  flex-wrap: nowrap;
  overflow: hidden;
}

// ============================================
// WRAPPER INTEGRATION (InputWrapper)
// ============================================

.pkt-fileupload-wrapper {
  &--full-width {
    width: 100%;

    .pkt-inputwrapper__fieldset {
      width: 100%;
      align-items: stretch;
    }
  }

  .pkt-inputwrapper__fieldset {
    margin-block-end: 0;
  }

  .pkt-inputwrapper__helptext {
    margin-block-end: 0.5rem;
  }
}

// ============================================
// IMAGE PREVIEW MODAL
// ============================================
// React: `className` is merged onto <dialog class="pkt-modal … pkt-fileupload__image-preview-modal">`.
// Elements: the same class lives on <pkt-modal>, dialog is only `.pkt-modal`.
// Use both selector forms so lightbox sizing and header/content overrides apply everywhere.

.pkt-fileupload__image-preview-modal {
  // Reset padding from modal (docs / legacy)
  .pkt-contents {
    padding: 0;
  }
}

// ============================================
// MODAL OVERRIDES to make it look like a lightbox!
// TODO: When we get an actual PktLightBox component, we can remove these overrides.
// ============================================

.pkt-modal.pkt-fileupload__image-preview-modal,
pkt-modal.pkt-fileupload__image-preview-modal .pkt-modal {
  // Shrink-wrap to content; beat `.pkt-modal--medium { width: … }` and full-viewport dialog defaults.
  box-sizing: border-box;
  width: fit-content;
  max-width: min(92vw, 56rem);
  max-height: min(92vh, 56rem);
  height: auto;
  margin: auto;

  // Let the body row shrink so tall images cannot push the counter below the viewport.
  .pkt-modal__wrapper {
    max-height: min(92vh, 56rem);
    min-height: 0;
    grid-template-rows: auto minmax(0, 1fr);
  }

  .pkt-modal__container {
    min-height: 0;
  }

  .pkt-modal__header {
    text-align: left;
  }

  .pkt-modal__headingText {
    line-height: 2rem;
    padding: 1rem 0 0 1.5rem;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    max-width: calc(100% - 3rem);
    background-color: transparent;
    color: var(--pkt-color-text-body-default);
  }

  .pkt-modal__container {
    padding-block-start: 0;
    background-color: transparent;
  }

  .pkt-modal__content {
    padding: 0 map.get(variables.$spacing, 'size-16') map.get(variables.$spacing, 'size-16');
    // Strip scroll-hint gradients from `_modal.scss` so the image and counter stay clear.
    background: functions.color-token('background-default');
    background-image: none;
    box-shadow: none;
    // Rejoin the modal flex/grid chain: visible overflow lets intrinsic image height ignore the viewport cap.
    min-height: 0;
    overflow: auto;
    overscroll-behavior: contain;

    // Stretch preview so inner grid `1fr` gets a real height and the image can shrink (light DOM + React).
    .pkt-fileupload__image-preview {
      flex: 1 1 auto;
      min-height: 0;
      align-self: stretch;
      width: 100%;
    }
  }

  .pkt-modal__closeButton {
    background-color: transparent;

    .pkt-btn {
      color: var(--pkt-color-text-body-default);

      &:hover,
      &:focus-visible {
        color: var(--pkt-color-text-action-hover);
      }
    }
  }

  &::backdrop {
    background-color: rgba(0, 0, 0, 0.85);
  }
}

.pkt-fileupload__image-preview {
  position: relative;
  background-color: functions.color-token('background-default');
  display: grid;
  grid-template-columns: auto 1fr auto;
  // First row takes remaining space but may shrink (tall portraits); second row keeps the counter on-screen.
  grid-template-rows: minmax(0, 1fr) auto;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 0;
  // Fallback when host layout does not pass a height down (extra safety vs. huge intrinsic size).
  max-height: min(calc(92vh - 6rem), 56rem);

  &__content {
    min-height: 0;
    height: 100%;
    grid-column: 1 / -1;
    grid-row: 1;
    z-index: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 1;
    min-width: 0;
    overflow: hidden;
  }

  &__image {
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    object-fit: contain;
  }

  &__nav {
    &--prev {
      grid-column: 1;
      grid-row: 1;
      margin-inline-start: 0.5rem;
    }

    &--next {
      grid-column: 3;
      grid-row: 1;
      margin-inline-end: 0.5rem;
    }

    // Same element as React: nav BEM + `.pkt-btn--medium` — round hit target; skin from `.pkt-btn--secondary`.
    &.pkt-btn {
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      z-index: 2;
      justify-self: center;
      align-self: center;
      border-radius: 50%;
      box-sizing: border-box;
      width: 3rem;
      height: 3rem;
      min-width: 3rem;
      min-height: 3rem;
      padding: 0;
      background-color: var(--pkt-color-background-default);

      .pkt-btn__icon,
      .pkt-icon {
        width: 1.5rem;
        height: 1.5rem;
      }
    }
  }

  &__counter {
    @include typography.get-text('pkt-txt-14-medium');
    color: var(--pkt-color-text-body-default);
    grid-column: 1 / -1;
    grid-row: 2;
    z-index: 1;
    position: relative;
    justify-self: center;
    text-align: center;
  }
}
