<script setup>
import AppLayout from "@/Layouts/AppLayout.vue";
import { ref, computed, onMounted, watch } from "vue";
import { useForm, Link, router } from "@inertiajs/vue3";
import axios from "axios";
import BasicTemplateInfo from "./Partials/BasicTemplateInfo.vue";
import ImportModeSettings from "./Partials/ImportModeSettings.vue";
import UnassignedMappings from "./Partials/UnassignedMappings.vue";
import EntityMappings from "./Partials/EntityMappings.vue";
import { Card, CardContent, CardHeader, CardTitle } from "@/Components/ui/card";
import { Label } from "@/Components/ui/label";
import { Input } from "@/Components/ui/input";
import { Textarea } from "@/Components/ui/textarea";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/Components/ui/select";
import { Button } from "@/Components/ui/button";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/Components/ui/alert-dialog";

const props = defineProps({
  template: Object,
  clients: Array,
  segments: Array,
  decisions: Array,
  actions: Array,
});

const form = useForm({
  name: props.template.name,
  description: props.template.description,
  source_type: props.template.source_type,
  default_record_type: props.template.default_record_type || "",
  is_active: props.template.is_active,
  reactivate: props.template.reactivate ?? false,
  client_uuid: props.template.client_uuid || null,
  sample_headers: props.template.sample_headers || [],
  // Add meta with default delimiter support
  meta: {
    ...(props.template.meta || {}),
    payments_import: props.template.meta?.payments_import ?? false,
    history_import: props.template.meta?.history_import ?? false,
    activity_action_id:
      props.template.meta?.activity_action_id ?? props.template.meta?.action_id ?? null,
    activity_decision_id:
      props.template.meta?.activity_decision_id ??
      props.template.meta?.decision_id ??
      null,
    delimiter: (props.template.meta && props.template.meta.delimiter) || "",
  },
});

const decisionsForSelectedAction = computed(() => {
  const act = (props.actions || []).find((a) => a.id === form.meta.action_id);
  return act?.decisions || [];
});

const decisionsForActivitiesAction = computed(() => {
  const act = (props.actions || []).find((a) => a.id === form.meta.activity_action_id);
  return act?.decisions || [];
});

const activityCreatedAtInput = computed({
  get() {
    if (!form.meta.activity_created_at) return "";
    return String(form.meta.activity_created_at).replace(" ", "T");
  },
  set(v) {
    form.meta.activity_created_at = v ? String(v).replace("T", " ") : null;
  },
});

watch(
  () => form.meta.action_id,
  () => {
    form.meta.decision_id = null;
  }
);

watch(
  () => form.meta.activity_action_id,
  () => {
    form.meta.activity_decision_id = null;
  }
);

const entities = computed(() => props.template.meta?.entities || []);
const hasMappings = computed(() => (props.template.mappings?.length || 0) > 0);
const canChangeClient = computed(() => !hasMappings.value); // guard reassignment when mappings exist (optional rule)

const unassigned = computed(() =>
  (props.template.mappings || []).filter((m) => !m.target_field)
);

const unassignedSourceColumns = computed(() => {
  const set = new Set();
  for (const m of unassigned.value) {
    if (m.source_column) set.add(m.source_column);
  }
  return Array.from(set).sort((a, b) => a.localeCompare(b));
});

const allSourceColumns = computed(() => {
  const set = new Set();
  (props.template.sample_headers || []).forEach((h) => set.add(h));
  (props.template.mappings || []).forEach((m) => {
    if (m.source_column) set.add(m.source_column);
  });

  return Array.from(set).sort((a, b) => a.localeCompare(b));
});

// Dynamic Import Entity definitions and field options from API
const entityDefs = ref([]);
const entityOptions = computed(() =>
  entityDefs.value.map((e) => ({ key: e.key, label: e.label || e.key }))
);
const fieldOptions = computed(() =>
  Object.fromEntries(entityDefs.value.map((e) => [e.key, e.fields || []]))
);
const ENTITY_ALIASES = computed(() => {
  const map = {};
  for (const e of entityDefs.value) {
    const aliases = Array.isArray(e.aliases) ? [...e.aliases] : [];
    if (!aliases.includes(e.key)) {
      aliases.push(e.key);
    }
    map[e.key] = aliases;
  }
  return map;
});

async function loadEntityDefs() {
  try {
    const { data } = await axios.get("/api/import-entities");
    entityDefs.value = data?.entities || [];
  } catch (e) {
    console.error("Failed to load import entity definitions", e);
  }
}

// Suggestions powered by backend API
const suggestions = ref({}); // { [sourceColumn]: { entity, field } }
async function refreshSuggestions(columns) {
  const cols = Array.isArray(columns) ? columns : unassignedSourceColumns.value;
  if (!cols || cols.length === 0) {
    return;
  }
  try {
    const only = props.template.meta?.entities || [];
    const { data } = await axios.post("/api/import-entities/suggest", {
      columns: cols,
      only_entities: only,
    });
    suggestions.value = { ...suggestions.value, ...(data?.suggestions || {}) };
  } catch (e) {
    console.error("Failed to load suggestions", e);
  }
}

// Save basic
const save = () => {
  const payload = { ...form.data() };
  if (!canChangeClient.value) {
    // drop client change when blocked
    delete payload.client_uuid;
  }
  const hasActivities =
    Array.isArray(payload.meta?.entities) && payload.meta.entities.includes("activities");
  if (
    hasActivities &&
    (!payload.meta?.activity_action_id || !payload.meta?.activity_decision_id)
  ) {
    alert(
      "Activity imports require selecting an Action and Decision (Activities section)."
    );
    return;
  }
  // Normalize empty delimiter: remove from meta to allow auto-detect
  if (
    payload.meta &&
    typeof payload.meta.delimiter === "string" &&
    payload.meta.delimiter.trim() === ""
  ) {
    delete payload.meta.delimiter;
  }
  useForm(payload).put(
    route("importTemplates.update", { template: props.template.uuid }),
    { preserveScroll: true }
  );
};

// Refresh page helper for partial components
function refreshPage() {
  router.reload({ preserveScroll: true });
}

// Non-blocking confirm modal state for delete
const deleteConfirmOpen = ref(false);
const deleteForm = useForm({});

// Bulk add state
const bulkForm = ref({
  sources: "",
  entity: null,
  default_field: "",
  apply_mode: "both",
  transform: "",
  group: "",
});

function openDeleteConfirm() {
  deleteConfirmOpen.value = true;
}

function performDelete() {
  deleteForm.delete(route("importTemplates.destroy", { template: props.template.uuid }), {
    onFinish: () => {
      deleteConfirmOpen.value = false;
    },
  });
}

function submitBulkAdd() {
  if (!bulkForm.value.sources || bulkForm.value.sources.trim() === "") {
    alert("Vnesite vsaj en izvorni stolpec");
    return;
  }
  router.post(
    route("importTemplates.mappings.bulk", { template: props.template.uuid }),
    {
      sources: bulkForm.value.sources,
      entity: bulkForm.value.entity || null,
      default_field: bulkForm.value.default_field || null,
      apply_mode: bulkForm.value.apply_mode || "both",
      transform: bulkForm.value.transform || "",
      group: bulkForm.value.group || null,
    },
    {
      preserveScroll: true,
      onSuccess: () => {
        bulkForm.value = {
          sources: "",
          entity: null,
          default_field: "",
          apply_mode: "both",
          transform: "",
          group: "",
        };
        refreshPage();
      },
    }
  );
}

// Load entity definitions and initial suggestions
onMounted(async () => {
  await loadEntityDefs();
  await refreshSuggestions();
});

// Refresh suggestions when unassigned list changes
watch(
  () => unassignedSourceColumns.value.join("|"),
  async () => {
    await refreshSuggestions();
  }
);

// Ensure default contract match key when turning on payments mode on existing template
watch(
  () => form.meta.payments_import,
  (enabled) => {
    if (enabled) {
      if (form.meta.history_import) {
        form.meta.history_import = false;
      }
    }
    if (enabled && !form.meta.contract_key_mode) {
      form.meta.contract_key_mode = "reference";
    }
  }
);

// History mode is mutually exclusive with payments mode
watch(
  () => form.meta.history_import,
  (enabled) => {
    if (enabled && form.meta.payments_import) {
      form.meta.payments_import = false;
      form.meta.contract_key_mode = null;
    }
  }
);
</script>

<template>
  <AppLayout :title="`Uredi predlogo: ${props.template.name}`">
    <template #header></template>

    <div class="py-2">
      <div class="max-w-6xl mx-auto sm:px-6 lg:px-8 space-y-6">
        <!-- Header Actions -->
        <div class="flex justify-end">
          <Button variant="destructive" @click="openDeleteConfirm">
            Izbriši predlogo
          </Button>
        </div>

        <!-- Basic Template Info -->
        <BasicTemplateInfo
          :form="form"
          :clients="props.clients"
          :segments="props.segments"
          :actions="props.actions"
          :decisions="decisionsForSelectedAction"
          :can-change-client="canChangeClient"
          @save="save"
        />

        <!-- Import Mode Settings -->
        <ImportModeSettings :form="form" :entities="entities" />

        <!-- Unassigned Mappings -->
        <UnassignedMappings
          :unassigned="unassigned"
          :template-uuid="props.template.uuid"
          :entity-options="entityOptions"
          :field-options="fieldOptions"
          :suggestions="suggestions"
          @refresh="refreshPage"
        />

        <!-- Bulk Add Mappings -->
        <Card>
          <CardHeader>
            <CardTitle>Bulk dodajanje preslikav</CardTitle>
          </CardHeader>
          <CardContent>
            <div class="grid grid-cols-1 gap-4">
              <div class="space-y-2">
                <Label
                  >Source columns (ločeno z vejicami, podpičji ali po vrsticah)</Label
                >
                <Textarea
                  v-model="bulkForm.sources"
                  placeholder="npr.: Pogodba sklic,Številka plačila,Datum,Znesek"
                  rows="4"
                />
              </div>
              <div class="grid grid-cols-1 sm:grid-cols-4 gap-4">
                <div class="space-y-2">
                  <Label>Entity (opcijsko)</Label>
                  <Select v-model="bulkForm.entity">
                    <SelectTrigger>
                      <SelectValue placeholder="(brez – pus" />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem v-for="e in entityOptions" :key="e.key" :value="e.key">
                        {{ e.label }}
                      </SelectItem>
                    </SelectContent>
                  </Select>
                </div>
                <div class="space-y-2">
                  <Label>Field (opcijsko, za vse)</Label>
                  <Input
                    v-model="bulkForm.default_field"
                    placeholder="(auto from source)"
                  />
                </div>
                <div class="space-y-2">
                  <Label>Transform (za vse)</Label>
                  <Select v-model="bulkForm.transform">
                    <SelectTrigger>
                      <SelectValue placeholder="None" />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="trim">trim</SelectItem>
                      <SelectItem value="upper">upper</SelectItem>
                      <SelectItem value="lower">lower</SelectItem>
                    </SelectContent>
                  </Select>
                </div>
                <div class="space-y-2">
                  <Label>Apply (za vse)</Label>
                  <Select v-model="bulkForm.apply_mode">
                    <SelectTrigger>
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="both">both</SelectItem>
                      <SelectItem value="insert">insert</SelectItem>
                      <SelectItem value="update">update</SelectItem>
                      <SelectItem value="keyref">keyref</SelectItem>
                    </SelectContent>
                  </Select>
                </div>
              </div>
              <div class="space-y-2">
                <Label>Group (za vse)</Label>
                <Input v-model="bulkForm.group" placeholder="1, 2, home, work" />
              </div>
              <div>
                <Button @click="submitBulkAdd">Dodaj več</Button>
              </div>
            </div>
          </CardContent>
        </Card>

        <!-- Entity Mappings -->
        <EntityMappings
          :entities="entities"
          :entity-options="entityOptions"
          :field-options="fieldOptions"
          :mappings="props.template.mappings || []"
          :template-uuid="props.template.uuid"
          :all-source-columns="allSourceColumns"
          :entity-aliases="ENTITY_ALIASES"
          :actions="props.actions"
          :decisions="props.decisions"
          @refresh="refreshPage"
        />
      </div>
    </div>

    <!-- Delete Confirmation Dialog -->
    <AlertDialog v-model:open="deleteConfirmOpen">
      <AlertDialogContent>
        <AlertDialogHeader>
          <AlertDialogTitle>Izbrišem predlogo?</AlertDialogTitle>
          <AlertDialogDescription>
            Tega dejanja ni mogoče razveljaviti. Vse preslikave te predloge bodo
            izbrisane.
          </AlertDialogDescription>
        </AlertDialogHeader>
        <AlertDialogFooter>
          <AlertDialogCancel :disabled="deleteForm.processing">
            Prekliči
          </AlertDialogCancel>
          <AlertDialogAction
            @click="performDelete"
            :disabled="deleteForm.processing"
            class="bg-destructive hover:bg-destructive/90"
          >
            <span v-if="deleteForm.processing">Brisanje…</span>
            <span v-else>Izbriši</span>
          </AlertDialogAction>
        </AlertDialogFooter>
      </AlertDialogContent>
    </AlertDialog>
  </AppLayout>
</template>

<style>
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.2s;
}
.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
</style>
