<script setup>
import { reactive, ref, computed, onMounted } from "vue";
import { Link, router, usePage } from "@inertiajs/vue3";
import axios from "axios";
import AppLayout from "@/Layouts/AppLayout.vue";
import DataTable from "@/Components/DataTable/DataTableNew2.vue";
import Pagination from "@/Components/Pagination.vue";
import DatePicker from "@/Components/DatePicker.vue";
import AppCard from "@/Components/app/ui/card/AppCard.vue";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/Components/ui/card";
import { Button } from "@/Components/ui/button";
import { Input } from "@/Components/ui/input";
import { Label } from "@/Components/ui/label";
import InputLabel from "@/Components/InputLabel.vue";
import { Separator } from "@/Components/ui/separator";
import AppPopover from "@/Components/app/ui/AppPopover.vue";
import AppCombobox from "@/Components/app/ui/AppCombobox.vue";
import { Download, Filter, RotateCcw } from "lucide-vue-next";

const props = defineProps({
  slug: { type: String, required: true },
  name: { type: String, required: true },
  description: { type: String, default: null },
  inputs: { type: Array, default: () => [] },
  columns: { type: Array, default: () => [] },
  rows: { type: Array, default: () => [] },
  meta: {
    type: Object,
    default: () => ({ total: 0, current_page: 1, per_page: 25, last_page: 1 }),
  },
  query: { type: Object, default: () => ({}) },
});

// filters: start with server-provided query or defaults
const filters = reactive(
  Object.assign(
    Object.fromEntries((props.inputs || []).map((i) => [i.key, i.default ?? null])),
    props.query || {}
  )
);

const filterPopoverOpen = ref(false);

const appliedFilterCount = computed(() => {
  let count = 0;
  for (const inp of props.inputs || []) {
    const value = filters[inp.key];
    if (value !== null && value !== undefined && value !== "") {
      count += 1;
    }
  }
  return count;
});

function resetFilters() {
  for (const i of props.inputs || []) {
    filters[i.key] = i.default ?? null;
  }
}

function applyFilters() {
  filterPopoverOpen.value = false;
  router.get(
    route("reports.show", props.slug),
    { ...filters, per_page: props.meta?.per_page || 25, page: 1 },
    { preserveState: false, replace: false }
  );
}

// If no query params were provided and we have inputs with defaults, apply filters automatically
// OR if there are validation errors for required filters, redirect with defaults
onMounted(() => {
  const page = usePage();
  const errors = page.props.errors || {};
  const hasQueryParams = Object.keys(props.query || {}).length > 0;
  const hasRequiredFilters = (props.inputs || []).some(i => i.required);
  
  // Check if we have validation errors for required filter fields
  const hasRequiredFilterErrors = (props.inputs || []).some(
    i => i.required && errors[i.key]
  );
  
  if ((!hasQueryParams && hasRequiredFilters) || hasRequiredFilterErrors) {
    // Apply filters with defaults on first load to satisfy required fields
    applyFilters();
  }
});

function exportFile(fmt) {
  const params = new URLSearchParams({
    format: fmt,
    ...Object.fromEntries(
      Object.entries(filters).filter(([_, v]) => v !== null && v !== "")
    ),
  });
  window.location.href = route("reports.export", props.slug) + "?" + params.toString();
}

// Async user options for select:user inputs
const userOptions = ref([]);
const userLoading = ref(false);
async function fetchUsers(initial = false) {
  userLoading.value = true;
  try {
    const res = await axios.get(route("reports.users"), {
      params: { limit: initial ? 50 : 50 },
    });
    userOptions.value = Array.isArray(res.data) ? res.data : [];
  } finally {
    userLoading.value = false;
  }
}
const hasUserFilter = computed(() =>
  (props.inputs || []).some((i) => i.type === "select:user")
);

// Async client options for select:client inputs
const clientOptions = ref([]);
const clientLoading = ref(false);
async function fetchClients(initial = false) {
  clientLoading.value = true;
  try {
    const res = await axios.get(route("reports.clients"));
    console.log("Clients response:", res.data);
    clientOptions.value = Array.isArray(res.data) ? res.data : [];
    console.log("clientOptions set to:", clientOptions.value);
  } finally {
    clientLoading.value = false;
  }
}
const hasClientFilter = computed(() =>
  (props.inputs || []).some((i) => i.type === "select:client")
);

onMounted(() => {
  if (hasUserFilter.value) fetchUsers(true);
  if (hasClientFilter.value) fetchClients(true);
});

// Formatting helpers (EU style)
function formatNumberEU(val) {
  if (typeof val !== "number") return String(val ?? "");
  // Use 0 decimals for integers, 2 for decimals
  const hasFraction = Math.abs(val % 1) > 0;
  const opts = hasFraction
    ? { minimumFractionDigits: 2, maximumFractionDigits: 2 }
    : { maximumFractionDigits: 0 };
  return new Intl.NumberFormat("sl-SI", opts).format(val);
}

function pad2(n) {
  return String(n).padStart(2, "0");
}

function formatDateEU(input) {
  if (!input) return "";
  if (typeof input === "string") {
    const s = input.trim();
    // ISO date YYYY-MM-DD
    const m = s.match(/^(\d{4})-(\d{2})-(\d{2})$/);
    if (m) {
      const [, y, mo, d] = m;
      return `${d}.${mo}.${y}`;
    }
  }
  // Fallback via Date object
  const d = new Date(input);
  if (isNaN(d)) return String(input);
  return `${pad2(d.getDate())}.${pad2(d.getMonth() + 1)}.${d.getFullYear()}`;
}

function formatDateTimeEU(input) {
  if (!input) return "";
  if (typeof input === "string") {
    // Handle "YYYY-MM-DD HH:MM:SS" or ISO
    const s = input.replace("T", " ").split(".")[0];
    const m = s.match(/^(\d{4})-(\d{2})-(\d{2})[ T](\d{2}):(\d{2})(?::(\d{2}))?$/);
    if (m) {
      const [, y, mo, d, hh, mm, ss] = m;
      return `${d}.${mo}.${y} ${hh}:${mm}:${ss ?? "00"}`;
    }
  }
  const d = new Date(input);
  if (isNaN(d)) return String(input);
  return `${pad2(d.getDate())}.${pad2(d.getMonth() + 1)}.${d.getFullYear()} ${pad2(
    d.getHours()
  )}:${pad2(d.getMinutes())}:${pad2(d.getSeconds())}`;
}

function isDateLikeKey(key) {
  if (typeof key !== "string") return false;
  return /(^|_)(date|datum)$/.test(key);
}
function isDateTimeKey(key) {
  if (typeof key !== "string") return false;
  return key.endsWith("_at");
}

function isDecimalKey(key) {
  if (typeof key !== "string") return false;
  return /(amount|price|total|sum|avg|mean|saldo|znesek|cost)/i.test(key);
}

function isIdentifierKey(key) {
  if (typeof key !== "string") return false;
  return /(reference|ref|uuid|guid|identifier|oznaka|sklic)$/i.test(key);
}

function formatCell(value, key) {
  if (value === null || value === undefined) return "";
  // Timestamps first
  if (isDateTimeKey(key)) return formatDateTimeEU(value);
  // Pure dates
  if (isDateLikeKey(key)) return formatDateEU(value);
  // ISO-like date string in value
  if (typeof value === "string" && /^\d{4}-\d{2}-\d{2}(?:[ T].*)?$/.test(value)) {
    return value.length > 10 ? formatDateTimeEU(value) : formatDateEU(value);
  }
  // Do not format identifier-like columns (e.g., contract reference)
  if (isIdentifierKey(key)) return value;
  // Numeric formatting: currency/decimal keys -> two decimals
  if (isDecimalKey(key)) {
    if (typeof value !== "number") return value;
    let num = value;

    return new Intl.NumberFormat("sl-SI", {
      minimumFractionDigits: 2,
      maximumFractionDigits: 2,
    }).format(num);
  }
  // Integers and generic numbers: only format actual numbers to avoid touching numeric-looking strings
  if (typeof value === "number") return formatNumberEU(value);
  return value;
}
</script>

<template>
  <AppLayout :title="name">
    <template #header />
    <div class="pt-12">
      <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
        <!-- Header Card -->
        <Card class="mb-6">
          <CardHeader>
            <div class="flex items-start justify-between">
              <div>
                <CardTitle>{{ name }}</CardTitle>
                <CardDescription v-if="description">{{ description }}</CardDescription>
              </div>
              <div class="flex gap-2">
                <Button variant="outline" size="sm" @click="exportFile('csv')">
                  <Download class="mr-2 h-4 w-4" />
                  CSV
                </Button>
                <Button variant="outline" size="sm" @click="exportFile('pdf')">
                  <Download class="mr-2 h-4 w-4" />
                  PDF
                </Button>
                <Button variant="outline" size="sm" @click="exportFile('xlsx')">
                  <Download class="mr-2 h-4 w-4" />
                  Excel
                </Button>
              </div>
            </div>
          </CardHeader>
        </Card>

        <!-- Results Card -->
        <AppCard
          title=""
          padding="none"
          class="p-0! gap-0"
          header-class="py-3! px-4 gap-0 text-muted-foreground"
          body-class=""
        >
          <template #header>
            <div class="flex items-center justify-between w-full">
              <CardTitle>Rezultati</CardTitle>
              <CardDescription>
                Skupaj {{ meta?.total || 0 }}
                {{ meta?.total === 1 ? "rezultat" : "rezultatov" }}
              </CardDescription>
            </div>
          </template>
          <DataTable
            :columns="
              columns.map((c) => ({
                key: c.key,
                label: c.label || c.key,
                sortable: false,
              }))
            "
            :data="rows"
            :meta="meta"
            route-name="reports.show"
            :route-params="{ slug: slug, ...filters }"
            :page-size="meta?.per_page || 25"
            :page-size-options="[10, 25, 50, 100]"
            :show-pagination="false"
            :show-toolbar="true"
            :hoverable="true"
            empty-text="Ni rezultatov."
          >
            <template #toolbar-filters>
              <AppPopover
                v-if="inputs && inputs.length > 0"
                v-model:open="filterPopoverOpen"
                align="start"
                content-class="w-[400px]"
              >
                <template #trigger>
                  <Button variant="outline" size="sm" class="gap-2">
                    <Filter class="h-4 w-4" />
                    Filtri
                    <span
                      v-if="appliedFilterCount > 0"
                      class="ml-1 rounded-full bg-primary px-2 py-0.5 text-xs text-primary-foreground"
                    >
                      {{ appliedFilterCount }}
                    </span>
                  </Button>
                </template>
                <div class="space-y-4">
                  <div class="space-y-2">
                    <h4 class="font-medium text-sm">Filtri poročila</h4>
                    <p class="text-sm text-muted-foreground">
                      Izberite parametre za zožanje prikaza podatkov.
                    </p>
                  </div>
                  <div class="space-y-3">
                    <div v-for="inp in inputs" :key="inp.key" class="space-y-1.5">
                      <InputLabel>{{ inp.label || inp.key }}</InputLabel>
                      <template v-if="inp.type === 'date'">
                        <DatePicker
                          v-model="filters[inp.key]"
                          format="dd.MM.yyyy"
                          placeholder="Izberi datum"
                        />
                      </template>
                      <template v-else-if="inp.type === 'integer'">
                        <Input
                          v-model.number="filters[inp.key]"
                          type="number"
                          placeholder="Vnesi število"
                        />
                      </template>
                      <template v-else-if="inp.type === 'select:user'">
                        <AppCombobox
                          v-model="filters[inp.key]"
                          :items="
                            userOptions.map((u) => ({ value: u.id, label: u.name }))
                          "
                          placeholder="Brez"
                          search-placeholder="Išči uporabnika..."
                          empty-text="Ni uporabnikov"
                          :disabled="userLoading"
                          button-class="w-full"
                        />
                        <div v-if="userLoading" class="text-xs text-muted-foreground">
                          Nalagam…
                        </div>
                      </template>
                      <template v-else-if="inp.type === 'select:client'">
                        <AppCombobox
                          v-model="filters[inp.key]"
                          :items="
                            clientOptions.map((c) => ({ value: c.id, label: c.name }))
                          "
                          placeholder="Brez"
                          search-placeholder="Išči stranko..."
                          empty-text="Ni strank"
                          :disabled="clientLoading"
                          button-class="w-full"
                        />
                        <div v-if="clientLoading" class="text-xs text-muted-foreground">
                          Nalagam…
                        </div>
                      </template>
                      <template v-else>
                        <Input
                          v-model="filters[inp.key]"
                          type="text"
                          placeholder="Vnesi vrednost"
                        />
                      </template>
                    </div>
                    <div class="flex justify-end gap-2 pt-2 border-t">
                      <Button
                        type="button"
                        variant="outline"
                        size="sm"
                        :disabled="appliedFilterCount === 0"
                        @click="resetFilters"
                      >
                        Počisti
                      </Button>
                      <Button type="button" size="sm" @click="applyFilters">
                        Uporabi
                      </Button>
                    </div>
                  </div>
                </div>
              </AppPopover>
            </template>
            <template
              v-for="col in columns"
              :key="col.key"
              #[`cell-${col.key}`]="{ row }"
            >
              {{ formatCell(row[col.key], col.key) }}
            </template>
          </DataTable>
          <div class="border-t border-gray-200 p-4">
            <Pagination
              :links="meta.links"
              :from="meta.from"
              :to="meta.to"
              :total="meta.total"
              :per-page="meta.per_page || 25"
              :last-page="meta.last_page"
              :current-page="meta.current_page"
              per-page-param="per_page"
              page-param="page"
            />
          </div>
        </AppCard>
      </div>
    </div>
  </AppLayout>
</template>
