<template>
  <section class="content-grid">
    <!-- Launcher -->
    <v-card class="span-12 panel-pad">
      <div class="toolbar-row mb-1">
        <h2 class="section-title">Period Close</h2>
      </div>
      <p class="quiet text-body-2 mb-3">
        Guided month-end / year-end close for the fixed-asset subledger. Posts the period's journal entries to the GL,
        reconciles the register, and locks the period against backdated changes. Every action is recorded in
        Admin → Activity &amp; Audit Trail.
      </p>
      <div class="toolbar-row" style="flex-wrap:wrap;gap:12px">
        <v-select v-model="form.book" :items="bookItems" label="Book" density="compact" hide-details style="max-width:200px" />
        <v-select v-model="form.period_type" :items="periodTypeItems" item-title="title" item-value="value" label="Period" density="compact" hide-details style="max-width:140px" />
        <v-text-field v-model.number="form.fiscal_year" type="number" label="Fiscal year" density="compact" hide-details style="max-width:130px" />
        <v-select v-if="form.period_type === 'month'" v-model="form.period_month" :items="monthItems" item-title="title" item-value="value" label="Month" density="compact" hide-details style="max-width:160px" />
        <v-btn color="primary" prepend-icon="mdi-play" :loading="starting" @click="startClose">Start / Resume</v-btn>
      </div>
      <v-alert v-if="error" type="error" density="compact" class="mt-3">{{ error }}</v-alert>
    </v-card>

    <!-- Active close: the wizard -->
    <v-card v-if="period" class="span-8 panel-pad">
      <div class="toolbar-row mb-3">
        <div>
          <h2 class="section-title">
            {{ window.label }} · {{ period.book_code }}
            <v-chip size="small" :color="statusColor" variant="tonal" class="ml-2">{{ period.status }}</v-chip>
            <v-icon v-if="period.locked" icon="mdi-lock" color="error" class="ml-1" />
          </h2>
          <div class="quiet text-body-2">{{ period.period_type === 'year' ? 'Year-end close' : 'Month-end close' }}</div>
        </div>
        <v-spacer />
        <v-btn v-if="period.locked" color="warning" variant="tonal" size="small" prepend-icon="mdi-lock-open" :loading="busy" @click="reopen">Reopen</v-btn>
        <v-btn v-else color="success" prepend-icon="mdi-lock-check" :loading="busy" :disabled="!canFinalize" @click="finalize">Finalize &amp; lock</v-btn>
      </div>
      <v-alert v-if="!period.locked && !canFinalize" type="info" density="compact" variant="tonal" class="mb-3">
        Complete the required steps to finalize: {{ missingRequired.join(', ') || 'run the reconciliation' }}.
      </v-alert>
      <v-alert v-if="message" type="success" density="compact" class="mb-3">{{ message }}</v-alert>

      <!-- Step cards -->
      <div v-for="(step, index) in steps" :key="step.key" class="close-step" :class="{ done: isDone(step.key) }">
        <div class="toolbar-row">
          <div class="step-num">{{ index + 1 }}</div>
          <div>
            <div class="font-weight-medium">
              {{ step.title }}
              <v-chip v-if="step.required" size="x-small" color="primary" variant="tonal" class="ml-1">required</v-chip>
              <v-icon v-if="isDone(step.key)" icon="mdi-check-circle" color="success" size="small" class="ml-1" />
            </div>
            <div class="quiet text-caption">{{ step.description }}</div>
          </div>
          <v-spacer />
          <v-btn v-if="!period.locked" size="x-small" :variant="isDone(step.key) ? 'tonal' : 'outlined'" :color="isDone(step.key) ? 'success' : undefined" @click="toggleStep(step.key)">
            {{ isDone(step.key) ? 'Done' : 'Mark done' }}
          </v-btn>
        </div>

        <div class="step-body">
          <!-- Additions -->
          <template v-if="step.key === 'additions'">
            <div class="quiet text-caption mb-1" v-if="data.threshold">Capitalization threshold: {{ currency(data.threshold) }}</div>
            <CloseTable :rows="data.additions" :columns="addCols" empty="No additions in this period.">
              <template #cell-below="{ row }"><v-chip v-if="row.below_threshold" size="x-small" color="warning" variant="tonal">below threshold</v-chip></template>
            </CloseTable>
          </template>

          <!-- Disposals -->
          <template v-else-if="step.key === 'disposals'">
            <CloseTable :rows="data.disposals" :columns="dispCols" empty="No disposals in this period." />
            <v-btn v-if="!period.locked && data.disposals.length" size="x-small" variant="tonal" class="mt-2" prepend-icon="mdi-bank-transfer" :loading="busy" @click="postDisposals">Post disposal entries</v-btn>
          </template>

          <!-- WIP -->
          <template v-else-if="step.key === 'wip'">
            <CloseTable :rows="data.wip" :columns="wipCols" empty="No work-in-progress assets.">
              <template #cell-action="{ row }">
                <v-btn v-if="!period.locked" size="x-small" color="primary" variant="tonal" :loading="busy" @click="capitalize(row)">Capitalize</v-btn>
              </template>
            </CloseTable>
          </template>

          <!-- Depreciation -->
          <template v-else-if="step.key === 'depreciation'">
            <div class="ledger-summary mb-2">
              <div class="ledger-chip"><span class="quiet">Period depreciation</span><strong>{{ currency(data.depreciation.total) }}</strong></div>
            </div>
            <CloseTable :rows="data.depreciation.by_department" :columns="deptCols" empty="No depreciation this period." />
            <v-alert v-if="data.depreciation.fully_depreciated_still_running.length" type="warning" density="compact" variant="tonal" class="mt-2">
              {{ data.depreciation.fully_depreciated_still_running.length }} fully-depreciated asset(s) still computing depreciation — review.
            </v-alert>
            <v-btn v-if="!period.locked" size="small" color="primary" class="mt-2" prepend-icon="mdi-bank-plus" :loading="busy" @click="postDepreciation">Post depreciation</v-btn>
          </template>

          <!-- Impairments -->
          <template v-else-if="step.key === 'impairments'">
            <CloseTable :rows="data.impairments" :columns="impairCols" empty="No impairment candidates flagged." />
            <div class="quiet text-caption mt-1">Record impairments from the asset's Adjustments tab; they post when this period is reconciled.</div>
          </template>

          <!-- Reconcile -->
          <template v-else-if="step.key === 'reconcile'">
            <v-btn v-if="!period.locked" size="small" variant="tonal" prepend-icon="mdi-scale-balance" :loading="busy" @click="runReconcile">Run reconciliation</v-btn>
            <div v-if="reconciliation" class="mt-2">
              <v-chip size="small" :color="reconciliation.balanced ? 'success' : 'warning'" variant="tonal" class="mb-2">
                {{ reconciliation.balanced ? 'Balanced' : `Variance ${currency(reconciliation.max_variance)} — clear or acknowledge` }}
              </v-chip>
              <CloseTable :rows="reconciliation.lines" :columns="reconCols" empty="" />
            </div>
          </template>

          <!-- Reports -->
          <template v-else-if="step.key === 'reports'">
            <div class="quiet text-body-2">Run and file the final reports for the period:</div>
            <ul class="quiet text-body-2 mt-1">
              <li>Fixed Asset Register · Depreciation Summary · Additions / Disposals</li>
            </ul>
          </template>

          <!-- Year-only confirm steps -->
          <template v-else-if="['final_month_close', 'physical_inventory', 'tax_books'].includes(step.key)">
            <div class="quiet text-body-2">{{ step.description }} Mark done once verified.</div>
          </template>
        </div>
      </div>
    </v-card>

    <!-- History -->
    <v-card :class="period ? 'span-4 panel-pad' : 'span-12 panel-pad'">
      <h3 class="section-title mb-2">Recent closes</h3>
      <v-list density="compact">
        <v-list-item
          v-for="p in periods"
          :key="p.id"
          :active="period && p.id === period.id"
          rounded="sm"
          @click="openPeriod(p.id)"
        >
          <v-list-item-title>{{ labelFor(p) }} · {{ p.book_code }}</v-list-item-title>
          <template #append>
            <v-icon v-if="p.status === 'closed'" icon="mdi-lock" color="error" size="small" />
            <v-chip v-else size="x-small" variant="tonal">{{ p.status }}</v-chip>
          </template>
        </v-list-item>
        <v-list-item v-if="!periods.length" class="quiet text-body-2">No closes yet.</v-list-item>
      </v-list>
    </v-card>
  </section>
</template>

<script>
import { apiRequest } from '../services/api';
import { currency } from '../utils/format';
import CloseTable from '../components/CloseTable.vue';

// Period Close wizard (Financial → Period Close). Walks the month/year close checklist, posts the
// period's depreciation / WIP / disposal / roll-forward journal entries to the GL, reconciles the
// register to the GL, and finalizes (locks) the period. Server enforces gating, scoping, and the lock.
const MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];

export default {
  components: { CloseTable },
  props: { token: { type: String, required: true } },
  data() {
    return {
      books: [],
      form: { book: 'GAAP', period_type: 'month', fiscal_year: new Date().getFullYear(), period_month: new Date().getMonth() + 1 },
      periodTypeItems: [{ title: 'Month', value: 'month' }, { title: 'Year', value: 'year' }],
      monthItems: MONTHS.map((title, i) => ({ title, value: i + 1 })),
      period: null,
      steps: [],
      data: null,
      periods: [],
      starting: false,
      busy: false,
      error: '',
      message: '',
      addCols: [
        { key: 'asset_id', label: 'Asset' }, { key: 'description', label: 'Description' },
        { key: 'acquisition_cost', label: 'Cost', format: 'currency' }, { key: 'in_service_date', label: 'In service' }, { key: 'below', label: '' }
      ],
      dispCols: [
        { key: 'asset_id', label: 'Asset' }, { key: 'description', label: 'Description' }, { key: 'disposal_date', label: 'Date' },
        { key: 'disposed_cost', label: 'Cost', format: 'currency' }, { key: 'accumulated_depreciation', label: 'Accum.', format: 'currency' }, { key: 'gain_loss', label: 'Gain/(loss)', format: 'currency' }
      ],
      wipCols: [
        { key: 'asset_id', label: 'Asset' }, { key: 'description', label: 'Description' }, { key: 'acquisition_cost', label: 'Cost', format: 'currency' }, { key: 'action', label: '' }
      ],
      deptCols: [{ key: 'department', label: 'Department / cost center' }, { key: 'amount', label: 'Depreciation', format: 'currency' }],
      impairCols: [{ key: 'asset_id', label: 'Asset' }, { key: 'description', label: 'Description' }, { key: 'condition', label: 'Condition' }, { key: 'acquisition_cost', label: 'Cost', format: 'currency' }],
      reconCols: [
        { key: 'account', label: 'Account' }, { key: 'subledger', label: 'Subledger', format: 'currency' },
        { key: 'gl', label: 'General ledger', format: 'currency' }, { key: 'variance', label: 'Variance', format: 'currency' }
      ]
    };
  },
  computed: {
    bookItems() {
      return this.books.map((b) => b.code);
    },
    window() {
      return this.data?.window || { label: '' };
    },
    reconciliation() {
      return this.data?.reconciliation || this.period?.reconciliation || null;
    },
    statusColor() {
      return { open: 'grey', in_progress: 'info', closed: 'success' }[this.period?.status] || undefined;
    },
    requiredKeys() {
      return this.steps.filter((s) => s.required).map((s) => s.key);
    },
    missingRequired() {
      return this.requiredKeys.filter((key) => !this.isDone(key));
    },
    canFinalize() {
      return this.period && !this.period.locked && this.missingRequired.length === 0 && Boolean(this.reconciliation);
    }
  },
  mounted() {
    this.loadBooks();
    this.loadPeriods();
  },
  methods: {
    currency,
    async api(path, options = {}) {
      return apiRequest(path, this.token, options);
    },
    labelFor(p) {
      return p.period_type === 'year' ? `FY ${p.fiscal_year}` : `${MONTHS[(p.period_month || 1) - 1].slice(0, 3)} ${p.fiscal_year}`;
    },
    isDone(key) {
      return Boolean(this.period?.steps?.[key]?.done);
    },
    async loadBooks() {
      try {
        const data = await (await this.api('/api/books')).json();
        this.books = data.books;
        const primary = this.books.find((b) => b.is_primary);
        if (primary) this.form.book = primary.code;
      } catch (error) {
        this.error = error.message;
      }
    },
    async loadPeriods() {
      try {
        this.periods = (await (await this.api('/api/close-periods')).json()).periods;
      } catch (error) {
        this.error = error.message;
      }
    },
    async startClose() {
      this.starting = true;
      this.error = '';
      this.message = '';
      try {
        const data = await (await this.api('/api/close-periods/start', { method: 'POST', body: JSON.stringify(this.form) })).json();
        await this.openPeriod(data.period.id);
        await this.loadPeriods();
      } catch (error) {
        this.error = error.message;
      } finally {
        this.starting = false;
      }
    },
    async openPeriod(id) {
      this.error = '';
      this.message = '';
      try {
        const data = await (await this.api(`/api/close-periods/${id}`)).json();
        this.period = data.period;
        this.steps = data.steps;
        this.data = data.data;
      } catch (error) {
        this.error = error.message;
      }
    },
    async refresh() {
      if (this.period) await this.openPeriod(this.period.id);
    },
    async act(path, body) {
      this.busy = true;
      this.error = '';
      this.message = '';
      try {
        const res = await (await this.api(path, { method: 'POST', body: JSON.stringify(body || {}) })).json();
        await this.refresh();
        return res;
      } catch (error) {
        this.error = error.message;
        return null;
      } finally {
        this.busy = false;
      }
    },
    async toggleStep(key) {
      await this.act(`/api/close-periods/${this.period.id}/steps/${key}`, { done: !this.isDone(key) });
    },
    async postDepreciation() {
      const res = await this.act(`/api/close-periods/${this.period.id}/post-depreciation`);
      if (res) this.message = `Posted ${currency(res.summary.debit)} of depreciation across ${res.summary.expense_lines} line(s).`;
    },
    async postDisposals() {
      const res = await this.act(`/api/close-periods/${this.period.id}/post-disposals`);
      if (res) this.message = `Posted entries for ${res.result.posted} disposal(s).`;
    },
    async runReconcile() {
      const res = await this.act(`/api/close-periods/${this.period.id}/reconcile`);
      if (res) this.message = res.reconciliation.balanced ? 'Subledger reconciles to the GL.' : `Variance of ${currency(res.reconciliation.max_variance)} — clear it or mark the step done to acknowledge.`;
    },
    async capitalize(row) {
      const date = window.prompt('In-service date (YYYY-MM-DD):', new Date().toISOString().slice(0, 10));
      if (!date) return;
      const res = await this.act(`/api/close-periods/${this.period.id}/wip/${row.id}/capitalize`, { in_service_date: date });
      if (res) this.message = `Capitalized ${row.asset_id} into service.`;
    },
    async finalize() {
      if (!window.confirm('Finalize and lock this period? Backdated changes will be blocked until it is reopened.')) return;
      const res = await this.act(`/api/close-periods/${this.period.id}/finalize`, { acknowledge_variance: true });
      if (res) {
        this.message = 'Period closed and locked.';
        await this.loadPeriods();
      }
    },
    async reopen() {
      if (!window.confirm('Reopen this closed period? Its posted close entries will be reversed.')) return;
      const res = await this.act(`/api/close-periods/${this.period.id}/reopen`);
      if (res) {
        this.message = 'Period reopened; close entries reversed.';
        await this.loadPeriods();
      }
    }
  }
};
</script>

<style scoped>
.close-step {
  border: 1px solid rgba(128, 128, 128, 0.2);
  border-radius: 8px;
  padding: 12px 14px;
  margin-bottom: 12px;
}
.close-step.done {
  border-color: rgba(76, 175, 80, 0.5);
}
.step-num {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: rgba(var(--v-theme-primary), 0.12);
  color: rgb(var(--v-theme-primary));
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 600;
  font-size: 0.85rem;
  margin-right: 6px;
}
.step-body {
  margin-top: 10px;
  margin-left: 32px;
}
.ledger-summary {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}
.ledger-chip {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 160px;
  padding: 8px 12px;
  border: 1px solid rgba(128, 128, 128, 0.25);
  border-radius: 8px;
}
.ledger-chip strong {
  font-size: 1.05rem;
}
</style>
