<template>
  <section class="content-grid">
    <!-- Rule set list -->
    <v-card class="span-4 panel-pad">
      <div class="toolbar-row mb-2">
        <h2 class="section-title">Tax rule sets</h2>
        <v-spacer />
        <v-btn size="small" variant="tonal" prepend-icon="mdi-plus" @click="newDraft">New</v-btn>
      </div>
      <p class="quiet text-body-2 mb-2">Template-driven JSON rule sets for federal, state, and local depreciation law updates.</p>

      <v-btn block variant="tonal" prepend-icon="mdi-upload" class="mb-3" @click="$refs.uploadInput.click()">Upload JSON</v-btn>
      <input ref="uploadInput" hidden type="file" accept=".json,application/json" @change="onUpload" />

      <v-list density="compact" nav>
        <v-list-item
          v-for="ruleSet in ruleSets"
          :key="ruleSet.id"
          :active="selected && selected.id === ruleSet.id"
          rounded="sm"
          @click="select(ruleSet)"
        >
          <v-list-item-title>{{ ruleSet.name }}</v-list-item-title>
          <v-list-item-subtitle>{{ ruleSet.jurisdiction }} · {{ ruleSet.version }} · {{ ruleSet.effective_date }}</v-list-item-subtitle>
          <template #append>
            <v-chip v-if="ruleSet.active" size="x-small" color="success" variant="tonal">active</v-chip>
          </template>
        </v-list-item>
      </v-list>
    </v-card>

    <!-- Editor -->
    <v-card class="span-8 panel-pad">
      <div class="form-grid mb-3">
        <v-text-field v-model="form.name" label="Name" />
        <v-text-field v-model="form.jurisdiction" label="Jurisdiction" placeholder="US-FED, US-CA, ..." />
        <v-text-field v-model="form.version" label="Version" />
        <v-text-field v-model="form.effective_date" type="date" label="Effective date" />
        <v-text-field v-model="form.source_note" class="full" label="Source note" />
        <v-switch v-model="form.active" label="Active" color="primary" density="compact" hide-details />
      </div>

      <div class="toolbar-row mb-2" style="flex-wrap:wrap;gap:8px">
        <v-btn size="small" variant="text" prepend-icon="mdi-code-braces" @click="formatJson">Format</v-btn>
        <v-btn size="small" variant="text" prepend-icon="mdi-table-refresh" :loading="expanding" @click="regenerateMethods">Regenerate method catalog</v-btn>
        <v-spacer />
        <v-btn size="small" variant="text" prepend-icon="mdi-download" @click="exportJson">Export</v-btn>
        <v-btn v-if="selected && !form.active" size="small" variant="tonal" prepend-icon="mdi-check-circle-outline" @click="activate">Activate</v-btn>
        <v-btn v-if="selected" size="small" variant="text" color="error" prepend-icon="mdi-delete-outline" @click="remove">Delete</v-btn>
        <v-btn color="primary" size="small" prepend-icon="mdi-content-save" :disabled="!jsonValid" :loading="saving" @click="save">Save</v-btn>
      </div>

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

      <component :is="editorComponent" ref="editor" v-model="editorContent" :theme="monacoTheme" />
    </v-card>
  </section>
</template>

<script>
import { defineAsyncComponent } from 'vue';
import { apiRequest, saveBlob } from '../services/api';

function blankForm() {
  return {
    id: null,
    name: '',
    jurisdiction: 'US-FED',
    version: '',
    effective_date: new Date().toISOString().slice(0, 10),
    source_note: '',
    active: true
  };
}

export default {
  props: {
    token: { type: String, required: true },
    dark: { type: Boolean, default: true }
  },
  emits: ['updated'],
  data() {
    return {
      editorComponent: defineAsyncComponent(() => import('../components/MonacoJsonEditor.vue')),
      ruleSets: [],
      selected: null,
      form: blankForm(),
      editorContent: '{\n  "jurisdiction": "US-FED",\n  "name": "New rule set",\n  "version": "1.0",\n  "effectiveDate": "2026-01-01",\n  "limits": {}\n}',
      saving: false,
      expanding: false,
      error: '',
      message: ''
    };
  },
  computed: {
    monacoTheme() {
      return this.dark ? 'vs-dark' : 'vs';
    },
    parsed() {
      try {
        return { value: JSON.parse(this.editorContent), error: '' };
      } catch (error) {
        return { value: null, error: error.message };
      }
    },
    jsonValid() {
      return this.parsed.error === '';
    },
    jsonError() {
      return this.editorContent.trim() ? this.parsed.error : '';
    }
  },
  mounted() {
    this.load();
  },
  methods: {
    async api(path, options = {}) {
      return apiRequest(path, this.token, options);
    },
    async load() {
      const data = await (await this.api('/api/tax-rules')).json();
      this.ruleSets = data.ruleSets;
      if (!this.selected && this.ruleSets.length) this.select(this.ruleSets[0]);
    },
    select(ruleSet) {
      this.message = '';
      this.error = '';
      this.selected = ruleSet;
      this.form = {
        id: ruleSet.id,
        name: ruleSet.name,
        jurisdiction: ruleSet.jurisdiction,
        version: ruleSet.version,
        effective_date: ruleSet.effective_date,
        source_note: ruleSet.source_note || '',
        active: ruleSet.active
      };
      this.editorContent = JSON.stringify(ruleSet.rules_json, null, 2);
    },
    newDraft() {
      this.selected = null;
      this.form = blankForm();
      this.editorContent = JSON.stringify({
        jurisdiction: 'US-FED',
        name: 'New rule set',
        version: '1.0',
        effectiveDate: new Date().toISOString().slice(0, 10),
        limits: { section179: { deductionLimit: 0, phaseOutBegins: 0 }, bonusDepreciation: { qualifiedPropertyPercent: 0 } }
      }, null, 2);
      this.message = '';
      this.error = '';
    },
    onUpload(event) {
      const [file] = event.target.files || [];
      if (!file) return;
      const reader = new FileReader();
      reader.onload = () => {
        this.selected = null;
        this.editorContent = String(reader.result || '');
        try {
          const parsed = JSON.parse(this.editorContent);
          this.form = {
            id: null,
            name: parsed.name || file.name.replace(/\.json$/i, ''),
            jurisdiction: parsed.jurisdiction || 'US-FED',
            version: parsed.version || '1.0',
            effective_date: parsed.effectiveDate || parsed.effective_date || new Date().toISOString().slice(0, 10),
            source_note: parsed.sourceNote || '',
            active: false
          };
          this.message = 'File loaded — review and Save to import.';
        } catch {
          this.message = '';
          this.error = 'Uploaded file is not valid JSON; fix it in the editor before saving.';
        }
      };
      reader.readAsText(file);
      event.target.value = '';
    },
    formatJson() {
      this.$refs.editor?.format?.();
    },
    async regenerateMethods() {
      if (!this.jsonValid) return;
      this.expanding = true;
      this.error = '';
      try {
        const data = await (await this.api('/api/tax-rules/expand', {
          method: 'POST',
          body: JSON.stringify({ rules_json: this.parsed.value })
        })).json();
        this.editorContent = JSON.stringify(data.rules_json, null, 2);
        this.message = 'Method catalog regenerated (68 methods).';
      } catch (error) {
        this.error = error.message;
      } finally {
        this.expanding = false;
      }
    },
    async save() {
      if (!this.jsonValid) return;
      this.saving = true;
      this.error = '';
      this.message = '';
      try {
        const payload = { ...this.form, rules_json: this.parsed.value };
        const method = this.form.id ? 'PUT' : 'POST';
        const url = this.form.id ? `/api/tax-rules/${this.form.id}` : '/api/tax-rules';
        const data = await (await this.api(url, { method, body: JSON.stringify(payload) })).json();
        this.message = 'Rule set saved.';
        await this.load();
        this.select(this.ruleSets.find((set) => set.id === data.ruleSet.id) || data.ruleSet);
        this.$emit('updated');
      } catch (error) {
        this.error = error.message;
      } finally {
        this.saving = false;
      }
    },
    async activate() {
      if (!this.selected) return;
      this.error = '';
      try {
        const data = await (await this.api(`/api/tax-rules/${this.selected.id}/activate`, { method: 'POST' })).json();
        this.ruleSets = data.ruleSets;
        this.select(this.ruleSets.find((set) => set.id === this.selected.id));
        this.message = 'Rule set activated.';
        this.$emit('updated');
      } catch (error) {
        this.error = error.message;
      }
    },
    async remove() {
      if (!this.selected) return;
      this.error = '';
      try {
        await this.api(`/api/tax-rules/${this.selected.id}`, { method: 'DELETE' });
        this.selected = null;
        this.form = blankForm();
        await this.load();
        this.$emit('updated');
      } catch (error) {
        this.error = error.message;
      }
    },
    exportJson() {
      const name = `${this.form.jurisdiction || 'rules'}-${this.form.version || 'export'}.json`.replace(/\s+/g, '-');
      saveBlob(new Blob([this.editorContent], { type: 'application/json' }), name);
    }
  }
};
</script>
