<template>
  <section class="content-grid">
    <v-card class="span-12 panel-pad">
      <div class="toolbar-row mb-3">
        <div>
          <h2 class="section-title">Preventative maintenance plans</h2>
          <div class="quiet text-body-2">Reusable maintenance procedures with a frequency and step checklist. Attach plans to assets from the asset's PM tab.</div>
        </div>
        <v-spacer />
        <v-btn color="primary" prepend-icon="mdi-plus" @click="openNew">New plan</v-btn>
      </div>

      <DataTable
        :columns="columns"
        :rows="plans"
        row-key="id"
        has-actions
        searchable
        search-placeholder="Filter plans"
        empty-text="No PM plans yet. Create one to get started."
      >
        <template #cell-name="{ row }">
          <span class="font-weight-bold">{{ row.name }}</span>
        </template>
        <template #cell-frequency="{ row }">every {{ row.frequency_value }} {{ unitLabel(row.frequency_unit) }}</template>
        <template #cell-steps="{ row }">{{ row.steps.length }}</template>
        <template #cell-estimated_minutes="{ row }">{{ row.estimated_minutes ? row.estimated_minutes + ' min' : '—' }}</template>
        <template #actions="{ row }">
          <v-btn icon="mdi-pencil" size="small" variant="text" @click="openEdit(row)" />
          <v-btn icon="mdi-delete-outline" size="small" variant="text" color="error" @click="remove(row)" />
        </template>
      </DataTable>
      <v-alert v-if="error" type="error" density="compact" class="mt-3">{{ error }}</v-alert>
    </v-card>

    <v-card class="span-12 panel-pad">
      <h2 class="section-title mb-1">Completed PM forms</h2>
      <p class="quiet text-body-2 mb-3">Signed completion records with condition ratings, notes, and photos.</p>
      <DataTable
        :columns="completionColumns"
        :rows="completions"
        row-key="id"
        :page-size="15"
        has-actions
        searchable
        search-placeholder="Filter completions"
        empty-text="No completed PM forms yet."
      >
        <template #cell-completed_at="{ row }">{{ (row.completed_at || '').slice(0, 10) }}</template>
        <template #cell-rating_safety="{ row }">{{ row.rating_safety ? row.rating_safety + '★' : '—' }}</template>
        <template #cell-photo_count="{ row }">{{ row.photo_count }}</template>
        <template #actions="{ row }">
          <v-btn size="small" variant="text" prepend-icon="mdi-file-eye-outline" @click="viewCompletion(row.id)">View</v-btn>
        </template>
      </DataTable>
    </v-card>

    <PmCompletionDialog v-model="completionDialog" :token="token" :completion-id="completionId" />

    <v-dialog v-model="dialog" max-width="720" scrollable>
      <v-card>
        <v-card-title>{{ form.id ? 'Edit PM plan' : 'New PM plan' }}</v-card-title>
        <v-card-text>
          <div class="form-grid">
            <v-text-field v-model="form.name" class="full" label="Plan name" />
            <v-combobox v-model="form.category" :items="categoryItems" label="Category" clearable />
            <v-text-field :model-value="totalStepMinutes" type="number" label="Estimated minutes (from steps)" readonly hint="Auto-totaled from step times" persistent-hint />
            <v-text-field v-model.number="form.frequency_value" type="number" label="Every" />
            <v-select v-model="form.frequency_unit" :items="pmFrequencyUnits" item-title="title" item-value="value" label="Frequency unit" />
            <v-textarea v-model="form.description" class="full" label="Description" rows="2" />
            <v-textarea v-model="form.instructions" class="full" label="Safety / general instructions" rows="2" />
          </div>

          <div class="toolbar-row mt-4 mb-1">
            <h3 class="section-title">Steps</h3>
            <v-spacer />
            <span class="quiet text-caption">Total {{ totalStepMinutes }} min</span>
            <v-btn size="small" variant="tonal" prepend-icon="mdi-plus" @click="addStep">Add step</v-btn>
          </div>
          <p v-if="!form.steps.length" class="quiet text-body-2">No steps yet — add the procedure steps (e.g. "Tighten lug bolt A3").</p>
          <div v-for="(step, index) in form.steps" :key="index" class="pm-step">
            <div class="pm-step-num">{{ index + 1 }}</div>
            <div class="pm-step-fields">
              <div class="d-flex" style="gap:8px">
                <v-text-field v-model="step.title" density="compact" hide-details placeholder="Step title" style="flex:1 1 auto" />
                <v-text-field v-model.number="step.est_minutes" type="number" density="compact" hide-details placeholder="Min" style="max-width:88px" suffix="min" />
              </div>
              <v-text-field v-model="step.details" density="compact" hide-details placeholder="Details (optional)" class="mt-1" />
            </div>
            <div class="pm-step-actions">
              <v-btn icon="mdi-arrow-up" size="x-small" variant="text" :disabled="index === 0" @click="moveStep(index, -1)" />
              <v-btn icon="mdi-arrow-down" size="x-small" variant="text" :disabled="index === form.steps.length - 1" @click="moveStep(index, 1)" />
              <v-btn icon="mdi-delete-outline" size="x-small" variant="text" color="error" @click="form.steps.splice(index, 1)" />
            </div>
          </div>

          <div class="toolbar-row mt-4 mb-1">
            <h3 class="section-title">Components / parts</h3>
            <v-spacer />
            <span class="quiet text-caption">Total {{ currency(totalComponentCost) }}</span>
            <v-btn size="small" variant="tonal" prepend-icon="mdi-plus" @click="addComponent">Add component</v-btn>
          </div>
          <p v-if="!form.components.length" class="quiet text-body-2">No components — add parts (part #, description, supplier, cost) to track PM cost.</p>
          <div v-for="(component, index) in form.components" :key="`c${index}`" class="pm-component">
            <v-text-field v-model="component.part_number" density="compact" hide-details placeholder="Part #" style="max-width:120px" />
            <v-text-field v-model="component.description" density="compact" hide-details placeholder="Description" style="flex:1 1 auto" />
            <v-text-field v-model="component.supplier" density="compact" hide-details placeholder="Supplier" style="max-width:140px" />
            <v-text-field v-model.number="component.cost" type="number" density="compact" hide-details placeholder="Cost" prefix="$" style="max-width:110px" />
            <v-btn icon="mdi-delete-outline" size="x-small" variant="text" color="error" @click="form.components.splice(index, 1)" />
          </div>

          <div class="toolbar-row mt-4 mb-1">
            <h3 class="section-title">Usage meters</h3>
            <v-spacer />
            <v-btn size="small" variant="tonal" prepend-icon="mdi-plus" @click="addMeter">Add meter</v-btn>
          </div>
          <p class="quiet text-body-2">
            Track usage (operating hours, kWh, gallons, cycles…) so service comes due on accumulated use, not just the calendar.
            Requires usage-based scheduling in PM settings.
          </p>
          <div v-for="(meter, index) in form.meters" :key="`m${index}`" class="pm-component">
            <v-text-field v-model="meter.label" density="compact" hide-details placeholder="Meter (e.g. Operating Hours)" style="flex:1 1 auto" />
            <v-text-field v-model="meter.unit" density="compact" hide-details placeholder="Unit" style="max-width:100px" />
            <v-text-field v-model.number="meter.usage_interval" type="number" density="compact" hide-details placeholder="Due every" style="max-width:130px" />
            <v-btn icon="mdi-delete-outline" size="x-small" variant="text" color="error" @click="form.meters.splice(index, 1)" />
          </div>

          <v-switch
            v-model="form.lifespan_adjust"
            color="primary"
            density="compact"
            hide-details
            class="mt-3"
            label="Tighten the interval as the asset ages (lifespan wear curve)"
          />

          <div class="toolbar-row mt-4 mb-1">
            <h3 class="section-title">Guidance photos</h3>
            <v-spacer />
            <v-btn size="small" variant="tonal" prepend-icon="mdi-camera-plus-outline" @click="$refs.planPhotoInput.click()">Add photos</v-btn>
            <input ref="planPhotoInput" hidden type="file" accept="image/*" capture="environment" multiple @change="onPhotoPick" />
          </div>
          <p v-if="!form.photos.length" class="quiet text-body-2">Add reference photos (diagrams, part locations, before/after) shown to technicians during the service.</p>
          <div v-else class="pm-plan-photo-grid">
            <div v-for="(photo, index) in form.photos" :key="photo.id || `np${index}`" class="pm-plan-photo">
              <div class="pm-plan-photo-frame">
                <img :src="photo.data" :alt="photo.caption || 'guidance'" />
                <v-btn icon="mdi-close" size="x-small" color="error" variant="flat" class="pm-plan-photo-remove" @click="form.photos.splice(index, 1)" />
              </div>
              <v-text-field v-model="photo.caption" density="compact" hide-details placeholder="Caption" class="mt-1" />
            </div>
          </div>
        </v-card-text>
        <v-card-actions>
          <v-spacer />
          <v-btn variant="text" @click="dialog = false">Cancel</v-btn>
          <v-btn color="primary" prepend-icon="mdi-content-save" :disabled="!form.name" :loading="saving" @click="save">Save plan</v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>
  </section>
</template>

<script>
import DataTable from '../components/DataTable.vue';
import PmCompletionDialog from '../components/PmCompletionDialog.vue';
import { apiRequest } from '../services/api';
import { pmFrequencyUnits } from '../constants';
import { currency } from '../utils/format';
import { clonePlain } from '../utils/clone';

function blankPlan() {
  return { id: null, name: '', description: '', category: '', frequency_value: 3, frequency_unit: 'months', estimated_minutes: null, instructions: '', steps: [], components: [], meters: [], lifespan_adjust: false, photos: [] };
}

export default {
  components: { DataTable, PmCompletionDialog },
  props: {
    token: { type: String, required: true }
  },
  data() {
    return {
      pmFrequencyUnits,
      plans: [],
      pmCategories: [],
      completions: [],
      completionDialog: false,
      completionId: null,
      dialog: false,
      form: blankPlan(),
      saving: false,
      error: '',
      columns: [
        { key: 'name', label: 'Plan' },
        { key: 'category', label: 'Category' },
        { key: 'frequency', label: 'Frequency', sortable: false },
        { key: 'steps', label: 'Steps' },
        { key: 'estimated_minutes', label: 'Est. time' },
        { key: 'components_total', label: 'Parts cost', format: 'currency' }
      ],
      completionColumns: [
        { key: 'asset_code', label: 'Asset' },
        { key: 'plan_name', label: 'Plan' },
        { key: 'completed_at', label: 'Completed', format: 'date' },
        { key: 'completed_by_name', label: 'By' },
        { key: 'rating_safety', label: 'Safety' },
        { key: 'photo_count', label: 'Photos', format: 'number' }
      ]
    };
  },
  computed: {
    categoryItems() {
      // Admin-managed PM categories, plus any value already in use so existing plans stay selectable.
      const inUse = this.plans.map((plan) => plan.category).filter(Boolean);
      return [...new Set([...this.pmCategories, ...inUse])].sort((a, b) => String(a).localeCompare(String(b)));
    },
    totalStepMinutes() {
      return this.form.steps.reduce((sum, step) => sum + (Number(step.est_minutes) || 0), 0);
    },
    totalComponentCost() {
      return this.form.components.reduce((sum, component) => sum + (Number(component.cost) || 0), 0);
    }
  },
  mounted() {
    this.load();
    this.loadCompletions();
    this.loadCategories();
  },
  methods: {
    currency,
    async api(path, options = {}) {
      return apiRequest(path, this.token, options);
    },
    async load() {
      const data = await (await this.api('/api/pm-plans')).json();
      this.plans = data.plans;
    },
    async loadCompletions() {
      const data = await (await this.api('/api/pm-completions')).json();
      this.completions = data.completions;
    },
    async loadCategories() {
      try {
        const data = await (await this.api('/api/pm-categories')).json();
        this.pmCategories = (data.categories || []).map((category) => category.name).filter(Boolean);
      } catch {
        this.pmCategories = [];
      }
    },
    viewCompletion(id) {
      this.completionId = id;
      this.completionDialog = true;
    },
    unitLabel(unit) {
      return (pmFrequencyUnits.find((u) => u.value === unit) || {}).title || unit;
    },
    openNew() {
      this.form = blankPlan();
      this.error = '';
      this.dialog = true;
    },
    async openEdit(plan) {
      this.error = '';
      // Fetch the full plan so guidance-photo image data (omitted from the list) is available.
      let full = plan;
      try {
        const data = await (await this.api(`/api/pm-plans/${plan.id}`)).json();
        full = data.plan;
      } catch {
        // fall back to the list row (photos will lack image data)
      }
      this.form = {
        ...clonePlain(full),
        steps: clonePlain(full.steps || []),
        components: clonePlain(full.components || []),
        meters: clonePlain(full.meters || []),
        lifespan_adjust: Boolean(full.lifespan_adjust),
        photos: clonePlain(full.photos || [])
      };
      this.dialog = true;
    },
    addStep() {
      this.form.steps.push({ title: '', details: '', est_minutes: null });
    },
    addComponent() {
      this.form.components.push({ part_number: '', description: '', supplier: '', cost: null });
    },
    addMeter() {
      this.form.meters.push({ label: '', unit: '', usage_interval: null });
    },
    onPhotoPick(event) {
      for (const file of Array.from(event.target.files || [])) {
        const reader = new FileReader();
        reader.onload = () => this.form.photos.push({ name: file.name, mime: file.type, data: String(reader.result), caption: '' });
        reader.readAsDataURL(file);
      }
      event.target.value = '';
    },
    moveStep(index, dir) {
      const target = index + dir;
      const steps = this.form.steps;
      [steps[index], steps[target]] = [steps[target], steps[index]];
    },
    async save() {
      this.saving = true;
      this.error = '';
      try {
        const method = this.form.id ? 'PUT' : 'POST';
        const url = this.form.id ? `/api/pm-plans/${this.form.id}` : '/api/pm-plans';
        // Existing photos carry an id; resend only {id, caption} so the stored blob isn't re-uploaded.
        const photos = (this.form.photos || []).map((p) => (p.id
          ? { id: p.id, caption: p.caption }
          : { data: p.data, name: p.name, mime: p.mime, caption: p.caption }));
        await this.api(url, { method, body: JSON.stringify({ ...this.form, photos }) });
        this.dialog = false;
        await this.load();
      } catch (error) {
        this.error = error.message;
      } finally {
        this.saving = false;
      }
    },
    async remove(plan) {
      this.error = '';
      try {
        await this.api(`/api/pm-plans/${plan.id}`, { method: 'DELETE' });
        await this.load();
      } catch (error) {
        this.error = error.message;
      }
    }
  }
};
</script>

<style scoped>
.pm-step {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px solid rgba(var(--v-theme-on-surface), 0.08);
}
.pm-step-num {
  flex: 0 0 26px;
  height: 26px;
  border-radius: 50%;
  background: rgba(var(--v-theme-primary), 0.15);
  color: rgb(var(--v-theme-primary));
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 0.8rem;
  margin-top: 4px;
}
.pm-step-fields {
  flex: 1 1 auto;
}
.pm-step-actions {
  display: flex;
  align-items: center;
}
.pm-component {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 0;
  border-bottom: 1px solid rgba(var(--v-theme-on-surface), 0.08);
}
.pm-plan-photo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 12px;
}
.pm-plan-photo-frame {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid rgba(var(--v-theme-on-surface), 0.18);
}
.pm-plan-photo-frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.pm-plan-photo-remove {
  position: absolute;
  top: 6px;
  right: 6px;
}
</style>
