<template>
  <v-dialog v-model="showDialog" max-width="600" persistent>
    <v-card>
      <v-toolbar>
        <v-row no-gutters class="fill-height px-6" align="center">
          <span class="font-weight-bold text-h6">Attendance Settings</span>
        </v-row>
      </v-toolbar>

      <v-card-text class="pa-6">
        <v-alert
          v-if="error"
          type="error"
          variant="tonal"
          density="compact"
          closable
          class="mb-4"
          @click:close="error = ''"
        >
          {{ error }}
        </v-alert>

        <v-form ref="formRef" v-model="valid" @submit.prevent="onSubmit">
          <v-row dense>
            <v-col cols="12">
              <v-checkbox
                v-model="isGeofencingEnabled"
                label="Enable Geofencing"
                density="comfortable"
                hide-details
              />
              <span
                v-if="isGeofencingEnabled"
                class="text-body-2 text-medium-emphasis"
              >
                Enabling this setting will require users to take attendance
                within a certain radius via QR code or within the site location.
              </span>
            </v-col>

            <template v-if="isGeofencingEnabled">
              <v-col cols="12" class="mt-4">
                <v-checkbox
                  v-model="isQrEnabled"
                  label="Enable QR Code"
                  density="comfortable"
                  hide-details
                />
              </v-col>

              <v-col v-if="isQrEnabled" cols="12">
                <v-card
                  variant="flat"
                  class="pa-4 d-flex flex-column align-center"
                >
                  <QrcodeVue
                    :value="site"
                    :level="'M'"
                    :render-as="'svg'"
                    :size="300"
                  />
                  <v-btn
                    variant="text"
                    color="primary"
                    class="mt-2"
                    @click="downloadQrCode"
                  >
                    <v-icon class="mr-2">mdi-download</v-icon>
                    Download QR Code
                  </v-btn>
                </v-card>
              </v-col>

              <v-col cols="12" class="mt-4">
                <InputLabel title="Site Location" />
                <v-btn
                  variant="outlined"
                  class="mt-2"
                  @click="isMapSearchVisible = true"
                >
                  <v-icon class="mr-2">mdi-map-search</v-icon>
                  Search Location
                </v-btn>
              </v-col>

              <v-col v-if="geolocation" cols="12">
                <LMap
                  :key="`map-${geolocation.latitude}-${geolocation.longitude}`"
                  style="height: 350px; border-radius: 8px"
                  :zoom="15"
                  :center="[geolocation.latitude, geolocation.longitude]"
                  :use-global-leaflet="false"
                >
                  <LTileLayer
                    url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
                    attribution='&copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors'
                  />
                  <LMarker
                    :lat-lng="[geolocation.latitude, geolocation.longitude]"
                    :draggable="true"
                    @update:lat-lng="onMarkerUpdate"
                  />
                  <LCircle
                    v-if="radius"
                    :lat-lng="[geolocation.latitude, geolocation.longitude]"
                    :radius="radiusInMeters"
                    :color="'#1867C0'"
                    :fill-color="'#1867C0'"
                    :fill-opacity="0.2"
                  />
                </LMap>
              </v-col>

              <v-col cols="12" class="mt-2">
                <InputLabel title="Radius (miles)" />
                <v-text-field
                  v-model.number="radius"
                  type="number"
                  density="comfortable"
                  placeholder="Enter radius in miles"
                  :rules="[(v) => v > 0 || 'Radius must be greater than 0']"
                  hide-details="auto"
                />
              </v-col>
            </template>
          </v-row>
        </v-form>
      </v-card-text>

      <v-toolbar class="pa-0" density="compact">
        <v-row no-gutters>
          <v-col cols="6" class="pa-0">
            <v-btn
              block
              variant="text"
              class="text-none"
              size="large"
              @click="close"
              height="56"
              :disabled="submitting"
            >
              Cancel
            </v-btn>
          </v-col>
          <v-col cols="6" class="pa-0">
            <v-btn
              block
              variant="flat"
              color="black"
              class="text-none font-weight-bold rounded-0"
              height="56"
              size="large"
              :loading="submitting"
              @click="onSubmit"
            >
              <v-icon class="mr-2">mdi-check</v-icon>
              Update
            </v-btn>
          </v-col>
        </v-row>
      </v-toolbar>
    </v-card>
  </v-dialog>

  <AttendanceMapSearchDialog
    v-model="isMapSearchVisible"
    :initialPostalCode="postalCode"
    :initialCountry="country"
    :initialCity="city"
    :initialAddress="address"
    @location-selected="onLocationSelected"
  />

  <Snackbar v-model="snackbar" :text="snackbarText" :color="snackbarColor" />
</template>

<script setup lang="ts">
import QrcodeVue from "qrcode.vue";

const showDialog = defineModel({ type: Boolean, default: false });

const props = defineProps({
  site: { type: String, required: true },
  serviceType: { type: String, default: "" },
});

const emit = defineEmits(["saved", "close"]);

const formRef = ref<any>(null);
const valid = ref(false);
const submitting = ref(false);
const error = ref("");

const isGeofencingEnabled = ref(false);
const isQrEnabled = ref(false);
const geolocation = ref<{ latitude: number; longitude: number } | null>(null);
const radius = ref(0.5);
const isMapSearchVisible = ref(false);

const radiusInMeters = computed(() => radius.value * 1609.34);

const { getAttendanceSettings, updateAttendanceSettings } = useAttendance();

const postalCode = ref("");
const country = ref("");
const city = ref("");
const address = ref("");

const {
  data: getAttendanceSettingsReq,
  refresh: getAttendanceSettingsRefresh,
  pending: loading,
} = await useLazyAsyncData(
  `attendance-settings-${props.site}`,
  () => getAttendanceSettings(props.site, props.serviceType),
  {
    watch: [() => props.site, () => props.serviceType],
    immediate: false,
  }
);

watchEffect(() => {
  if (getAttendanceSettingsReq.value) {
    isGeofencingEnabled.value =
      getAttendanceSettingsReq.value.isGeofencingEnabled || false;

    if (getAttendanceSettingsReq.value.location) {
      geolocation.value = {
        latitude: getAttendanceSettingsReq.value.location.latitude,
        longitude: getAttendanceSettingsReq.value.location.longitude,
      };
    }

    if (getAttendanceSettingsReq.value.mile) {
      radius.value = getAttendanceSettingsReq.value.mile;
    }

    if (getAttendanceSettingsReq.value.postalCode) {
      postalCode.value = getAttendanceSettingsReq.value.postalCode;
    }

    if (getAttendanceSettingsReq.value.country) {
      country.value = getAttendanceSettingsReq.value.country;
    }

    if (getAttendanceSettingsReq.value.city) {
      city.value = getAttendanceSettingsReq.value.city;
    }

    if (getAttendanceSettingsReq.value.address) {
      address.value = getAttendanceSettingsReq.value.address;
    }
  }
});

onMounted(() => {
  if (navigator.geolocation && !geolocation.value) {
    navigator.geolocation.getCurrentPosition((position) => {
      if (!geolocation.value) {
        geolocation.value = {
          latitude: position.coords.latitude,
          longitude: position.coords.longitude,
        };
      }
    });
  }
});

const onMarkerUpdate = ({ lat, lng }: { lat: number; lng: number }) => {
  geolocation.value = { latitude: lat, longitude: lng };
};

const onLocationSelected = (payload: {
  latitude: number;
  longitude: number;
  address?: string;
  city?: string;
  country?: string;
  postalCode?: string;
}) => {
  geolocation.value = { latitude: payload.latitude, longitude: payload.longitude };
  if (payload.postalCode) postalCode.value = payload.postalCode;
  if (payload.country) country.value = payload.country;
  if (payload.city) city.value = payload.city;
  if (payload.address) address.value = payload.address;

  isMapSearchVisible.value = false;
};

const downloadQrCode = () => {
  const svg = document.querySelector("svg");
  if (!svg) return;

  const svgData = new XMLSerializer().serializeToString(svg);
  const canvas = document.createElement("canvas");
  const ctx = canvas.getContext("2d");
  const img = new Image();

  const padding = 40;

  img.onload = () => {
    canvas.width = img.width + padding * 2;
    canvas.height = img.height + padding * 2;

    if (ctx) {
      ctx.fillStyle = "#ffffff";
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      ctx.drawImage(img, padding, padding);

      const pngFile = canvas.toDataURL("image/png");
      const downloadLink = document.createElement("a");
      downloadLink.href = pngFile;
      downloadLink.download = `attendance-qr-${props.site}.png`;
      downloadLink.click();
    }
  };

  img.src =
    "data:image/svg+xml;base64," + btoa(unescape(encodeURIComponent(svgData)));
};

const snackbar = ref(false);
const snackbarText = ref("");
const snackbarColor = ref("success");

const showSnackbar = (text: string, color: string = "success") => {
  snackbarText.value = text;
  snackbarColor.value = color;
  snackbar.value = true;
};

const onSubmit = async () => {
  if (!formRef.value?.validate()) return;

  if (isGeofencingEnabled.value && !geolocation.value) {
    error.value = "Please set a location before enabling geofencing.";
    return;
  }

  submitting.value = true;
  error.value = "";

  try {
    const payload: any = {
      site: props.site,
      isLocationEnabled: isGeofencingEnabled.value,
    };

    if (isGeofencingEnabled.value) {
      payload.isGeofencingEnabled = true;

      if (geolocation.value) {
        payload.location = {
          latitude: geolocation.value.latitude,
          longitude: geolocation.value.longitude,
        };
      }
      if (postalCode.value) payload.postalCode = postalCode.value;
      if (country.value) payload.country = country.value;
      if (city.value) payload.city = city.value;
      if (address.value) payload.address = address.value;

      payload.mile = radius.value;
    } else {
      payload.isGeofencingEnabled = false;
    }

    await updateAttendanceSettings(props.site, payload, props.serviceType);
    await getAttendanceSettingsRefresh();

    showSnackbar("Settings updated successfully");

    emit("saved", payload);
    close();
  } catch (err: any) {
    console.error("Error saving attendance settings:", err);
    const errorMessage =
      err.statusMessage ||
      err.message ||
      "Failed to save settings. Please try again.";
    error.value = errorMessage;
    showSnackbar(errorMessage, "error");
  } finally {
    submitting.value = false;
  }
};

const close = () => {
  error.value = "";
  showDialog.value = false;
  emit("close");
};

watch(showDialog, (newVal) => {
  if (newVal) {
    getAttendanceSettingsRefresh();
  }
});
</script>
