<template>
  <div class="eli-data-hora">
    <v-text-field
      v-model="valor"
      :type="tipoInput"
      :label="opcoesEfetivas.rotulo"
      :placeholder="opcoesEfetivas.placeholder"
      :disabled="desabilitadoEfetivo"
      :clearable="Boolean(opcoesEfetivas.limpavel)"
      :error="Boolean(opcoesEfetivas.erro)"
      :error-messages="opcoesEfetivas.mensagensErro"
      :hint="opcoesEfetivas.dica"
      :persistent-hint="Boolean(opcoesEfetivas.dicaPersistente)"
      :density="opcoesEfetivas.densidade ?? 'comfortable'"
      :variant="opcoesEfetivas.variante ?? 'outlined'"
      :min="minLocal"
      :max="maxLocal"
      v-bind="attrs"
      @focus="emitCompatFocus"
      @blur="emitCompatBlur"
    />
  </div>
</template>

<script lang="ts">
import { computed, defineComponent, PropType } from "vue";
import dayjs from "dayjs";
import type { CampoDensidade, CampoVariante } from "../../tipos";
import type { PadroesEntradas } from "./tiposEntradas";

type EntradaDataHora = PadroesEntradas["dataHora"];

type PropsAntigas = {
  modo?: "data" | "dataHora";
  rotulo?: string;
  placeholder?: string;
  desabilitado?: boolean;
  limpavel?: boolean;
  erro?: boolean;
  mensagensErro?: string | string[];
  dica?: string;
  dicaPersistente?: boolean;
  densidade?: CampoDensidade;
  variante?: CampoVariante;
  min?: string;
  max?: string;
};

export default defineComponent({
  name: "EliEntradaDataHora",
  inheritAttrs: false,
  props: {
    // --- Novo padrão EliEntrada ---
    value: {
      type: String as PropType<EntradaDataHora["value"]>,
      default: undefined,
    },
    opcoes: {
      type: Object as PropType<EntradaDataHora["opcoes"]>,
      required: false,
      default: undefined,
    },

    // --- Compatibilidade com componente antigo EliDataHora ---
    modelValue: {
      type: String as PropType<string | null>,
      default: null,
    },
    modo: { type: String as PropType<PropsAntigas["modo"]>, default: undefined },
    rotulo: { type: String, default: undefined },
    placeholder: { type: String, default: undefined },
    desabilitado: { type: Boolean, default: undefined },
    limpavel: { type: Boolean, default: undefined },
    erro: { type: Boolean, default: undefined },
    mensagensErro: {
      type: [String, Array] as PropType<string | string[]>,
      default: undefined,
    },
    dica: { type: String, default: undefined },
    dicaPersistente: { type: Boolean, default: undefined },
    densidade: { type: String as PropType<CampoDensidade>, default: undefined },
    variante: { type: String as PropType<CampoVariante>, default: undefined },
    min: { type: String as PropType<string | undefined>, default: undefined },
    max: { type: String as PropType<string | undefined>, default: undefined },
  },
  emits: {
    // Novo padrão
    "update:value": (_v: string | null) => true,
    input: (_v: string | null) => true, // compat Vue2
    change: (_v: string | null) => true,

    // Compat antigo
    "update:modelValue": (_v: string | null) => true,
    alterar: (_v: string | null) => true,
    foco: () => true,
    desfoco: () => true,
    focus: () => true,
    blur: () => true,
  },
  setup(props, { emit, attrs }) {
    const opcoesEfetivas = computed<EntradaDataHora["opcoes"]>(() => {
      // 1) se veio `opcoes` (novo), usa
      if (props.opcoes) return props.opcoes;

      // 2) fallback: constrói a partir das props antigas
      return {
        rotulo: props.rotulo ?? "Data e hora",
        placeholder: props.placeholder ?? "",
        modo: props.modo ?? "dataHora",
        limpavel: props.limpavel,
        erro: props.erro,
        mensagensErro: props.mensagensErro,
        dica: props.dica,
        dicaPersistente: props.dicaPersistente,
        densidade: props.densidade,
        variante: props.variante,
        min: props.min,
        max: props.max,
      };
    });

    const modoEfetivo = computed<"data" | "dataHora">(
      () => opcoesEfetivas.value.modo ?? "dataHora"
    );

    const desabilitadoEfetivo = computed<boolean>(() => Boolean(props.desabilitado));

    const tipoInput = computed<"date" | "datetime-local">(() =>
      modoEfetivo.value === "data" ? "date" : "datetime-local"
    );

    function isoParaInputDatetime(valorIso: string): string {
      if (modoEfetivo.value === "data") {
        return dayjs(valorIso).format("YYYY-MM-DD");
      }
      return dayjs(valorIso).format("YYYY-MM-DDTHH:mm");
    }

    function inputDatetimeParaIsoLocal(valorInput: string): string {
      if (modoEfetivo.value === "data") {
        return dayjs(`${valorInput}T00:00`).format();
      }
      return dayjs(valorInput).format();
    }

    const effectiveModelValue = computed<string | null>(() => {
      // Prioridade: value (novo) se vier definido; senão usa modelValue (antigo)
      return props.value !== undefined ? (props.value ?? null) : props.modelValue;
    });

    const valor = computed<string>({
      get: () => {
        if (!effectiveModelValue.value) return "";
        return isoParaInputDatetime(effectiveModelValue.value);
      },
      set: (v) => {
        const normalizado = v && v.length > 0 ? v : null;
        if (!normalizado) {
          emit("update:value", null);
          emit("input", null);
          emit("change", null);

          emit("update:modelValue", null);
          emit("alterar", null);
          return;
        }

        const valorEmitido = inputDatetimeParaIsoLocal(normalizado);

        emit("update:value", valorEmitido);
        emit("input", valorEmitido);
        emit("change", valorEmitido);

        emit("update:modelValue", valorEmitido);
        emit("alterar", valorEmitido);
      },
    });

    const minLocal = computed<string | undefined>(() => {
      const min = opcoesEfetivas.value.min;
      if (!min) return undefined;
      return isoParaInputDatetime(min);
    });

    const maxLocal = computed<string | undefined>(() => {
      const max = opcoesEfetivas.value.max;
      if (!max) return undefined;
      return isoParaInputDatetime(max);
    });

    function emitCompatFocus() {
      emit("foco");
      emit("focus");
    }

    function emitCompatBlur() {
      emit("desfoco");
      emit("blur");
    }

    return {
      attrs,
      valor,
      tipoInput,
      minLocal,
      maxLocal,
      opcoesEfetivas,
      desabilitadoEfetivo,
      emitCompatFocus,
      emitCompatBlur,
    };
  },
});
</script>

<style>
.eli-data-hora {
  width: 100%;
}
</style>
