<template>
  <switch 
    v-if="native" 
    :checked="value"
    :disabled="disabled"
    @change="(e: any) => change(e.detail.value)"
  />
  <view v-else 
    class="nana-switch"
    :style="{
      ...themeStyles.toggleOut,
      ...style,
    }"
    @click="change()"
  >
    <view class="outView" :style="{
      transitionDuration: `${animDuration}ms`,
      backgroundColor: themeContext.resolveThemeColor(value ? color : inverseColor),
      opacity: disabled ? 0.6 : 1,
      ...style,
    }">
      <view
        class="dot"
        :style="{
          width: size,
          height: size,
          transform: `translateX(${translateX})`,
          transitionDuration: `${animDuration}ms`,
        }"
      >
        <view class="dotInner" :style="{
          backgroundColor: themeContext.resolveThemeColor(dotColor),
          borderRadius: themeContext.resolveSize(size / 2),
          marginTop: themeContext.resolveSize(dotPadding),
          marginLeft: themeContext.resolveSize(dotPadding),
          width: themeContext.resolveSize(size - dotPadding * 2),
          height: themeContext.resolveSize(size - dotPadding * 2),
          transitionDuration: `${animDuration}ms`,
          ...themeStyles.toggleDotInner.value,
        }">
          <ActivityIndicator
            v-if="loading" 
            :size="Math.max(size * 0.6  - 2, 10)"
            :color="themeContext.resolveThemeColor(value ? color : inverseColor)" 
          />
        </view>
      </view>
    </view>
  </view>
</template>

<script setup lang="ts">
import { computed, toRef } from 'vue';
import ActivityIndicator from '../basic/ActivityIndicator.vue';
import { propGetThemeVar, useTheme, type ViewStyle } from '../theme/ThemeDefine';
import { DynamicVar } from '../theme/ThemeTools';
import { useFieldChildValueInjector } from './FormContext';
import Feedback from '../utils/Feedback';

export interface SwitchProps {
  /**
   * 开关是否开启
   * @default false
   */
  modelValue?: boolean;
  /**
   * 是否使用原生 Switch 组件
   * @default false
   */
  native?: boolean;
  /**
   * 开关的主颜色
   * @default primary
   */
  color?: string;
  /**
   * 开关的反色
   * @default switch
   */
  inverseColor?: string;
  /**
   * 开关点的颜色
   * @default lightButton
   */
  dotColor?: string;
  /**
   * 开关是否是加载中状态
   * @default false
   */
  loading?: boolean;
  /**
   * 开关是否禁用
   * @default false
   */
  disabled?: boolean;
  /**
   * 是否有触感反馈
   * @platform iOS
   * @default true
   */
  impactFeedback?: boolean;
  /**
   * 开关大小
   * @default 60
   */
  size?: number;
}

const emit = defineEmits([ 'update:modelValue' ])

const props = withDefaults(defineProps<SwitchProps>(), {
  modelValue: false,
  native: false,
  color: () => propGetThemeVar('SwitchColor', 'primary'),
  inverseColor: () => propGetThemeVar('SwitchInverseColor', 'background.switch'),
  dotColor: () => propGetThemeVar('SwitchDotColor', 'lightButton'),
  loading: false,
  disabled: false,
  impactFeedback: () => propGetThemeVar('SwitchImpactFeedback', true),
  size: () => propGetThemeVar('SwitchSize', 60),
});

const themeContext = useTheme();

const style = computed(() => ({
  width: themeContext.resolveSize(props.size * 1.8),
  height: themeContext.resolveSize(props.size),
  borderRadius: themeContext.resolveSize(props.size / 2),
} as ViewStyle))

const dotPadding = computed(() => themeContext.getVar('SwitchDotPadding', 4));
const themeStyles = themeContext.useThemeStyles({
  toggleDotInner: {
    boxShadow: DynamicVar('SwitchDotShadow', 'rgba(0, 0, 0, 0.1) 2px 2px 8px 2px'),
  },
});

const {
  value,
  updateValue,
  context,
} = useFieldChildValueInjector(
  toRef(props, 'modelValue'), 
  (v) => emit('update:modelValue', v)
);

const animDuration = computed(() => themeContext.getVar('SwitchAnimDuration', 200));
const translateX = computed(() => value.value ? themeContext.resolveSize((props.size * 1.8) - props.size) : 0);

function change(_value?: boolean) {
  if (_value === undefined)
    _value = !value.value;
  if (props.disabled === true || props.loading)
    return;
  if (props.impactFeedback)
    Feedback.impactSelectionFeedbackGenerator();
  updateValue(_value);
}

defineOptions({
  options: {
    styleIsolation: "shared",
    virtualHost: true,
  }
})
</script>

<style lang="scss">
.nana-switch {
  display: flex;
  position: relative;
  overflow: hidden;

  .outView {
    display: flex;
    position: relative;
    overflow: hidden;
  }
  .dot {
    display: flex;
    position: absolute;
    z-index: 10,
  }
  .dotInner, .dot {
    display: flex;
    justify-content: center;
    align-items: center;
  }
  .dotInner, .dot, .outView {
    transition: all ease-in-out 0.3s;
  }
}


</style>