import { useEffect, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { apiFetch } from '@core/lib/api'
import { useAppPath } from '@core/hooks/useAppPath'
import { Card, CardContent, CardHeader, CardTitle } from '@core/components/ui/card'
import { Button } from '@core/components/ui/button'
import { Badge } from '@core/components/ui/badge'
import { Skeleton } from '@core/components/ui/skeleton'
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from '@core/components/ui/dialog'
import { Input } from '@core/components/ui/input'
import { Label } from '@core/components/ui/label'
import { Textarea } from '@core/components/ui/textarea'
import { NativeSelect, NativeSelectOption } from '@core/components/ui/native-select'
import { FolderGit2, Plus, Play, CheckCircle2, Clock, AlertCircle, GitGraph, LayoutDashboard, Trash2, Layers, Pencil, X } from 'lucide-react'

interface SourceSet {
  id: string
  name: string
  base_path: string
  globs?: string
  exclude_globs?: string
  layer?: string
}

interface CILProject {
  id: string
  title: string
  description: string
  status: string
  data: {
    repo_path: string
    language_mix: string
    ingestion_status: 'not_started' | 'in_progress' | 'complete'
    file_count: number
    chunk_count: number
    total_ingestion_cost_usd: number
    last_ingested_at: string | null
    source_sets?: SourceSet[]
    dependencies?: string[]
  }
  created_at: string
}

const STATUS_BADGE: Record<string, { label: string; variant: 'default' | 'secondary' | 'outline' }> = {
  not_started: { label: 'Not Started', variant: 'outline' },
  in_progress: { label: 'In Progress', variant: 'secondary' },
  complete: { label: 'Complete', variant: 'default' },
}

const STATUS_ICON: Record<string, React.ElementType> = {
  not_started: Clock,
  in_progress: AlertCircle,
  complete: CheckCircle2,
}

export default function CILProjectsPage() {
  const navigate = useNavigate()
  const appPath = useAppPath()
  const [projects, setProjects] = useState<CILProject[]>([])
  const [loading, setLoading] = useState(true)
  const [showCreate, setShowCreate] = useState(false)
  const [creating, setCreating] = useState(false)
  const [confirmDeleteId, setConfirmDeleteId] = useState<string | null>(null)
  const [deleting, setDeleting] = useState(false)
  const [form, setForm] = useState({ name: '', description: '', repo_path: '', language_mix: '', source_sets: [] as SourceSet[] })
  const [editingProjectId, setEditingProjectId] = useState<string | null>(null)

  const fetchProjects = () => {
    setLoading(true)
    apiFetch('/api/custom_cil-project?action=list')
      .then(r => r.json())
      .then(data => setProjects(data?.projects || data?.data?.projects || []))
      .catch(() => {})
      .finally(() => setLoading(false))
  }

  useEffect(() => { fetchProjects() }, [])

  const handleSave = async () => {
    if (!form.name || !form.repo_path) return
    setCreating(true)
    try {
      const payload: Record<string, any> = {
        name: form.name,
        description: form.description,
        repo_path: form.repo_path,
        language_mix: form.language_mix,
      }
      if (form.source_sets && form.source_sets.length > 0) {
        payload.source_sets = form.source_sets.map(ss => ({
          ...ss,
          globs: ss.globs ? ss.globs.split(',').map(s => s.trim()).filter(Boolean) : undefined,
          exclude_globs: ss.exclude_globs ? ss.exclude_globs.split(',').map(s => s.trim()).filter(Boolean) : undefined,
        }))
      }

      let res: Response
      if (editingProjectId) {
        res = await apiFetch(`/api/custom_cil-project?action=update&id=${editingProjectId}`, {
          method: 'PATCH',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ data: payload }),
        })
      } else {
        res = await apiFetch('/api/custom_cil-project?action=create', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(payload),
        })
      }

      const data = await res.json()
      const newId = data?.project?.id || data?.data?.project?.id
      setShowCreate(false)
      setEditingProjectId(null)
      setForm({ name: '', description: '', repo_path: '', language_mix: '', source_sets: [] })
      if (newId && !editingProjectId) {
        navigate(appPath(`/cil/${newId}/ingest`))
      } else {
        fetchProjects()
      }
    } catch {
    } finally {
      setCreating(false)
    }
  }

  const openCreate = () => {
    setEditingProjectId(null)
    setForm({ name: '', description: '', repo_path: '', language_mix: '', source_sets: [] })
    setShowCreate(true)
  }

  const openEdit = (project: CILProject) => {
    setEditingProjectId(project.id)
    setForm({
      name: project.title,
      description: project.description,
      repo_path: project.data?.repo_path || '',
      language_mix: project.data?.language_mix || '',
      source_sets: (project.data?.source_sets || []).map(ss => ({
        ...ss,
        globs: Array.isArray(ss.globs) ? ss.globs.join(', ') : ss.globs || '',
        exclude_globs: Array.isArray(ss.exclude_globs) ? ss.exclude_globs.join(', ') : ss.exclude_globs || '',
      })),
    })
    openCreate()
  }

  const handleDeleteProject = async () => {
    if (!confirmDeleteId) return
    setDeleting(true)
    try {
      await apiFetch(`/api/custom_cil-project?action=delete&id=${confirmDeleteId}`, {
        method: 'DELETE',
      })
      setConfirmDeleteId(null)
      fetchProjects()
    } catch {
    } finally {
      setDeleting(false)
    }
  }

  return (
    <div className="p-6 space-y-6">
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold flex items-center gap-2">
            <FolderGit2 className="h-6 w-6 text-indigo-500" />
            Code Intelligence Layer
          </h1>
          <p className="text-muted-foreground text-sm mt-1">
            Register codebases, run ingestion passes, and query the code graph
          </p>
        </div>
        <Button onClick={() => openCreate()}>
          <Plus className="h-4 w-4 mr-2" />
          New Project
        </Button>
      </div>

      {loading ? (
        <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4">
          {[1, 2, 3].map(i => <Skeleton key={i} className="h-44 rounded-xl" />)}
        </div>
      ) : projects.length === 0 ? (
        <div className="flex flex-col items-center justify-center py-24 text-center space-y-3">
          <FolderGit2 className="h-12 w-12 text-muted-foreground/40" />
          <p className="text-muted-foreground">No projects yet. Register a codebase to get started.</p>
          <Button variant="outline" onClick={() => openCreate()}>
            <Plus className="h-4 w-4 mr-2" />
            New Project
          </Button>
        </div>
      ) : (
        <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4">
          {projects.map(project => {
            const ingestionStatus = project.data?.ingestion_status || 'not_started'
            const { label, variant } = STATUS_BADGE[ingestionStatus] || STATUS_BADGE.not_started
            const StatusIcon = STATUS_ICON[ingestionStatus] || Clock

            return (
              <Card
                key={project.id}
                className="cursor-pointer hover:shadow-md transition-shadow"
                onClick={() => navigate(appPath(`/cil/${project.id}/ingest`))}
              >
                <CardHeader className="pb-2">
                  <div className="flex items-start justify-between gap-2">
                    <CardTitle className="text-base">{project.title}</CardTitle>
                    <Badge variant={variant} className="shrink-0 flex items-center gap-1">
                      <StatusIcon className="h-3 w-3" />
                      {label}
                    </Badge>
                  </div>
                  <p className="text-xs text-muted-foreground font-mono truncate">
                    {project.data?.repo_path || '—'}
                  </p>
                </CardHeader>
                <CardContent className="space-y-3">
                  {project.description && (
                    <p className="text-sm text-muted-foreground line-clamp-2">{project.description}</p>
                  )}
                  <div className="grid grid-cols-3 gap-2 pt-1">
                    <div className="text-center">
                      <div className="text-xl font-bold">{project.data?.file_count ?? 0}</div>
                      <div className="text-xs text-muted-foreground">Files</div>
                    </div>
                    <div className="text-center">
                      <div className="text-xl font-bold">{project.data?.chunk_count ?? 0}</div>
                      <div className="text-xs text-muted-foreground">Chunks</div>
                    </div>
                    <div className="text-center">
                      <div className="text-xl font-bold">
                        ${(project.data?.total_ingestion_cost_usd ?? 0).toFixed(2)}
                      </div>
                      <div className="text-xs text-muted-foreground">Cost</div>
                    </div>
                  </div>
                  {project.data?.language_mix && (
                    <p className="text-xs text-muted-foreground">{project.data.language_mix}</p>
                  )}
                  <div className="flex gap-2">
                    <Button
                      size="sm"
                      variant="outline"
                      className="flex-1"
                      onClick={e => {
                        e.stopPropagation()
                        navigate(appPath(`/cil/${project.id}/ingest`))
                      }}
                    >
                      <Play className="h-3 w-3 mr-1" />
                      Run Pipeline
                    </Button>
                    <Button
                      size="sm"
                      variant="ghost"
                      className="px-2"
                      onClick={e => {
                        e.stopPropagation()
                        navigate(appPath(`/cil/${project.id}/dashboard`))
                      }}
                      title="Dashboard"
                    >
                      <LayoutDashboard className="h-3.5 w-3.5" />
                    </Button>
                    <Button
                      size="sm"
                      variant="ghost"
                      className="px-2"
                      onClick={e => {
                        e.stopPropagation()
                        navigate(appPath(`/cil/${project.id}/files`))
                      }}
                      title="Browse Files"
                    >
                      <Layers className="h-3.5 w-3.5" />
                    </Button>
                    <Button
                      size="sm"
                      variant="ghost"
                      className="px-2"
                      onClick={e => {
                        e.stopPropagation()
                        navigate(appPath(`/cil/${project.id}/graph`))
                      }}
                      title="View Graph"
                    >
                      <GitGraph className="h-3.5 w-3.5" />
                    </Button>
                    <Button
                      size="sm"
                      variant="ghost"
                      className="px-2"
                      onClick={e => {
                        e.stopPropagation()
                        openEdit(project)
                      }}
                      title="Edit project"
                    >
                      <Pencil className="h-3.5 w-3.5" />
                    </Button>
                    <Button
                      size="sm"
                      variant="ghost"
                      className="px-2 text-destructive hover:text-destructive hover:bg-destructive/10"
                      onClick={e => {
                        e.stopPropagation()
                        setConfirmDeleteId(project.id)
                      }}
                      title="Delete project"
                    >
                      <Trash2 className="h-3.5 w-3.5" />
                    </Button>
                  </div>
                </CardContent>
              </Card>
            )
          })}
        </div>
      )}

      {/* Create Project Dialog */}
      <Dialog open={showCreate} onOpenChange={open => { if (!open) { setEditingProjectId(null); setForm({ name: '', description: '', repo_path: '', language_mix: '', source_sets: [] }) } setShowCreate(open) }}>
        <DialogContent className="max-w-2xl max-h-[85vh] overflow-y-auto">
          <DialogHeader>
            <DialogTitle>{editingProjectId ? 'Edit CIL Project' : 'Register New CIL Project'}</DialogTitle>
          </DialogHeader>
          <div className="space-y-4 py-2">
            <div className="space-y-1.5">
              <Label htmlFor="name">Project Name *</Label>
              <Input
                id="name"
                placeholder="spine-ia"
                value={form.name}
                onChange={e => setForm(f => ({ ...f, name: e.target.value }))}
              />
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="repo_path">Repository Path *</Label>
              <Input
                id="repo_path"
                placeholder="/Users/thistle/CascadeProjects/spine-ia"
                value={form.repo_path}
                onChange={e => setForm(f => ({ ...f, repo_path: e.target.value }))}
              />
              <p className="text-xs text-muted-foreground">Absolute path to the repository root on the agent's filesystem</p>
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="language_mix">Languages</Label>
              <Input
                id="language_mix"
                placeholder="TypeScript, SQL"
                value={form.language_mix}
                onChange={e => setForm(f => ({ ...f, language_mix: e.target.value }))}
              />
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="description">Description</Label>
              <Textarea
                id="description"
                placeholder="Spine framework — multi-tenant SaaS platform"
                value={form.description}
                onChange={e => setForm(f => ({ ...f, description: e.target.value }))}
                rows={3}
              />
            </div>

            {/* Source Sets */}
            <div className="space-y-2 pt-2 border-t">
              <div className="flex items-center justify-between">
                <Label>Source Sets</Label>
                <Button
                  type="button"
                  size="sm"
                  variant="outline"
                  onClick={() => setForm(f => ({
                    ...f,
                    source_sets: [...f.source_sets, { id: crypto.randomUUID(), name: '', base_path: '', globs: '', exclude_globs: '', layer: 'app-specific' }],
                  }))}
                >
                  <Plus className="h-3 w-3 mr-1" /> Add Source Set
                </Button>
              </div>
              <p className="text-xs text-muted-foreground">
                Optional. Leave empty to use the default globs. Each source set defines a base path relative to the repo root, its own globs/excludes, and an architectural layer.
              </p>
              {form.source_sets.length === 0 && (
                <p className="text-xs text-muted-foreground italic">No source sets — default globs will be used.</p>
              )}
              {form.source_sets.map((ss, idx) => (
                <div key={ss.id} className="border rounded-md p-3 space-y-2 bg-muted/30">
                  <div className="flex items-center justify-between gap-2">
                    <Input
                      placeholder="Set name"
                      value={ss.name}
                      onChange={e => setForm(f => {
                        const next = [...f.source_sets]
                        next[idx] = { ...next[idx], name: e.target.value }
                        return { ...f, source_sets: next }
                      })}
                      className="text-sm"
                    />
                    <Button
                      type="button"
                      size="sm"
                      variant="ghost"
                      className="text-destructive hover:text-destructive hover:bg-destructive/10 shrink-0"
                      onClick={() => setForm(f => ({ ...f, source_sets: f.source_sets.filter((_, i) => i !== idx) }))}
                    >
                      <X className="h-3.5 w-3.5" />
                    </Button>
                  </div>
                  <div className="grid grid-cols-2 gap-2">
                    <Input
                      placeholder="Base path (relative to repo)"
                      value={ss.base_path}
                      onChange={e => setForm(f => {
                        const next = [...f.source_sets]
                        next[idx] = { ...next[idx], base_path: e.target.value }
                        return { ...f, source_sets: next }
                      })}
                      className="text-xs font-mono"
                    />
                    <NativeSelect
                      value={ss.layer || 'app-specific'}
                      onChange={e => setForm(f => {
                        const next = [...f.source_sets]
                        next[idx] = { ...next[idx], layer: e.target.value }
                        return { ...f, source_sets: next }
                      })}
                      className="text-xs"
                    >
                      <NativeSelectOption value="shared-core">shared-core</NativeSelectOption>
                      <NativeSelectOption value="app-specific">app-specific</NativeSelectOption>
                      <NativeSelectOption value="infrastructure">infrastructure</NativeSelectOption>
                      <NativeSelectOption value="test">test</NativeSelectOption>
                    </NativeSelect>
                  </div>
                  <Input
                    placeholder="Globs, comma-separated (e.g. **/*.ts, **/*.tsx)"
                    value={ss.globs || ''}
                    onChange={e => setForm(f => {
                      const next = [...f.source_sets]
                      next[idx] = { ...next[idx], globs: e.target.value }
                      return { ...f, source_sets: next }
                    })}
                    className="text-xs font-mono"
                  />
                  <Input
                    placeholder="Exclude globs, comma-separated (optional)"
                    value={ss.exclude_globs || ''}
                    onChange={e => setForm(f => {
                      const next = [...f.source_sets]
                      next[idx] = { ...next[idx], exclude_globs: e.target.value }
                      return { ...f, source_sets: next }
                    })}
                    className="text-xs font-mono"
                  />
                </div>
              ))}
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setShowCreate(false)}>Cancel</Button>
            <Button
              onClick={handleSave}
              disabled={creating || !form.name || !form.repo_path}
            >
              {creating ? 'Saving…' : (editingProjectId ? 'Save Project' : 'Create Project')}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Delete confirmation dialog */}
      <Dialog open={!!confirmDeleteId} onOpenChange={open => { if (!open) setConfirmDeleteId(null) }}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle className="text-destructive flex items-center gap-2">
              <Trash2 className="h-4 w-4" /> Delete Project
            </DialogTitle>
          </DialogHeader>
          <p className="text-sm text-muted-foreground">
            This will permanently delete the project and <strong>all associated files, chunks, proposals, embeddings, and graph links</strong>. This action cannot be undone.
          </p>
          <p className="text-sm font-medium">
            Project: <span className="font-mono">{projects.find(p => p.id === confirmDeleteId)?.title || confirmDeleteId}</span>
          </p>
          <DialogFooter>
            <Button variant="outline" onClick={() => setConfirmDeleteId(null)} disabled={deleting}>Cancel</Button>
            <Button variant="destructive" onClick={handleDeleteProject} disabled={deleting}>
              {deleting ? 'Deleting…' : 'Delete Project'}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  )
}
