<template>
  <section class="content-grid">
    <v-card class="span-6 panel-pad">
      <h2 class="section-title mb-1">Scan an asset</h2>
      <p class="quiet text-body-2 mb-3">
        Point your camera at an asset barcode, or type the code to look it up and update it in the field.
      </p>

      <div class="scan-viewport mb-3">
        <video ref="video" class="scan-video" muted playsinline></video>
        <div v-if="!scanning" class="scan-placeholder">
          <v-icon icon="mdi-barcode-scan" size="40" />
          <span>Camera off</span>
        </div>
      </div>

      <div class="toolbar-row">
        <v-btn v-if="!scanning" color="primary" prepend-icon="mdi-camera" :loading="starting" @click="startScan">Start camera</v-btn>
        <v-btn v-else color="error" variant="tonal" prepend-icon="mdi-stop" @click="stopScan">Stop</v-btn>
        <v-select
          v-if="deviceItems.length > 1"
          v-model="deviceId"
          :items="deviceItems"
          item-title="title"
          item-value="value"
          density="compact"
          hide-details
          label="Camera"
          style="max-width: 240px"
          @update:model-value="restartScan"
        />
      </div>

      <v-divider class="my-4" />

      <div class="toolbar-row">
        <v-text-field
          v-model="manualCode"
          label="Enter barcode / asset ID"
          hide-details
          prepend-inner-icon="mdi-keyboard-outline"
          @keyup.enter="lookup(manualCode)"
        />
        <v-btn variant="tonal" prepend-icon="mdi-magnify" @click="lookup(manualCode)">Look up</v-btn>
      </div>

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

    <v-card v-if="asset" class="span-6 panel-pad">
      <div class="toolbar-row mb-3">
        <div>
          <h2 class="section-title">{{ asset.asset_id }}</h2>
          <div class="quiet text-body-2">{{ asset.description }}</div>
        </div>
        <v-spacer />
        <span :class="['status-chip', `status-${form.status}`]">{{ form.status }}</span>
      </div>

      <div class="form-grid">
        <v-select v-model="form.status" :items="statusItems" label="Status" />
        <v-select v-model="form.condition" :items="conditionItems" clearable label="Condition" />
        <v-text-field v-model="form.location" label="Location" />
        <v-text-field v-model="form.department" label="Department" />
        <v-text-field v-model="form.custodian" label="Custodian" />
        <v-textarea v-model="fieldNote" class="full" label="Add field note" rows="2" />
      </div>

      <div class="toolbar-row mt-3">
        <v-spacer />
        <v-btn variant="text" @click="clearAsset">Clear</v-btn>
        <v-btn color="primary" prepend-icon="mdi-content-save" :loading="saving" @click="save">Update asset</v-btn>
      </div>
    </v-card>

    <v-card v-else class="span-6 panel-pad d-flex align-center justify-center" style="min-height: 220px">
      <div class="quiet text-body-2 text-center">
        <v-icon icon="mdi-cube-scan" size="40" class="mb-2" /><br>
        Scan or look up an asset to update it here.
      </div>
    </v-card>
  </section>
</template>

<script>
import { apiRequest } from '../services/api';
import { conditionItems, statusItems } from '../constants';

export default {
  props: {
    token: { type: String, required: true }
  },
  emits: ['asset-updated'],
  data() {
    return {
      conditionItems,
      statusItems,
      reader: null,
      controls: null,
      scanning: false,
      starting: false,
      devices: [],
      deviceId: null,
      asset: null,
      form: { status: 'in_service', condition: null, location: '', department: '', custodian: '' },
      fieldNote: '',
      manualCode: '',
      error: '',
      message: '',
      saving: false
    };
  },
  computed: {
    deviceItems() {
      return this.devices.map((device, index) => ({
        title: device.label || `Camera ${index + 1}`,
        value: device.deviceId
      }));
    }
  },
  beforeUnmount() {
    this.stopScan();
  },
  methods: {
    async startScan() {
      this.error = '';
      this.message = '';
      this.starting = true;
      try {
        const { BrowserMultiFormatReader } = await import('@zxing/browser');
        this.reader = new BrowserMultiFormatReader();
        this.devices = await BrowserMultiFormatReader.listVideoInputDevices();
        if (!this.devices.length) throw new Error('No camera found on this device');
        // Prefer a rear-facing camera when we can identify one.
        if (!this.deviceId) {
          const back = this.devices.find((device) => /back|rear|environment/i.test(device.label || ''));
          this.deviceId = (back || this.devices[this.devices.length - 1]).deviceId;
        }
        this.scanning = true;
        this.controls = await this.reader.decodeFromVideoDevice(this.deviceId, this.$refs.video, (result, _err, controls) => {
          if (result) {
            controls.stop();
            this.scanning = false;
            this.lookup(result.getText());
          }
        });
      } catch (error) {
        this.scanning = false;
        this.error = `Camera unavailable: ${error.message}. Camera access needs HTTPS or localhost — you can still enter codes manually.`;
      } finally {
        this.starting = false;
      }
    },
    stopScan() {
      try {
        this.controls?.stop();
      } catch {
        // controls may already be stopped
      }
      this.controls = null;
      this.scanning = false;
    },
    async restartScan() {
      if (this.scanning) {
        this.stopScan();
        await this.startScan();
      }
    },
    async lookup(code) {
      const value = String(code || '').trim();
      if (!value) return;
      this.error = '';
      this.message = '';
      try {
        const response = await apiRequest(`/api/assets/lookup?code=${encodeURIComponent(value)}`, this.token);
        const data = await response.json();
        this.asset = data.asset;
        this.manualCode = value;
        this.form = {
          status: data.asset.status,
          condition: data.asset.condition || null,
          location: data.asset.location || '',
          department: data.asset.department || '',
          custodian: data.asset.custodian || ''
        };
        this.fieldNote = '';
      } catch (error) {
        this.asset = null;
        this.error = error.message;
      }
    },
    async save() {
      if (!this.asset) return;
      this.saving = true;
      this.error = '';
      try {
        await apiRequest(`/api/assets/${this.asset.id}`, this.token, {
          method: 'PUT',
          body: JSON.stringify(this.form)
        });
        if (this.fieldNote.trim()) {
          await apiRequest(`/api/assets/${this.asset.id}/notes`, this.token, {
            method: 'POST',
            body: JSON.stringify({ body: this.fieldNote.trim() })
          });
        }
        this.message = `${this.asset.asset_id} updated`;
        this.$emit('asset-updated');
        this.clearAsset();
      } catch (error) {
        this.error = error.message;
      } finally {
        this.saving = false;
      }
    },
    clearAsset() {
      this.asset = null;
      this.fieldNote = '';
      this.manualCode = '';
    }
  }
};
</script>
