<script setup lang="ts">
import Button from '@/components/ui/button/Button.vue';
import Checkbox from '@/components/ui/checkbox/Checkbox.vue';
import { useForm, Field as VeeField } from 'vee-validate';
import {
  Field,
  FieldContent,
  FieldDescription,
  FieldGroup,
  FieldLabel,
} from '@/components/ui/field'
import FieldError from '@/components/ui/field/FieldError.vue';
import Input from '@/components/ui/input/Input.vue';
import Textarea from '@/components/ui/textarea/Textarea.vue';
import { toTypedSchema } from '@vee-validate/zod';
import { nextTick, onMounted, ref, watch } from 'vue';
import * as z from 'zod';
import DateInput from '../form/DateInput.vue';
import { ApplicationData } from '@shared/types/application';
import Dialog from '../ui/dialog/Dialog.vue';
import DialogTrigger from '../ui/dialog/DialogTrigger.vue';
import DialogContent from '../ui/dialog/DialogContent.vue';
import DialogHeader from '../ui/dialog/DialogHeader.vue';
import DialogTitle from '../ui/dialog/DialogTitle.vue';
import DialogDescription from '../ui/dialog/DialogDescription.vue';
import { getCoC } from '@/api/application';
import { startBrowserTracingPageLoadSpan } from '@sentry/vue';

const regexA = /^https?:\/\/steamcommunity\.com\/id\/[A-Za-z0-9_]+\/?$/;
const regexB = /^https?:\/\/steamcommunity\.com\/profiles\/\d+\/?$/;


const formSchema = toTypedSchema(z.object({
  dob: z.string().refine(v => v, { message: "A date of birth is required." }),
  name: z.string().nonempty(),
  playtime: z.preprocess((v) => (v === "" ? undefined : String(v)), z.string({ required_error: "Required" }).regex(/^\d+(\.\d+)?$/, "Must be a number").transform(Number).refine((n) => n >= 0, "Cannot be less than 0")),
  hobbies: z.string().nonempty(),
  military: z.boolean(),
  communities: z.string().nonempty(),
  joinReason: z.string().nonempty(),
  milsimAttraction: z.string().nonempty(),
  referral: z.string().nonempty(),
  steamProfile: z.string().nonempty().refine((val) => regexA.test(val) || regexB.test(val), { message: "Invalid Steam profile URL." }),
  timezone: z.string().nonempty(),
  canAttendSaturday: z.boolean(),
  interests: z.string().nonempty(),
  acknowledgeRules: z.literal(true, {
    errorMap: () => ({ message: "Required" })
  }),
}))


const fallbackInitials = {
  military: false,
  canAttendSaturday: false,
  acknowledgeRules: false,
}

const props = defineProps<{
  readOnly: boolean,
  data: ApplicationData | null,
}>()

const emit = defineEmits(['submit']);

const initialValues = ref<Record<string, unknown> | null>(null);

const { handleSubmit, resetForm, values } = useForm({
  validationSchema: formSchema,
  validateOnMount: false,
});

const submitForm = handleSubmit(async (val) => {
  await onSubmit(val);
});

async function onSubmit(val: any) {
  emit('submit', val);
}

onMounted(async () => {
  if (props.data !== null) {
    const parsed = typeof props.data === "string"
      ? JSON.parse(props.data)
      : props.data;

    initialValues.value = { ...parsed };
  } else {
    initialValues.value = { ...fallbackInitials };
  }

  // apply the initial values to the vee-validate form
  resetForm({ values: initialValues.value });

  // CoCbox.value.innerHTML = await getCoC()
  CoCString.value = await getCoC();
})

const showCoC = ref(false);
const CoCbox = ref<HTMLElement>();
const CoCString = ref<string>();

async function onDialogToggle(state: boolean) {
  showCoC.value = state;
}

function enforceExternalLinks() {
  if (!CoCbox.value) return;

  const links = CoCbox.value.querySelectorAll("a");
  links.forEach(a => {
    a.setAttribute("target", "_blank");
    a.setAttribute("rel", "noopener noreferrer");
  });
}

watch(() => showCoC.value, async () => {
  if (showCoC.value) {
    await nextTick(); // wait for v-html to update
    enforceExternalLinks();
  }
});

function convertToAge(dob: string) {

  if (dob === undefined) return "";
  const [month, day, year] = dob.split('/').map(Number);

  let dobDate = new Date(year, month - 1, day);

  let out = Math.floor(
    (Date.now() - dobDate.getTime()) / (1000 * 60 * 60 * 24 * 365.2425)
  );

  return Number.isNaN(out) ? "" : out;
}

</script>

<template>
  <form v-if="initialValues" @submit.prevent="submitForm" class="space-y-6">
    <!-- Age -->
    <VeeField name="dob" v-slot="{ field, errors }">
      <Field>
        <FieldLabel>What is your date of birth?</FieldLabel>
        <FieldContent>
          <div class="flex items-center gap-10">
            <DateInput :model-value="(field.value as string) ?? ''" :disabled="readOnly" @update:model-value="field.onChange" />
            <p v-if="props.readOnly" class="text-muted-foreground">Age: {{ convertToAge(field.value) }}</p>
          </div>
        </FieldContent>
        <div class="h-4">
          <FieldError v-if="errors.length" :errors="errors" />
        </div>
      </Field>
    </VeeField>

    <!-- Name -->
    <VeeField name="name" v-slot="{ field, errors }">
      <Field>
        <FieldLabel>What name will you be going by within the community?</FieldLabel>
        <FieldDescription>This name must be consistent across platforms.</FieldDescription>
        <FieldContent>
          <Input :model-value="field.value" @update:model-value="field.onChange" :disabled="readOnly" />
        </FieldContent>
        <div class="h-4">
          <FieldError v-if="errors.length" :errors="errors" />
        </div>
      </Field>
    </VeeField>

    <!-- Playtime -->
    <VeeField name="playtime" v-slot="{ field, errors }">
      <Field>
        <FieldLabel>How long have you played Arma 3 for (in hours)?</FieldLabel>
        <FieldContent>
          <Input type="number" :model-value="field.value" @update:model-value="field.onChange" :disabled="readOnly" />
        </FieldContent>
        <div class="h-4">
          <FieldError v-if="errors.length" :errors="errors" />
        </div>
      </Field>
    </VeeField>

    <!-- Hobbies -->
    <VeeField name="hobbies" v-slot="{ field, errors }">
      <Field>
        <FieldLabel>What hobbies do you like to participate in outside of gaming?</FieldLabel>
        <FieldContent>
          <Textarea rows="4" class="resize-none" :model-value="field.value" @update:model-value="field.onChange"
            :disabled="readOnly" />
        </FieldContent>
        <div class="h-4">
          <FieldError v-if="errors.length" :errors="errors" />
        </div>
      </Field>
    </VeeField>

    <!-- Military (boolean) -->
    <VeeField name="military" v-slot="{ field, errors }">
      <Field>
        <FieldLabel>Have you ever served in the military?</FieldLabel>
        <FieldContent>
          <div class="flex items-center gap-2">
            <Checkbox :model-value="field.value" @update:model-value="field.onChange" :disabled="readOnly" />
            <span>Yes (checked) / No (unchecked)</span>
          </div>
        </FieldContent>
        <div class="h-4">
          <FieldError v-if="errors.length" :errors="errors" />
        </div>
      </Field>
    </VeeField>

    <!-- Other communities (freeform) -->
    <VeeField name="communities" v-slot="{ field, errors }">
      <Field>
        <FieldLabel>Are you a part of any other communities? If so, which ones? If none, type "No"</FieldLabel>
        <FieldContent>
          <Input :model-value="field.value" @update:model-value="field.onChange" :disabled="readOnly" />
        </FieldContent>
        <div class="h-4">
          <FieldError v-if="errors.length" :errors="errors" />
        </div>
      </Field>
    </VeeField>

    <!-- Why join -->
    <VeeField name="joinReason" v-slot="{ field, errors }">
      <Field>
        <FieldLabel>Why do you want to join our community?</FieldLabel>
        <FieldContent>
          <Textarea rows="4" class="resize-none" :model-value="field.value" @update:model-value="field.onChange"
            :disabled="readOnly" />
        </FieldContent>
        <div class="h-4">
          <FieldError v-if="errors.length" :errors="errors" />
        </div>
      </Field>
    </VeeField>

    <!-- Attraction to milsim -->
    <VeeField name="milsimAttraction" v-slot="{ field, errors }">
      <Field>
        <FieldLabel>What attracts you to the Arma 3 milsim playstyle?</FieldLabel>
        <FieldContent>
          <Textarea rows="4" class="resize-none" :model-value="field.value" @update:model-value="field.onChange"
            :disabled="readOnly" />
        </FieldContent>
        <div class="h-4">
          <FieldError v-if="errors.length" :errors="errors" />
        </div>
      </Field>
    </VeeField>

    <!-- Referral (freeform) -->
    <VeeField name="referral" v-slot="{ field, errors }">
      <Field>
        <FieldLabel>Where did you hear about us? (If another member, who?)</FieldLabel>
        <FieldContent>
          <Input placeholder="e.g., Reddit / Member: Alice" :model-value="field.value" @update:model-value="field.onChange"
            :disabled="readOnly" />
        </FieldContent>
        <div class="h-4">
          <FieldError v-if="errors.length" :errors="errors" />
        </div>
      </Field>
    </VeeField>

    <!-- Steam profile -->
    <VeeField name="steamProfile" v-slot="{ field, errors }">
      <Field>
        <FieldLabel>Steam profile link</FieldLabel>
        <FieldDescription>
          Format: <code>https://steamcommunity.com/id/USER/</code> or
          <code>https://steamcommunity.com/profiles/STEAMID64/</code>
        </FieldDescription>
        <FieldContent>
          <Input type="url" placeholder="https://steamcommunity.com/profiles/7656119..." :model-value="field.value"
            @update:model-value="field.onChange" :disabled="readOnly" />
        </FieldContent>
        <div class="h-4">
          <FieldError v-if="errors.length" :errors="errors" />
        </div>
      </Field>
    </VeeField>

    <!-- Timezone -->
    <VeeField name="timezone" v-slot="{ field, errors }">
      <Field>
        <FieldLabel>What time zone are you in?</FieldLabel>
        <FieldContent>
          <Input placeholder="e.g., AEST, EST, UTC+10" :model-value="field.value" @update:model-value="field.onChange"
            :disabled="readOnly" />
        </FieldContent>
        <div class="h-4">
          <FieldError v-if="errors.length" :errors="errors" />
        </div>
      </Field>
    </VeeField>

    <!-- Attendance (boolean) -->
    <VeeField name="canAttendSaturday" v-slot="{ field, errors }">
      <Field>
        <FieldLabel>Are you able to attend weekly operations Saturdays @ 7pm CST?</FieldLabel>
        <FieldContent>
          <div class="flex items-center gap-2">
            <Checkbox :model-value="field.value ?? false" @update:model-value="field.onChange" :disabled="readOnly" />
            <span>Yes (checked) / No (unchecked)</span>
          </div>
        </FieldContent>
        <div class="h-4">
          <FieldError v-if="errors.length" :errors="errors" />
        </div>
      </Field>
    </VeeField>

    <!-- Interests / Playstyle (freeform) -->
    <VeeField name="interests" v-slot="{ field, errors }">
      <Field>
        <FieldLabel>Which playstyles interest you?</FieldLabel>
        <FieldContent>
          <Input placeholder="e.g., Rifleman; Medic; Pilot" :model-value="field.value" @update:model-value="field.onChange"
            :disabled="readOnly" />
        </FieldContent>
        <div class="h-4">
          <FieldError v-if="errors.length" :errors="errors" />
        </div>
      </Field>
    </VeeField>

    <!-- Code of Conduct (boolean, field name kept as-is) -->
    <VeeField name="acknowledgeRules" v-slot="{ field, errors }">
      <Field>
        <FieldLabel>Community Code of Conduct</FieldLabel>
        <FieldContent>
          <div class="flex items-center gap-2">
            <Checkbox :model-value="field.value" @update:model-value="field.onChange" :disabled="readOnly" />
            <span>By checking this box, you accept the <Button variant="link" class="p-0 h-min"
                @click.prevent.stop="showCoC = true">Code of
                Conduct</Button>.</span>
          </div>
        </FieldContent>
        <div class="h-4">
          <FieldError v-if="errors.length" :errors="errors" />
        </div>
      </Field>
    </VeeField>

    <div class="pt-2" v-if="!readOnly">
      <Button type="submit" :disabled="readOnly">Submit Application</Button>
    </div>

    <Dialog :open="showCoC" @update:open="onDialogToggle">
      <DialogContent class="sm:max-w-fit">
        <DialogHeader>
          <DialogTitle>Community Code of Conduct</DialogTitle>
          <DialogDescription class="w-full max-h-[75vh] overflow-y-auto scrollbar-themed">
            <div v-html="CoCString" ref="CoCbox" class="bookstack-container w-full"></div>
          </DialogDescription>
        </DialogHeader>
      </DialogContent>
    </Dialog>

  </form>
</template>