import { SubmissionFile } from '@/types'
import { defineStore } from 'pinia'
import { ref, nextTick, computed } from "vue";
import { ocrService } from "@/services/ocrService";

const CONFIDENCE_VALUE = 0.8;

export const useUploadsStore = defineStore('uploads', () => {
  const submissionFiles = ref<SubmissionFile[]>([])

  const isProcessingOCR = computed(() =>
    submissionFiles.value.some(item => item.ocrProcessing)
  );

  const hasLowConfidence = computed(() =>
    submissionFiles.value.some(file => {
      return isLowConfidence(file)
    })
  )

  const submissionFilesNeedingManualSelection = computed(() => {
    return submissionFiles.value.filter(file => file.needsManualPuzzleSelection)
  })

  const isLowConfidence = (file: SubmissionFile) => {
    if (!file.ocrData?.confidence) return false;
    return (
      file.ocrData.confidence.cost < CONFIDENCE_VALUE ||
      file.ocrData.confidence.cycles < CONFIDENCE_VALUE ||
      file.ocrData.confidence.area < CONFIDENCE_VALUE
    )
  }

  const processOCR = async (submissionFile: SubmissionFile) => {
    while (isProcessingOCR.value) {
      const waitingTimeMs = Math.floor(Math.random() * 400) + 100;
      console.log(`OCR is already processing, waiting ${waitingTimeMs}ms...`);
      await new Promise((res) => setTimeout(res, waitingTimeMs));
    }

    const index = submissionFiles.value.indexOf(submissionFile)

    // Update the reactive array directly
    submissionFiles.value[index].ocrProcessing = true;
    submissionFiles.value[index].ocrError = undefined;
    submissionFiles.value[index].ocrData = undefined;

    try {
      console.log("Starting OCR processing for:", submissionFile.file.name);
      await ocrService.initialize();
      const ocrData = await ocrService.extractOpusMagnumData(submissionFile.file);
      console.log("OCR completed:", ocrData);

      // Force reactivity update
      await nextTick();
      submissionFiles.value[index].ocrData = ocrData;

      // Check if puzzle confidence is below CONFIDENCE_VALUE and needs manual selection
      if (ocrData.confidence.puzzle < CONFIDENCE_VALUE) {
        submissionFiles.value[index].needsManualPuzzleSelection = true;
        console.log(
          `Low puzzle confidence (${Math.round(ocrData.confidence.puzzle * 100)}%) for ${submissionFile.file.name}, requiring manual selection`,
        );
      } else {
        submissionFiles.value[index].needsManualPuzzleSelection = false;
      }

      await nextTick();
    } catch (error) {
      console.error("OCR processing failed:", error);
      submissionFiles.value[index].ocrError = "Failed to extract puzzle data";

    } finally {
      submissionFiles.value[index].ocrProcessing = false;
    }
  };

  const processLowConfidenceOCRFiles = async () => {
    const files = submissionFiles.value.filter(file => isLowConfidence(file))

    for (const file of files) {
      processOCR(file)
    }
  }

  const clearFiles = () => {
    submissionFiles.value = []
  }

  return {
    submissionFiles,
    submissionFilesNeedingManualSelection,
    processOCR,
    processLowConfidenceOCRFiles,
    clearFiles,

    // computed
    isProcessingOCR,
    hasLowConfidence,

    CONFIDENCE_VALUE
  }
})
