<script setup lang="ts">
import { ref, watch } from "vue";
import { useForm, useHttp, usePage } from "@inertiajs/vue3";
import QRCode from "qrcode";
import { ShieldCheck, ShieldOff } from "lucide-vue-next";
import Alert from "../ui/Alert.vue";
import AlertDescription from "../ui/AlertDescription.vue";
import AlertTitle from "../ui/AlertTitle.vue";
import Button from "../ui/Button.vue";
import Card from "../ui/Card.vue";
import CardContent from "../ui/CardContent.vue";
import CardDescription from "../ui/CardDescription.vue";
import CardFooter from "../ui/CardFooter.vue";
import CardHeader from "../ui/CardHeader.vue";
import CardTitle from "../ui/CardTitle.vue";
import Dialog from "../ui/Dialog.vue";
import DialogContent from "../ui/DialogContent.vue";
import DialogDescription from "../ui/DialogDescription.vue";
import DialogFooter from "../ui/DialogFooter.vue";
import DialogHeader from "../ui/DialogHeader.vue";
import DialogTitle from "../ui/DialogTitle.vue";
import FormItem from "../ui/FormItem.vue";
import FormLabel from "../ui/FormLabel.vue";
import FormMessage from "../ui/FormMessage.vue";
import InputOtp from "../ui/InputOtp.vue";
import InputOtpGroup from "../ui/InputOtpGroup.vue";
import InputOtpSlot from "../ui/InputOtpSlot.vue";
import type { FieldDefinition } from "./types";
import { useTranslations } from "../../composables/useTranslations";
import { useBuilderPrefix } from "../../composables/useBuilderPrefix";

const { t } = useTranslations();

defineProps<{
  field: FieldDefinition;
  modelValue: unknown;
  error?: string;
}>();

defineEmits<{ "update:modelValue": [value: unknown] }>();

const page = usePage<{
  mfaEnabled: boolean;
  recoveryCodes: string[] | null;
}>();

const prefix = useBuilderPrefix();

const setupOpen = ref(false);
const qrCodeDataUrl = ref("");
const secretKey = ref("");
const setupStep = ref<"qr" | "confirm">("qr");

const confirmForm = useForm({ code: "" });
const recoveryCodesForm = useForm({});
const mfaSetupHttp = useHttp({});

// PinInputRoot expects string[], confirmForm.code is a string — use a bridge ref
const otpCode = ref<string[]>([]);
watch(otpCode, (v) => {
  confirmForm.code = v.join("");
});

// Reset dialog state whenever it closes (regardless of how it was closed)
watch(setupOpen, (isOpen) => {
  if (!isOpen) {
    confirmForm.reset();
    setupStep.value = "qr";
    otpCode.value = [];
  }
});

function startSetup() {
  mfaSetupHttp.post(`/${prefix}/account/mfa/enable`, {
    onSuccess: async (response: { secret: string; qr_code_url: string }) => {
      secretKey.value = response.secret;
      qrCodeDataUrl.value = await QRCode.toDataURL(response.qr_code_url);
      setupStep.value = "qr";
      setupOpen.value = true;
    },
  });
}

function confirmMfa() {
  confirmForm.post(`/${prefix}/account/mfa/confirm`, {
    onSuccess: () => {
      setupOpen.value = false;
      confirmForm.reset();
    },
  });
}

function cancelSetup() {
  setupOpen.value = false;
  // watch(setupOpen) handles form reset
}

function regenerateCodes() {
  recoveryCodesForm.post(`/${prefix}/account/mfa/recovery-codes`);
}
</script>

<template>
  <div class="space-y-4">
    <!-- MFA status card -->
    <Card>
      <CardHeader>
        <div class="flex items-center gap-2">
          <ShieldCheck
            v-if="page.props.mfaEnabled"
            class="h-5 w-5 text-green-600"
          />
          <ShieldOff v-else class="h-5 w-5 text-destructive" />
          <CardTitle>{{ t("builder.mfa.title") }}</CardTitle>
        </div>
        <CardDescription>
          <template v-if="page.props.mfaEnabled">
            {{ t("builder.mfa.enabled") }}
          </template>
          <template v-else>
            {{ t("builder.mfa.setup_description") }}
          </template>
        </CardDescription>
      </CardHeader>

      <CardContent v-if="!page.props.mfaEnabled">
        <Alert variant="destructive">
          <ShieldOff class="h-4 w-4" />
          <AlertTitle>{{ t("builder.mfa.required_title") }}</AlertTitle>
          <AlertDescription>
            {{ t("builder.mfa.setup_required") }}
          </AlertDescription>
        </Alert>
      </CardContent>

      <CardFooter>
        <Button v-if="!page.props.mfaEnabled" @click="startSetup">
          {{ t("builder.mfa.enable") }}
        </Button>
        <Button
          v-else
          variant="outline"
          :disabled="recoveryCodesForm.processing"
          @click="regenerateCodes"
        >
          {{ t("builder.mfa.regenerate_codes") }}
        </Button>
      </CardFooter>
    </Card>

    <!-- Recovery codes -->
    <Card v-if="page.props.recoveryCodes">
      <CardHeader>
        <CardTitle>{{ t("builder.mfa.recovery_codes") }}</CardTitle>
        <CardDescription>
          {{ t("builder.mfa.recovery_codes_description") }}
        </CardDescription>
      </CardHeader>
      <CardContent>
        <div class="grid grid-cols-2 gap-2 font-mono text-sm">
          <div
            v-for="code in page.props.recoveryCodes"
            :key="code"
            class="rounded bg-muted px-3 py-1.5 text-center"
          >
            {{ code }}
          </div>
        </div>
      </CardContent>
    </Card>
  </div>

  <!-- MFA setup dialog -->
  <Dialog v-model:open="setupOpen">
    <DialogContent class="sm:max-w-md">
      <DialogHeader>
        <DialogTitle>{{ t("builder.mfa.setup_title") }}</DialogTitle>
        <DialogDescription>
          <template v-if="setupStep === 'qr'">
            {{ t("builder.mfa.scan_qr") }}
          </template>
          <template v-else>
            {{ t("builder.mfa.enter_code") }}
          </template>
        </DialogDescription>
      </DialogHeader>

      <!-- QR code step -->
      <div v-if="setupStep === 'qr'" class="space-y-4">
        <div class="flex justify-center">
          <img
            v-if="qrCodeDataUrl"
            :src="qrCodeDataUrl"
            alt="QR code for MFA setup"
            class="h-48 w-48 rounded border"
          />
        </div>
        <p class="text-center text-xs text-muted-foreground">
          {{ t("builder.mfa.cant_scan") }}
          <span class="block font-mono font-medium text-foreground">
            {{ secretKey }}
          </span>
        </p>
        <DialogFooter>
          <Button variant="ghost" type="button" @click="cancelSetup">
            {{ t("builder.mfa.cancel") }}
          </Button>
          <Button type="button" @click="setupStep = 'confirm'">
            {{ t("builder.mfa.continue") }}
          </Button>
        </DialogFooter>
      </div>

      <!-- Confirm code step -->
      <div v-else class="space-y-4">
        <form @submit.prevent="confirmMfa">
          <FormItem>
            <FormLabel :error="!!confirmForm.errors.code">
              {{ t("builder.mfa.auth_code") }}
            </FormLabel>
            <InputOtp v-model="otpCode" :length="6">
              <InputOtpGroup>
                <InputOtpSlot v-for="i in 6" :key="i" :index="i - 1" />
              </InputOtpGroup>
            </InputOtp>
            <FormMessage :message="confirmForm.errors.code" />
          </FormItem>

          <DialogFooter class="mt-4">
            <Button type="button" variant="outline" @click="setupStep = 'qr'">
              {{ t("builder.mfa.back") }}
            </Button>
            <Button type="submit" :disabled="confirmForm.processing">
              {{ t("builder.mfa.enable") }}
            </Button>
          </DialogFooter>
        </form>
      </div>
    </DialogContent>
  </Dialog>
</template>
