<script setup lang="ts">
import { ref, computed } from "vue";
import { Button } from "@/components/ui/button";
import { Progress } from "@/components/ui/progress";
import { Loader2, Scissors } from "lucide-vue-next";

const SPLIT_ROWS = 500_000;

const splitting = ref(false);
const progress = ref({ message: "", current: 0, total: 0, files: 0 });
const fileInputRef = ref<HTMLInputElement | null>(null);
let abortRef = false;

const splitFile = async (file: File) => {
  abortRef = false;
  splitting.value = true;
  progress.value = { message: "Lecture en streaming...", current: 0, total: 0, files: 0 };

  const stream = file.stream();
  const reader = stream.getReader();
  const decoder = new TextDecoder("utf-8", { fatal: false });

  let header = "";
  let leftover = "";
  let currentLines: string[] = [];
  let totalRows = 0;
  let fileCount = 0;
  const baseName = file.name.replace(/\.[^.]+$/, "");

  const flushToFile = (lines: string[]) => {
    fileCount++;
    const content = [header, ...lines].join("\n");
    const blob = new Blob([content], { type: "text/csv" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = `${baseName}_part${fileCount}.csv`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  };

  try {
    while (true) {
      if (abortRef) break;
      const { done, value } = await reader.read();
      const chunk = decoder.decode(value, { stream: !done });
      const text = leftover + chunk;
      const lines = text.split(/\r?\n/);
      leftover = done ? "" : (lines.pop() || "");

      for (const line of lines) {
        const trimmed = line.trim();
        if (!trimmed) continue;

        if (!header) {
          // Remove BOM
          header = trimmed.charCodeAt(0) === 0xfeff ? trimmed.slice(1) : trimmed;
          continue;
        }

        currentLines.push(trimmed);
        totalRows++;

        if (currentLines.length >= SPLIT_ROWS) {
          flushToFile(currentLines);
          currentLines = [];
          progress.value = {
            message: `Fichier ${fileCount} créé...`,
            current: totalRows,
            total: Math.max(totalRows, Math.round(file.size / 300)),
            files: fileCount,
          };
          // Small delay to let browser process the download
          await new Promise((r) => setTimeout(r, 300));
        }
      }

      if (done) break;
    }

    // Flush remaining
    if (currentLines.length > 0 && !abortRef) {
      flushToFile(currentLines);
    }

    progress.value = {
      message: `✅ ${fileCount} fichiers créés (${totalRows.toLocaleString("fr-CA")} lignes total)`,
      current: totalRows,
      total: totalRows,
      files: fileCount,
    };
  } catch (err: any) {
    progress.value = {
      message: `❌ Erreur: ${err.message}`,
      current: totalRows,
      total: totalRows,
      files: fileCount,
    };
  }

  splitting.value = false;
};

const pct = computed(() => (progress.value.total > 0 ? Math.round((progress.value.current / progress.value.total) * 100) : 0));

const onFileChange = (e: Event) => {
  const target = e.target as HTMLInputElement;
  const file = target.files?.[0];
  if (file) splitFile(file);
  target.value = "";
};

const cancelSplit = () => {
  abortRef = true;
};

const splitLabel = (SPLIT_ROWS / 1000).toFixed(0);
</script>

<template>
  <div class="bg-card border border-border rounded-2xl p-6 space-y-4">
    <div class="flex items-start gap-4">
      <div class="w-12 h-12 rounded-xl bg-accent/50 flex items-center justify-center flex-shrink-0">
        <Scissors class="w-6 h-6 text-muted-foreground" />
      </div>
      <div>
        <h3 class="font-semibold text-lg">Découper un CSV</h3>
        <p class="text-sm text-muted-foreground">
          Sépare un gros fichier CSV en plusieurs fichiers de {{ splitLabel }}k lignes
          pour éviter les timeouts lors de l'import. Utilise le streaming (pas de limite de taille).
        </p>
      </div>
    </div>

    <input
      ref="fileInputRef"
      type="file"
      accept=".csv,.tsv,.txt"
      class="hidden"
      @change="onFileChange"
    />

    <Button v-if="!splitting && !progress.message" @click="fileInputRef?.click()" class="w-full" variant="outline" size="lg">
      <Scissors class="w-5 h-5 mr-2" />
      Sélectionner un CSV à découper
    </Button>

    <div v-if="splitting" class="space-y-3">
      <div class="flex items-center gap-2 text-sm text-muted-foreground">
        <Loader2 class="w-4 h-4 animate-spin" />
        {{ progress.message }}
      </div>
      <Progress :value="pct" class="h-3" />
      <div class="flex justify-between text-xs text-muted-foreground">
        <span>{{ progress.current.toLocaleString("fr-CA") }} lignes lues</span>
        <span>{{ progress.files }} fichiers créés</span>
      </div>
      <Button variant="destructive" size="sm" @click="cancelSplit">
        Annuler
      </Button>
    </div>

    <div v-if="!splitting && progress.message" class="space-y-3">
      <p class="text-sm text-primary font-medium">{{ progress.message }}</p>
      <p class="text-xs text-muted-foreground">
        Importez ensuite chaque partie via les cartes ci-dessus.
      </p>
      <Button variant="outline" size="sm" @click="progress = { message: '', current: 0, total: 0, files: 0 }">
        Découper un autre fichier
      </Button>
    </div>
  </div>
</template>
