/** @format */

import { RadioComponentConfig } from '../types/RadioComponentConfig';

export class Radio {
  private Templates: typeof window.Formio.Templates;

  constructor() {
    this.Templates = window.Formio.Templates || {};
  }

  radioStyle(): string {
    return `
      .bc-radios, .bc-radios__item {
        position: relative;
      }
      .bc-radios {
        border: none !important;
        padding: 0 !important;
      }
      .bc-radios__item {
        display: flex;
        flex-wrap: wrap;
        margin-bottom: 10px;
      }
      .bc-radios__input {
        z-index: 1;
        width: 44px;
        height: 44px;
        margin: 0 !important;
        opacity: 0;
        left: 0;
        top: 0;
        cursor: pointer;
      }
      .bc-radio__label {
        align-self: center;
        max-width: calc(100% - 74px);
        margin-bottom: 0;
        margin-left: 40px;
        padding: 7px 15px;
        cursor: pointer;
        touch-action: manipulation;
      }
      .bc-radio__label > .bc_checkedItem:before {
        content: "";
        box-sizing: border-box;
        position: absolute;
        top: 2px;
        left: 2px;
        width: 40px;
        height: 40px;
        border: 2px solid;
        border-radius: 50%;
        background: transparent;
      }
      .bc-radio__label > .bc_checkedItem:after {
        content: "";
        position: absolute;
        top: 12px;
        left: 12px;
        width: 0;
        height: 0;
        border: 10px solid;
        border-radius: 50%;
        opacity: 0;
        background: #000;
      }
      .bc-radios__input:checked + .bc_checkedItem:after {
        opacity: 1;
      }
      .bc-radios__input:checked + .bc_checkedItem:before,
      .bc-radios__input[type=radio]:focus + .bc_checkedItem:before {
        outline: 3px solid rgba(0, 0, 0, 0) !important;
        outline-offset: 1px;
        box-shadow: 0 0 0 3px #fd0 !important;
        border-width: 4px;
      }`;
  }

  radio(): { form: (ctx: RadioComponentConfig) => string } {
    return {
      form: (ctx: RadioComponentConfig): string => {
        return `
        <fieldset
          class="govuk-radios bc-radios ${ctx.inline ? 'govuk-radios--inline' : ''}"
          ref="radioGroup"
          role="${ctx.component.type === 'selectboxes' ? 'group' : 'radiogroup'}"
          aria-required="${ctx.component.validate?.required}"
          aria-labelledby="${ctx.instance.id}-${ctx.component.key}--legend"
          ${
            ctx.component.description
              ? `aria-describedby="d-${ctx.instance.id}-${ctx.component.key}"`
              : ''
          }
        >
          <legend hidden id="${ctx.instance.id}-${ctx.component.key}--legend">${
          ctx.component.label
        }</legend>
          ${ctx.values
            .map((item, index) => {
              const inputId = `${ctx.instance?.root?.id}-${ctx.id}-${ctx.row}-${
                typeof item.value === 'object' ? item.value + '-' + index : item.value
              }`;
              const isChecked =
                ctx.value &&
                (ctx.value === item.value ||
                  (typeof ctx.value === 'object' &&
                    Object.prototype.hasOwnProperty.call(ctx.value, item.value) &&
                    ctx.value[item.value]));

              return `
            <div class="bc-radios__item ${ctx.input.attr.type} form-check${
                ctx.inline ? '-inline' : ''
              }" ref="wrapper">
              <label class="bc-radio__label label-position-${
                ctx.component.optionsLabelPosition
              }" for="${inputId}">
                ${
                  ['left', 'top'].includes(ctx.component.optionsLabelPosition)
                    ? `<span>${ctx.t(item.label, { _userInput: true })}</span>`
                    : ''
                }
                <input
                  ref="input"
                  class="bc-radios__input${ctx.input.attr.class ? ' ' + ctx.input.attr.class : ''}"
                  ${Object.entries(ctx.input.attr)
                    .filter(([key]) => key !== 'class')
                    .map(([key, val]) => `${key}="${val}"`)
                    .join(' ')}
                  value="${item.value}"
                  ${isChecked ? 'checked' : ''}
                  ${item.disabled ? 'disabled' : ''}
                  id="${inputId}"
                  role="${ctx.component.type === 'selectboxes' ? 'checkbox' : 'radio'}"
                />
                <span class="bc_checkedItem"></span>
                ${
                  !ctx.component.optionsLabelPosition ||
                  ['right', 'bottom'].includes(ctx.component.optionsLabelPosition)
                    ? `<span>${ctx.t(item.label, { _userInput: true })}</span>`
                    : ''
                }
              </label>
            </div>`;
            })
            .join('')}
        </fieldset>`;
      },
    };
  }

  componentStyles(): string[] {
    return [this.radioStyle()];
  }

  styleTagContent(): string {
    return this.componentStyles().join('\n');
  }

  injectStyleToHead(): void {
    if (!document.getElementById('custom-bc-template__style')) {
      const styleTag = document.createElement('style');
      styleTag.id = 'custom-bc-template__style';
      styleTag.textContent = this.styleTagContent();
      document.head.appendChild(styleTag);
    }
  }

  init(): void {
    this.Templates.current = {
      radio: this.radio(),
    };
    this.injectStyleToHead();
  }
}
