<template>
  <section class="dashboard-designer">
    <div class="toolbar-row mb-3">
      <div>
        <h2 class="section-title">Dashboard</h2>
        <div v-if="editing" class="quiet text-caption">Drag widgets by their title bar; drag the bottom-right corner to resize.</div>
      </div>
      <v-spacer />
      <template v-if="editing">
        <v-menu :close-on-content-click="false">
          <template #activator="{ props }">
            <v-btn v-bind="props" size="small" variant="tonal" prepend-icon="mdi-plus">Add widget</v-btn>
          </template>
          <v-card max-width="320" max-height="70vh" class="overflow-y-auto">
            <template v-for="group in groups" :key="group">
              <v-list-subheader>{{ group }}</v-list-subheader>
              <v-list density="compact" class="py-0">
                <v-list-item
                  v-for="w in widgetsIn(group)"
                  :key="w.type"
                  :prepend-icon="w.icon"
                  :title="w.title"
                  @click="addWidget(w.type)"
                />
              </v-list>
            </template>
          </v-card>
        </v-menu>
        <v-btn size="small" variant="text" prepend-icon="mdi-restore" @click="resetDefault">Reset</v-btn>
        <v-btn size="small" variant="text" @click="cancelEdit">Cancel</v-btn>
        <v-btn size="small" color="primary" :loading="saving" prepend-icon="mdi-content-save" @click="save">Save</v-btn>
      </template>
      <v-btn v-else size="small" color="primary" variant="tonal" prepend-icon="mdi-pencil" @click="startEdit">Edit layout</v-btn>
    </div>

    <v-alert v-if="message" type="success" density="compact" class="mb-3">{{ message }}</v-alert>

    <GridLayout
      v-if="layout.length"
      :layout="layout"
      :col-num="12"
      :row-height="40"
      :is-draggable="editing"
      :is-resizable="editing"
      :margin="[12, 12]"
      :vertical-compact="true"
      :use-css-transforms="true"
      class="dash-grid"
    >
      <GridItem
        v-for="item in layout"
        :key="item.i"
        :x="item.x"
        :y="item.y"
        :w="item.w"
        :h="item.h"
        :i="item.i"
        :min-w="reg(item).minW"
        :min-h="reg(item).minH"
        drag-allow-from=".widget-handle"
        drag-ignore-from=".widget-actions"
      >
        <component :is="reg(item).component" :token="token" :editing="editing" :config="item.config || {}" @remove="remove(item)" />
      </GridItem>
    </GridLayout>

    <div v-else class="empty-dash quiet">
      <v-icon icon="mdi-view-dashboard-outline" size="48" class="mb-2" />
      <div>Your dashboard is empty.</div>
      <v-btn class="mt-3" color="primary" variant="tonal" prepend-icon="mdi-pencil" @click="startEdit">Edit layout</v-btn>
    </div>
  </section>
</template>

<script>
import { GridLayout, GridItem } from 'grid-layout-plus';
import { apiRequest } from '../services/api';
import { WIDGETS, WIDGET_GROUPS, defaultLayout } from '../dashboard/widgets';

// Drag-and-drop dashboard designer. Renders the user's saved widget layout on a free-form 12-column grid
// (grid-layout-plus). In Edit mode the user adds widgets from the palette, drags/resizes them, and saves;
// the layout persists per user. Widget data re-scopes to the active company automatically (the view is
// remounted on company switch by App.vue). Provides a navigate() to widgets (e.g. Quick links).
export default {
  components: { GridLayout, GridItem },
  props: { token: { type: String, required: true } },
  emits: ['navigate'],
  provide() {
    return { dashboardNavigate: (view) => this.$emit('navigate', view) };
  },
  data() {
    return { layout: [], editing: false, saving: false, message: '', snapshot: null, groups: WIDGET_GROUPS };
  },
  mounted() { this.loadLayout(); },
  methods: {
    reg(item) { return WIDGETS[item.type] || {}; },
    widgetsIn(group) {
      return Object.entries(WIDGETS).filter(([, w]) => w.group === group).map(([type, w]) => ({ type, ...w }));
    },
    sanitize(layout) {
      // Keep only known widget types and the fields we persist.
      return (Array.isArray(layout) ? layout : [])
        .filter((it) => it && WIDGETS[it.type])
        .map((it) => ({ i: it.i, type: it.type, x: it.x, y: it.y, w: it.w, h: it.h, config: it.config || undefined }));
    },
    async loadLayout() {
      try {
        const saved = (await (await apiRequest('/api/dashboard/layout', this.token)).json()).layout;
        const clean = this.sanitize(saved);
        this.layout = clean.length ? clean : defaultLayout();
      } catch {
        this.layout = defaultLayout();
      }
    },
    startEdit() { this.snapshot = JSON.parse(JSON.stringify(this.layout)); this.editing = true; this.message = ''; },
    cancelEdit() { if (this.snapshot) this.layout = this.snapshot; this.editing = false; },
    resetDefault() { this.layout = defaultLayout(); },
    addWidget(type) {
      const w = WIDGETS[type];
      const maxY = this.layout.reduce((m, it) => Math.max(m, it.y + it.h), 0);
      this.layout.push({ i: `${type}-${Date.now()}`, type, x: 0, y: maxY, w: w.w, h: w.h });
    },
    remove(item) { this.layout = this.layout.filter((it) => it.i !== item.i); },
    async save() {
      this.saving = true;
      try {
        const payload = this.sanitize(this.layout);
        await apiRequest('/api/dashboard/layout', this.token, { method: 'PUT', body: JSON.stringify({ layout: payload }) });
        this.editing = false;
        this.message = 'Dashboard saved.';
      } catch (e) { this.message = `Save failed: ${e.message}`; } finally { this.saving = false; }
    }
  }
};
</script>

<!-- grid-layout-plus ships only SCSS; these are the minimal runtime styles it needs (global). -->
<style>
.vgl-layout { position: relative; box-sizing: border-box; }
.vgl-item { box-sizing: border-box; transition: 200ms ease; transition-property: left, top, right; }
.vgl-item--transform { right: auto; left: 0; transition-property: transform; }
.vgl-item--no-touch { touch-action: none; }
.vgl-item--placeholder { z-index: 2; user-select: none; background: rgb(var(--v-theme-primary)); opacity: 0.18; border-radius: 10px; transition-duration: 100ms; }
.vgl-item--dragging { z-index: 3; user-select: none; transition: none; }
.vgl-item--resizing { z-index: 3; user-select: none; opacity: 0.7; }
.vgl-item__resizer { position: absolute; right: 0; bottom: 0; box-sizing: border-box; width: 14px; height: 14px; cursor: se-resize; }
.vgl-item__resizer::before { position: absolute; inset: 0 3px 3px 0; content: ''; border: 0 solid rgba(128,128,128,.8); border-right-width: 2px; border-bottom-width: 2px; }
</style>

<style scoped>
.empty-dash { text-align: center; padding: 60px 20px; border: 1px dashed rgba(128,128,128,.3); border-radius: 12px; }
.dash-grid { margin: 0 -6px; }
</style>
