<script setup lang="ts">
import { ref, onMounted, onUnmounted, computed } from 'vue'
import { api, type TaskFull, type PipelineStep, type PendingAction } from '../api'
import Badge from '../components/Badge.vue'
import Modal from '../components/Modal.vue'

const props = defineProps<{ id: string }>()

const task = ref<TaskFull | null>(null)
const loading = ref(true)
const error = ref('')
const selectedStep = ref<PipelineStep | null>(null)
const polling = ref(false)
let pollTimer: ReturnType<typeof setInterval> | null = null

// Approve modal
const showApprove = ref(false)
const approveForm = ref({ title: '', description: '', type: 'decision', createFollowups: true })
const approveLoading = ref(false)
const followupResults = ref<{ id: string; title: string }[]>([])
const pendingActions = ref<PendingAction[]>([])
const resolvingAction = ref(false)

// Reject modal
const showReject = ref(false)
const rejectReason = ref('')

async function load() {
  try {
    const prev = task.value
    task.value = await api.taskFull(props.id)
    // Auto-start polling if task is in_progress
    if (task.value.status === 'in_progress' && !polling.value) {
      startPolling()
    }
    // Stop polling when pipeline done
    if (prev?.status === 'in_progress' && task.value.status !== 'in_progress') {
      stopPolling()
    }
  } catch (e: any) {
    error.value = e.message
  } finally {
    loading.value = false
  }
}

function startPolling() {
  if (polling.value) return
  polling.value = true
  pollTimer = setInterval(load, 3000)
}

function stopPolling() {
  polling.value = false
  if (pollTimer) { clearInterval(pollTimer); pollTimer = null }
}

onMounted(load)
onUnmounted(stopPolling)

function statusColor(s: string) {
  const m: Record<string, string> = {
    pending: 'gray', in_progress: 'blue', review: 'yellow',
    done: 'green', blocked: 'red', decomposed: 'purple',
  }
  return m[s] || 'gray'
}

const roleIcons: Record<string, string> = {
  pm: '\u{1F9E0}', security: '\u{1F6E1}', debugger: '\u{1F50D}',
  frontend_dev: '\u{1F4BB}', backend_dev: '\u{2699}', tester: '\u{2705}',
  reviewer: '\u{1F4CB}', architect: '\u{1F3D7}', followup_pm: '\u{1F4DD}',
}

function stepStatusClass(step: PipelineStep) {
  if (step.success) return 'border-green-700 bg-green-950/30'
  return 'border-red-700 bg-red-950/30'
}

function stepStatusIcon(step: PipelineStep) {
  return step.success ? '\u2713' : '\u2717'
}

function stepStatusColor(step: PipelineStep) {
  return step.success ? 'text-green-400' : 'text-red-400'
}

function formatOutput(text: string | null): string {
  if (!text) return ''
  try {
    const parsed = JSON.parse(text)
    return JSON.stringify(parsed, null, 2)
  } catch {
    return text
  }
}

async function approve() {
  if (!task.value) return
  approveLoading.value = true
  followupResults.value = []
  pendingActions.value = []
  try {
    const data: Record<string, unknown> = {
      create_followups: approveForm.value.createFollowups,
    }
    if (approveForm.value.title) {
      data.decision_title = approveForm.value.title
      data.decision_description = approveForm.value.description
      data.decision_type = approveForm.value.type
    }
    const res = await api.approveTask(props.id, data as any)
    if (res.followup_tasks?.length) {
      followupResults.value = res.followup_tasks.map(t => ({ id: t.id, title: t.title }))
    }
    if (res.pending_actions?.length) {
      pendingActions.value = res.pending_actions
    }
    if (!res.followup_tasks?.length && !res.pending_actions?.length) {
      showApprove.value = false
    }
    approveForm.value = { title: '', description: '', type: 'decision', createFollowups: true }
    await load()
  } catch (e: any) {
    error.value = e.message
  } finally {
    approveLoading.value = false
  }
}

async function resolveAction(action: PendingAction, choice: string) {
  resolvingAction.value = true
  try {
    const res = await api.resolveAction(props.id, action, choice)
    pendingActions.value = pendingActions.value.filter(a => a !== action)
    if (choice === 'manual_task' && res.result && typeof res.result === 'object' && 'id' in res.result) {
      followupResults.value.push({ id: (res.result as any).id, title: (res.result as any).title })
    }
    if (choice === 'rerun') {
      await load()
    }
  } catch (e: any) {
    error.value = e.message
  } finally {
    resolvingAction.value = false
  }
}

async function reject() {
  if (!task.value || !rejectReason.value) return
  try {
    await api.rejectTask(props.id, rejectReason.value)
    showReject.value = false
    rejectReason.value = ''
    await load()
  } catch (e: any) {
    error.value = e.message
  }
}

async function runPipeline() {
  try {
    await api.runTask(props.id)
    startPolling()
    await load()
  } catch (e: any) {
    error.value = e.message
  }
}

const hasSteps = computed(() => (task.value?.pipeline_steps?.length ?? 0) > 0)
const isRunning = computed(() => task.value?.status === 'in_progress')
</script>

<template>
  <div v-if="loading && !task" class="text-gray-500 text-sm">Loading...</div>
  <div v-else-if="error && !task" class="text-red-400 text-sm">{{ error }}</div>
  <div v-else-if="task">
    <!-- Header -->
    <div class="mb-6">
      <div class="flex items-center gap-2 mb-1">
        <router-link :to="`/project/${task.project_id}`" class="text-gray-600 hover:text-gray-400 text-sm no-underline">
          &larr; {{ task.project_id }}
        </router-link>
      </div>
      <div class="flex items-center gap-3 mb-2">
        <h1 class="text-xl font-bold text-gray-100">{{ task.id }}</h1>
        <span class="text-gray-400">{{ task.title }}</span>
        <Badge :text="task.status" :color="statusColor(task.status)" />
        <span v-if="isRunning" class="inline-block w-2 h-2 bg-blue-500 rounded-full animate-pulse"></span>
        <span class="text-xs text-gray-600">pri {{ task.priority }}</span>
      </div>
      <div v-if="task.brief" class="text-xs text-gray-500 mb-1">
        Brief: {{ JSON.stringify(task.brief) }}
      </div>
      <div v-if="task.assigned_role" class="text-xs text-gray-500">
        Assigned: {{ task.assigned_role }}
      </div>
    </div>

    <!-- Pipeline Graph -->
    <div v-if="hasSteps || isRunning" class="mb-6">
      <h2 class="text-sm font-semibold text-gray-300 mb-3">
        Pipeline
        <span v-if="isRunning" class="text-blue-400 text-xs font-normal ml-2 animate-pulse">running...</span>
      </h2>
      <div class="flex items-center gap-1 overflow-x-auto pb-2">
        <template v-for="(step, i) in task.pipeline_steps" :key="step.id">
          <div v-if="i > 0" class="text-gray-600 text-lg shrink-0 px-1">&rarr;</div>
          <button
            @click="selectedStep = selectedStep?.id === step.id ? null : step"
            class="border rounded-lg px-3 py-2 min-w-[120px] text-left transition-all shrink-0"
            :class="[
              stepStatusClass(step),
              selectedStep?.id === step.id ? 'ring-1 ring-blue-500' : '',
            ]"
          >
            <div class="flex items-center gap-1.5 mb-1">
              <span class="text-base">{{ roleIcons[step.agent_role] || '\u{1F916}' }}</span>
              <span class="text-xs font-medium text-gray-300">{{ step.agent_role }}</span>
              <span :class="stepStatusColor(step)" class="text-xs ml-auto">{{ stepStatusIcon(step) }}</span>
            </div>
            <div class="flex gap-2 text-[10px] text-gray-500">
              <span v-if="step.duration_seconds">{{ step.duration_seconds }}s</span>
              <span v-if="step.tokens_used">{{ step.tokens_used?.toLocaleString() }}tk</span>
              <span v-if="step.cost_usd">${{ step.cost_usd?.toFixed(3) }}</span>
            </div>
          </button>
        </template>
      </div>
    </div>

    <!-- No pipeline -->
    <div v-if="!hasSteps && !isRunning" class="mb-6 text-sm text-gray-600">
      No pipeline steps yet.
    </div>

    <!-- Selected step output -->
    <div v-if="selectedStep" class="mb-6">
      <h2 class="text-sm font-semibold text-gray-300 mb-2">
        Output: {{ selectedStep.agent_role }}
        <span class="text-xs text-gray-600 font-normal ml-2">{{ selectedStep.created_at }}</span>
      </h2>
      <div class="border border-gray-800 rounded-lg bg-gray-900/50 overflow-hidden">
        <pre class="p-4 text-xs text-gray-300 overflow-x-auto whitespace-pre-wrap max-h-[600px] overflow-y-auto">{{ formatOutput(selectedStep.output_summary) }}</pre>
      </div>
    </div>

    <!-- Related Decisions -->
    <div v-if="task.related_decisions?.length" class="mb-6">
      <h2 class="text-sm font-semibold text-gray-300 mb-2">Related Decisions</h2>
      <div class="space-y-1">
        <div v-for="d in task.related_decisions" :key="d.id"
          class="px-3 py-2 border border-gray-800 rounded text-xs">
          <Badge :text="d.type" :color="d.type === 'gotcha' ? 'red' : 'blue'" />
          <span class="text-gray-300 ml-2">{{ d.title }}</span>
        </div>
      </div>
    </div>

    <!-- Actions Bar -->
    <div class="sticky bottom-0 bg-gray-950 border-t border-gray-800 py-3 flex gap-3 -mx-6 px-6 mt-8">
      <button v-if="task.status === 'review'"
        @click="showApprove = true"
        class="px-4 py-2 text-sm bg-green-900/50 text-green-400 border border-green-800 rounded hover:bg-green-900">
        &#10003; Approve
      </button>
      <button v-if="task.status === 'review' || task.status === 'in_progress'"
        @click="showReject = true"
        class="px-4 py-2 text-sm bg-red-900/50 text-red-400 border border-red-800 rounded hover:bg-red-900">
        &#10007; Reject
      </button>
      <button v-if="task.status === 'pending' || task.status === 'blocked'"
        @click="runPipeline"
        :disabled="polling"
        class="px-4 py-2 text-sm bg-blue-900/50 text-blue-400 border border-blue-800 rounded hover:bg-blue-900 disabled:opacity-50">
        <span v-if="polling" class="inline-block w-3 h-3 border-2 border-blue-400 border-t-transparent rounded-full animate-spin mr-1"></span>
        {{ polling ? 'Pipeline running...' : '&#9654; Run Pipeline' }}
      </button>
    </div>

    <!-- Approve Modal -->
    <Modal v-if="showApprove" title="Approve Task" @close="showApprove = false; followupResults = []; pendingActions = []">
      <!-- Pending permission actions -->
      <div v-if="pendingActions.length" class="space-y-3">
        <p class="text-sm text-yellow-400">Permission issues need your decision:</p>
        <div v-for="(action, i) in pendingActions" :key="i"
          class="border border-yellow-900/50 rounded-lg p-3 space-y-2">
          <p class="text-sm text-gray-300">{{ action.description }}</p>
          <div class="flex gap-2">
            <button @click="resolveAction(action, 'rerun')" :disabled="resolvingAction"
              class="px-3 py-1 text-xs bg-blue-900/50 text-blue-400 border border-blue-800 rounded hover:bg-blue-900 disabled:opacity-50">
              Rerun (skip permissions)
            </button>
            <button @click="resolveAction(action, 'manual_task')" :disabled="resolvingAction"
              class="px-3 py-1 text-xs bg-gray-800 text-gray-300 border border-gray-700 rounded hover:bg-gray-700 disabled:opacity-50">
              Create task
            </button>
            <button @click="resolveAction(action, 'skip')" :disabled="resolvingAction"
              class="px-3 py-1 text-xs bg-gray-800 text-gray-500 border border-gray-700 rounded hover:bg-gray-700 disabled:opacity-50">
              Skip
            </button>
          </div>
        </div>
      </div>
      <!-- Follow-up results -->
      <div v-if="followupResults.length && !pendingActions.length" class="space-y-3">
        <p class="text-sm text-green-400">Task approved. Created {{ followupResults.length }} follow-up tasks:</p>
        <div class="space-y-1">
          <router-link v-for="f in followupResults" :key="f.id" :to="`/task/${f.id}`"
            class="block px-3 py-2 border border-gray-800 rounded text-sm text-gray-300 hover:border-gray-600 no-underline">
            <span class="text-gray-500">{{ f.id }}</span> {{ f.title }}
          </router-link>
        </div>
        <button @click="showApprove = false; followupResults = []"
          class="w-full py-2 bg-gray-800 text-gray-300 border border-gray-700 rounded text-sm hover:bg-gray-700">
          Close
        </button>
      </div>
      <!-- Approve form -->
      <form v-if="!followupResults.length && !pendingActions.length" @submit.prevent="approve" class="space-y-3">
        <label class="flex items-center gap-2 text-sm text-gray-300 cursor-pointer">
          <input type="checkbox" v-model="approveForm.createFollowups"
            class="rounded border-gray-600 bg-gray-800 text-blue-500" />
          Create follow-up tasks from pipeline results
        </label>
        <p class="text-xs text-gray-500">Optionally record a decision:</p>
        <input v-model="approveForm.title" placeholder="Decision title (optional)"
          class="w-full bg-gray-800 border border-gray-700 rounded px-3 py-2 text-sm text-gray-200 placeholder-gray-600" />
        <textarea v-if="approveForm.title" v-model="approveForm.description" placeholder="Description"
          class="w-full bg-gray-800 border border-gray-700 rounded px-3 py-2 text-sm text-gray-200 placeholder-gray-600 resize-y" rows="2"></textarea>
        <button type="submit" :disabled="approveLoading"
          class="w-full py-2 bg-green-900/50 text-green-400 border border-green-800 rounded text-sm hover:bg-green-900 disabled:opacity-50">
          {{ approveLoading ? 'Processing...' : 'Approve &amp; mark done' }}
        </button>
      </form>
    </Modal>

    <!-- Reject Modal -->
    <Modal v-if="showReject" title="Reject Task" @close="showReject = false">
      <form @submit.prevent="reject" class="space-y-3">
        <textarea v-model="rejectReason" placeholder="Why are you rejecting this?" rows="3" required
          class="w-full bg-gray-800 border border-gray-700 rounded px-3 py-2 text-sm text-gray-200 placeholder-gray-600 resize-y"></textarea>
        <button type="submit"
          class="w-full py-2 bg-red-900/50 text-red-400 border border-red-800 rounded text-sm hover:bg-red-900">
          Reject &amp; return to pending
        </button>
      </form>
    </Modal>
  </div>
</template>
