<template>
  <div class="p-4" style="border: 1px solid #e5e7eb; border-radius: 8px; background: #fafafa;">
    <Panel class="mb-3" header="Details">
        <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem;">
        <div>
            <div style="color: #6b7280; font-size: 0.875rem; margin-bottom: 0.25rem;">Trading Days</div>
            <div style="font-weight: 600;">{{ rowData.trading_days || 0 }}</div>
        </div>
        <div>
            <div style="color: #6b7280; font-size: 0.875rem; margin-bottom: 0.25rem;">Start Date</div>
            <div style="font-weight: 600;">{{ rowData.start_date || '-' }}</div>
        </div>
        <div>
            <div style="color: #6b7280; font-size: 0.875rem; margin-bottom: 0.25rem;">End Date</div>
            <div style="font-weight: 600;">{{ rowData.end_date || '-' }}</div>
        </div>
        <div>
            <div style="color: #6b7280; font-size: 0.875rem; margin-bottom: 0.25rem;">Closed Days</div>
            <div style="font-weight: 600;">{{ rowData.closed_date || 0 }}</div>
        </div>
        <div>
            <div style="color: #6b7280; font-size: 0.875rem; margin-bottom: 0.25rem;">Final Balance</div>
            <div style="font-weight: 600;">{{ fmtMoney(rowData.balance) }}</div>
        </div>
        </div>
    </Panel>
    <Panel header="Performance">
      <PerformanceChart :data="rowData" />
    </Panel>
    <div class="flex justify-content-end mt-3">
      <Button size="small" rounded icon="pi pi-search" label="Decisions View" @click="decisionsVisible = true" />
    </div>
  </div>
  <Dialog v-model:visible="decisionsVisible" modal :header="`${rowData.agent_name} (${rowData.asset}) - ${rowData.model}`" :style="{ width: '90vw', maxWidth: '1200px' }">
    <div>
      <div v-if="decisionsLoading" class="flex justify-content-center p-4">
        <ProgressSpinner style="width:40px;height:40px" strokeWidth="4" />
      </div>
      <div v-else class="decisions-table-wrapper">
        <DataTable :value="decisionsRows" :rows="25" :rowsPerPageOptions="[25,50]" paginator :sortField="'date'" :sortOrder="1">
          <Column field="date" header="Date" sortable />
          <Column field="action" header="Action">
            <template #body="{ data }">
              <Tag :value="data.action" :severity="getTagColor(data.action)" rounded/>
            </template>
          </Column>
          <Column field="price" header="Price">
            <template #body="{ data }">{{ Number(data.price).toFixed(2) }}</template>
          </Column>
          <Column field="equity" header="Equity (w/ fees)">
            <template #body="{ data }">{{ fmtMoney(data.equity) }}</template>
          </Column>
          <Column field="position" header="Position">
            <template #body="{ data }">
              <Tag :value="data.position" :severity="getTagColor(data.position)" rounded/>
            </template>
          </Column>
          <Column field="sentiment" header="Sentiment" />
        </DataTable>
      </div>
    </div>
  </Dialog>
</template>

<script>
import Panel from 'primevue/panel'
import Dialog from 'primevue/dialog'
import Tag from 'primevue/tag'
import PerformanceChart from './PerformanceChart.vue'
import { getAllDecisions } from '../lib/dataCache'
import { readAllRawDecisions } from '../lib/idb'
import { filterRowsToNyseTradingDays } from '../lib/marketCalendar'
import { STRATEGIES } from '../lib/strategies'
import { computeStrategyEquity } from '../lib/perf'
export default {
  name: 'ExpansionContent',
  components: {
    Panel,
    PerformanceChart,
    Dialog,
    Tag
  },
  props: {
    rowData: { type: Object, required: true }
  },
  data(){
    return {
      decisionsVisible: false,
      decisionsLoading: false,
      decisionsRows: []
    }
  },
  watch: {
    decisionsVisible: {
      async handler(v){ if (v) await this.loadDecisions() }
    }
  },
  methods: {
    fmtMoney(v){ try{ return `$${Number(v).toLocaleString(undefined,{minimumFractionDigits:2,maximumFractionDigits:2})}` }catch{return v} },
    getSeqFromIds(row){
      const all = getAllDecisions() || []
      const ids = row && (row.decision_ids || row.ids || [])
      let seq = []
      if (ids && ids.length) {
        seq = all.filter(r => ids.includes(r.id))
      } else if (row) {
        // Only fallback to full data if no decision_ids were provided at all
        seq = all.filter(r => r.agent_name === row.agent_name && r.asset === row.asset && r.model === row.model)
      }
      seq.sort((a,b) => (a.date > b.date ? 1 : -1))
      return seq
    },
    async getSeqWithFallback(row){
      let seq = this.getSeqFromIds(row)
      if (seq.length) return seq
      try {
        const all = await readAllRawDecisions()
        const ids = row && (row.decision_ids || row.ids || [])
        if (ids && ids.length) {
          seq = all.filter(r => ids.includes(r.id))
        } else if (row) {
          // Only fallback to full data if no decision_ids were provided at all
          seq = all.filter(r => r.agent_name === row.agent_name && r.asset === row.asset && r.model === row.model)
        }
        seq.sort((a,b) => (a.date > b.date ? 1 : -1))
      } catch(_) {}
      return seq
    },
    computePositionSeries(rows, strategyCfg){
      const data = (rows || []).filter(r => r && r.date && r.price != null).sort((a,b) => (a.date > b.date ? 1 : -1))
      if (!data.length) return []
      let position = 'FLAT'
      let entryPrice = 0
      const positions = []
      for (let i = 0; i < data.length; i++) {
        const price = Number(data[i].price)
        const action = String(data[i].recommended_action || 'HOLD').toUpperCase()
        if ((strategyCfg.tradingMode || 'normal') === 'normal') {
          if (action === 'BUY') {
            if (position === 'FLAT') { position = 'LONG'; entryPrice = price }
            else if (position === 'SHORT') { position = 'LONG'; entryPrice = price }
          } else if (action === 'SELL') {
            if (position === 'LONG') { position = 'FLAT'; entryPrice = 0 }
            else if (position === 'FLAT' && (strategyCfg.strategy || 'long_short') === 'long_short') { position = 'SHORT'; entryPrice = price }
          }
        } else { // aggressive
          if (action === 'HOLD') {
            if (position === 'LONG' || position === 'SHORT') { position = 'FLAT'; entryPrice = 0 }
          } else if (action === 'BUY') {
            if (position === 'SHORT') { position = 'FLAT'; entryPrice = 0 }
            if (position === 'FLAT') { position = 'LONG'; entryPrice = price }
          } else if (action === 'SELL') {
            if (position === 'LONG') { position = 'FLAT'; entryPrice = 0 }
            if (position === 'FLAT' && (strategyCfg.strategy || 'long_short') === 'long_short') { position = 'SHORT'; entryPrice = price }
          }
        }
        positions.push(position === 'LONG' ? 'Long' : (position === 'SHORT' ? 'Short' : 'Flat'))
      }
      // force last flat only affects capital; positions array already recorded daily state
      return positions
    },
    async loadDecisions(){
      this.decisionsLoading = true
      try {
        const row = this.rowData
        const rawSeq = await this.getSeqWithFallback(row)
        const isCrypto = row.asset === 'BTC' || row.asset === 'ETH'
        const seq = isCrypto ? rawSeq : (await filterRowsToNyseTradingDays(rawSeq) || [])
        if (!seq.length) { this.decisionsRows = []; return }
        const strategyCfg = (STRATEGIES || []).find(s => s.id === row.strategy) || { strategy: 'long_short', tradingMode: 'normal', fee: 0.0005 }
        const equitySeries = computeStrategyEquity(seq, 100000, strategyCfg.fee, strategyCfg.strategy, strategyCfg.tradingMode)
        const positionSeries = this.computePositionSeries(seq, strategyCfg)
        const n = Math.min(seq.length, equitySeries.length, positionSeries.length)
        const rows = []
        for (let i = 0; i < n; i++) {
          const r = seq[i]
          rows.push({
            date: r.date,
            action: String(r.recommended_action || 'HOLD').toUpperCase(),
            price: r.price,
            equity: equitySeries[i],
            position: positionSeries[i],
            sentiment: r.sentiment
          })
        }
        this.decisionsRows = rows
      } finally {
        this.decisionsLoading = false
      }
    },
    getTagColor(action) {
      const a = String(action || '').trim().toUpperCase()
      // Actions
      if (a === 'BUY') return 'success'
      if (a === 'SELL') return 'danger'
      if (a === 'HOLD') return 'secondary'
      // Positions
      if (a === 'LONG') return 'success'
      if (a === 'SHORT') return 'danger'
      if (a === 'FLAT') return 'secondary'
      return 'secondary'
    }
    
  }
}
</script>

<style scoped>
.decisions-table-wrapper {
  overflow-x: auto;
  overflow-y: visible;
}

/* 确保在小屏幕上表格可以滚动 */
@media (max-width: 768px) {
  .decisions-table-wrapper {
    max-width: 100%;
  }
  
  .decisions-table-wrapper :deep(.p-datatable) {
    min-width: 600px;
  }
}
</style>