<template>
  <label :class="labelClasses" :for="id">
    <input
      type="checkbox"
      :id="id"
      :checked="modelValue"
      :disabled="disabled"
      @change="onChange"
    />
    <span class="checkmark"></span>
    <span v-if="label" class="checkbox-text-label">{{ label }}</span>
  </label>
</template>

<script lang="ts">
import { defineComponent, computed, PropType } from 'vue';

export default defineComponent({
  name: 'VCheckbox',
  props: {
    modelValue: {
      type: Boolean,
      required: true,
    },
    label: {
      type: String,
      default: null,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    id: {
      type: String,
      default: () => `vcheckbox-${Math.random().toString(36).substring(2, 9)}`, // Auto-generate ID if not provided
    },
  },
  emits: ['update:modelValue'],
  setup(props, { emit }) {
    const labelClasses = computed(() => [
      'checkbox-label',
      { 'disabled': props.disabled },
    ]);

    const onChange = (event: Event) => {
      const target = event.target as HTMLInputElement;
      emit('update:modelValue', target.checked);
    };

    return {
      labelClasses,
      onChange,
    };
  },
});
</script>

<style lang="scss" scoped>
.checkbox-label {
  display: inline-flex; // Changed from block to inline-flex for better alignment with other form elements if needed
  align-items: center;
  cursor: pointer;
  position: relative;
  user-select: none; // Prevent text selection on click
  padding-left: 28px; // Space for the custom checkmark
  min-height: 20px; // Ensure consistent height, matches checkmark size + border
  font-size: 1rem; // Default font size, can be inherited or customized

  // Hide the default browser checkbox
  input[type="checkbox"] {
    position: absolute;
    opacity: 0;
    cursor: pointer;
    height: 0;
    width: 0;
  }

  // Custom checkmark
  .checkmark {
    position: absolute;
    top: 50%;
    left: 0;
    transform: translateY(-50%);
    height: 20px;
    width: 20px;
    background-color: #fff; // Default background
    border: 1px solid #adb5bd; // Default border (e.g., Gray-400)
    border-radius: 0.25rem; // Rounded corners
    transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out;

    // Checkmark symbol (hidden when not checked)
    &:after {
      content: "";
      position: absolute;
      display: none;
      left: 6px;
      top: 2px;
      width: 5px;
      height: 10px;
      border: solid white;
      border-width: 0 2px 2px 0;
      transform: rotate(45deg);
    }
  }

  // When checkbox is checked
  input[type="checkbox"]:checked ~ .checkmark {
    background-color: #007bff; // Checked background (e.g., Primary color)
    border-color: #007bff;
  }

  input[type="checkbox"]:checked ~ .checkmark:after {
    display: block; // Show checkmark symbol
  }

  // Focus state (accessibility) - style the custom checkmark
  input[type="checkbox"]:focus ~ .checkmark {
    box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); // Focus ring like Bootstrap
  }

  // Disabled state
  &.disabled {
    cursor: not-allowed;
    opacity: 0.7; // Dim the entire label including text

    input[type="checkbox"]:disabled ~ .checkmark {
      background-color: #e9ecef; // Disabled background (e.g., Gray-200)
      border-color: #ced4da; // Disabled border (e.g., Gray-300)
    }

    input[type="checkbox"]:disabled:checked ~ .checkmark {
      background-color: #7badec; // Lighter primary for disabled checked state
      border-color: #7badec;
    }
  }

  .checkbox-text-label {
    margin-left: 0.5rem; // Space between checkmark and text label (if checkmark is not absolute or padding-left on root is used)
                         // With absolute checkmark and padding-left on root, this might not be needed or adjusted.
                         // Given current setup (padding-left: 28px on root), this provides additional space if label text is present.
                         // If checkmark was part of the flex flow, this would be more critical.
                         // Let's adjust to ensure it's always to the right of the 28px padded area.
    vertical-align: middle; // Align text with the (conceptual) middle of the checkmark
  }
}
</style>
