<!-- QRScannerDialog.vue -->
<template>
  <div
    v-if="visible && !isNativePlatform"
    class="dialog-overlay z-[60] fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center"
  >
    <div
      class="dialog relative bg-white rounded-lg shadow-xl max-w-lg w-full mx-4"
    >
      <!-- Header -->
      <div class="p-4 border-b border-gray-200">
        <h3 class="text-lg font-medium text-gray-900">Scan QR Code</h3>
        <button
          class="absolute top-4 right-4 text-gray-400 hover:text-gray-500"
          aria-label="Close dialog"
          @click="close"
        >
          <svg
            class="h-6 w-6"
            fill="none"
            viewBox="0 0 24 24"
            stroke="currentColor"
          >
            <path
              stroke-linecap="round"
              stroke-linejoin="round"
              stroke-width="2"
              d="M6 18L18 6M6 6l12 12"
            />
          </svg>
        </button>
      </div>

      <!-- Scanner -->
      <div class="p-4">
        <div
          v-if="useQRReader && !isNativePlatform"
          class="relative aspect-square"
        >
          <!-- Status Message -->
          <div 
            class="absolute top-0 left-0 right-0 bg-black bg-opacity-50 text-white text-center py-2 z-10"
          >
            <p v-if="isInitializing">Initializing camera...</p>
            <p v-else-if="isScanning">Position QR code in the frame</p>
            <p v-else-if="error" class="text-red-300">{{ error }}</p>
            <p v-else>Ready to scan</p>
          </div>

          <qrcode-stream
            :camera="options?.camera === 'front' ? 'user' : 'environment'"
            @decode="onDecode"
            @init="onInit"
            @detect="onDetect"
            @error="onError"
          />
          
          <!-- Scanning Frame -->
          <div
            class="absolute inset-0 border-2"
            :class="{
              'border-blue-500': !error && !isScanning,
              'border-green-500 animate-pulse': isScanning,
              'border-red-500': error
            }"
            style="opacity: 0.5; pointer-events: none;"
          ></div>

          <!-- Camera Switch Button -->
          <button
            @click="toggleCamera"
            class="absolute bottom-4 right-4 bg-white rounded-full p-2 shadow-lg"
            title="Switch camera"
          >
            <svg
              class="h-6 w-6 text-gray-600"
              fill="none"
              viewBox="0 0 24 24"
              stroke="currentColor"
            >
              <path
                stroke-linecap="round"
                stroke-linejoin="round"
                stroke-width="2"
                d="M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z"
              />
              <path
                stroke-linecap="round"
                stroke-linejoin="round"
                stroke-width="2"
                d="M15 13a3 3 0 11-6 0 3 3 0 016 0z"
              />
            </svg>
          </button>
        </div>
        <div v-else class="text-center py-8">
          <p class="text-gray-500">
            {{
              isNativePlatform
                ? "Using native camera scanner..."
                : "QR code scanning is not supported in this browser."
            }}
          </p>
          <p v-if="!isNativePlatform" class="text-sm text-gray-400 mt-2">
            Please ensure you're using a modern browser with camera access.
          </p>
        </div>
      </div>

      <!-- Footer -->
      <div class="p-4 border-t border-gray-200">
        <div class="flex flex-col space-y-4">
          <!-- Instructions -->
          <div class="text-sm text-gray-600">
            <ul class="list-disc list-inside space-y-1">
              <li>Ensure the QR code is well-lit and in focus</li>
              <li>Hold your device steady</li>
              <li>The QR code should fit within the scanning frame</li>
            </ul>
          </div>

          <!-- Error Message -->
          <p v-if="error" class="text-red-500 text-sm">{{ error }}</p>

          <!-- Actions -->
          <div class="flex justify-end space-x-2">
            <button
              v-if="error"
              class="px-4 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-600"
              @click="retryScanning"
            >
              Retry
            </button>
            <button
              class="px-4 py-2 bg-gray-100 text-gray-700 rounded-md hover:bg-gray-200"
              @click="close"
            >
              Cancel
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue } from "vue-facing-decorator";
import { QrcodeStream } from "vue-qrcode-reader";
import { QRScannerOptions } from "@/services/QRScanner/types";
import { logger } from "@/utils/logger";
import { Capacitor } from "@capacitor/core";

interface ScanProps {
  onScan: (result: string) => void;
  onError?: (error: Error) => void;
  options?: QRScannerOptions;
}

@Component({
  components: {
    QrcodeStream,
  },
})
export default class QRScannerDialog extends Vue {
  @Prop({ type: Function, required: true }) onScan!: ScanProps["onScan"];
  @Prop({ type: Function }) onError?: ScanProps["onError"];
  @Prop({ type: Object }) options?: ScanProps["options"];

  visible = true;
  error: string | null = null;
  useQRReader = __USE_QR_READER__;
  isNativePlatform =
    Capacitor.isNativePlatform() ||
    __IS_MOBILE__ ||
    Capacitor.getPlatform() === "android" ||
    Capacitor.getPlatform() === "ios";
  
  isInitializing = true;
  isScanning = false;
  preferredCamera: 'user' | 'environment' = 'environment';

  created() {
    logger.log("QRScannerDialog platform detection:", {
      capacitorNative: Capacitor.isNativePlatform(),
      isMobile: __IS_MOBILE__,
      platform: Capacitor.getPlatform(),
      useQRReader: this.useQRReader,
      isNativePlatform: this.isNativePlatform,
      userAgent: navigator.userAgent,
      mediaDevices: !!navigator.mediaDevices,
      getUserMedia: !!(navigator.mediaDevices && navigator.mediaDevices.getUserMedia),
    });

    // If on native platform, close immediately and don't initialize web scanner
    if (this.isNativePlatform) {
      logger.log("Closing QR dialog on native platform");
      this.$nextTick(() => this.close());
    }
  }

  async onInit(promise: Promise<void>): Promise<void> {
    // Don't initialize on mobile platforms
    if (this.isNativePlatform) {
      logger.log("Skipping web scanner initialization on native platform");
      return;
    }

    this.isInitializing = true;
    this.error = null;
    logger.log("Initializing QR scanner...");
    
    try {
      await promise;
      this.isInitializing = false;
      logger.log("QR scanner initialized successfully");
    } catch (error) {
      const wrappedError =
        error instanceof Error ? error : new Error(String(error));
      this.error = wrappedError.message;
      if (this.onError) {
        this.onError(wrappedError);
      }
      logger.error("Error initializing QR scanner:", {
        error: wrappedError.message,
        stack: wrappedError.stack,
        name: wrappedError.name,
      });
    } finally {
      this.isInitializing = false;
    }
  }

  onDetect(promise: Promise<any>): void {
    this.isScanning = true;
    logger.log("QR code detected, processing...");
    promise
      .then((result) => {
        logger.log("QR code processed successfully:", result);
      })
      .catch((error) => {
        logger.error("Error processing QR code:", {
          error: error instanceof Error ? error.message : String(error),
          stack: error instanceof Error ? error.stack : undefined,
        });
      })
      .finally(() => {
        this.isScanning = false;
      });
  }

  onDecode(result: string): void {
    logger.log("QR code decoded:", result);
    try {
      this.onScan(result);
      this.close();
    } catch (error) {
      const wrappedError =
        error instanceof Error ? error : new Error(String(error));
      this.error = wrappedError.message;
      if (this.onError) {
        this.onError(wrappedError);
      }
      logger.error("Error handling QR scan result:", {
        error: wrappedError.message,
        stack: wrappedError.stack,
        name: wrappedError.name,
      });
    }
  }

  onError(error: Error): void {
    this.isScanning = false;
    logger.error("QR scanner error:", {
      error: error.message,
      stack: error.stack,
      name: error.name,
    });
    this.error = error.message;
    if (this.onError) {
      this.onError(error);
    }
  }

  toggleCamera(): void {
    this.preferredCamera = this.preferredCamera === 'user' ? 'environment' : 'user';
  }

  retryScanning(): void {
    this.error = null;
    this.isInitializing = true;
    // The QR scanner component will automatically reinitialize
  }

  async close(): Promise<void> {
    logger.log("Closing QR scanner dialog");
    this.visible = false;
    await this.$nextTick();
    if (this.$el && this.$el.parentNode) {
      this.$el.parentNode.removeChild(this.$el);
    }
  }
}
</script>

<style scoped>
.dialog-overlay {
  backdrop-filter: blur(4px);
}

.qrcode-stream {
  width: 100%;
  height: 100%;
}

@keyframes pulse {
  0% {
    opacity: 0.5;
  }
  50% {
    opacity: 0.75;
  }
  100% {
    opacity: 0.5;
  }
}

.animate-pulse {
  animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
</style>
