'use client'

import { useState, useEffect, useCallback } from 'react'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Badge } from '@/components/ui/badge'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select'
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from '@/components/ui/dialog'
import { Label } from '@/components/ui/label'
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table'
import {
  BookOpen,
  Plus,
  TrendingUp,
  TrendingDown,
  Minus,
  Loader2,
  AlertCircle,
  GraduationCap,
  Trash2,
  BarChart3,
} from 'lucide-react'
import { BRAND } from '@/lib/constants'

/* ------------------------------------------------------------------ */
/* Types                                                               */
/* ------------------------------------------------------------------ */

interface AcademicResult {
  id: string
  userId: string
  year: number
  term: number
  subject: string
  result: number
  createdAt: string
  updatedAt: string
}

interface GroupedResults {
  [yearTerm: string]: {
    year: number
    term: number
    results: AcademicResult[]
  }
}

/* ------------------------------------------------------------------ */
/* Helper                                                              */
/* ------------------------------------------------------------------ */

function getTrend(current: number, previous: number | null) {
  if (previous === null) return { direction: 'none' as const, change: 0 }
  const diff = current - previous
  if (Math.abs(diff) < 0.5) return { direction: 'none' as const, change: 0 }
  return { direction: (diff > 0 ? 'up' : 'down') as const, change: Math.abs(diff) }
}

function getResultColor(result: number) {
  if (result >= 80) return 'text-green-600 bg-green-50'
  if (result >= 60) return 'text-blue-600 bg-blue-50'
  if (result >= 50) return 'text-yellow-600 bg-yellow-50'
  if (result >= 40) return 'text-orange-600 bg-orange-50'
  return 'text-red-600 bg-red-50'
}

function TrendIcon({ direction, change }: { direction: string; change: number }) {
  if (direction === 'up') {
    return (
      <span className="inline-flex items-center gap-0.5 text-xs font-medium text-green-600">
        <TrendingUp className="w-3 h-3" />+{change.toFixed(1)}%
      </span>
    )
  }
  if (direction === 'down') {
    return (
      <span className="inline-flex items-center gap-0.5 text-xs font-medium text-red-500">
        <TrendingDown className="w-3 h-3" />-{change.toFixed(1)}%
      </span>
    )
  }
  return (
    <span className="inline-flex items-center gap-0.5 text-xs text-gray-400">
      <Minus className="w-3 h-3" />—
    </span>
  )
}

const currentYear = new Date().getFullYear()

/* ------------------------------------------------------------------ */
/* Main Page                                                           */
/* ------------------------------------------------------------------ */

export default function ResultsPage() {
  const [results, setResults] = useState<AcademicResult[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [showForm, setShowForm] = useState(false)
  const [formYear, setFormYear] = useState(currentYear.toString())
  const [formTerm, setFormTerm] = useState('')
  const [formSubject, setFormSubject] = useState('')
  const [formResult, setFormResult] = useState('')
  const [saving, setSaving] = useState(false)

  const fetchResults = useCallback(async () => {
    setLoading(true)
    setError(null)
    try {
      const res = await fetch(`/api/results?userId=demo-student`)
      if (!res.ok) throw new Error('Failed to fetch results')
      const data = await res.json()
      setResults(data.results || [])
    } catch (err) {
      setError(err instanceof Error ? err.message : 'An error occurred')
    } finally {
      setLoading(false)
    }
  }, [])

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

  const handleSubmit = async () => {
    if (!formYear || !formTerm || !formSubject || !formResult) return
    setSaving(true)
    try {
      const res = await fetch('/api/results', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          userId: 'demo-student',
          year: parseInt(formYear),
          term: parseInt(formTerm),
          subject: formSubject,
          result: parseInt(formResult),
        }),
      })
      if (!res.ok) throw new Error('Failed to save result')
      setShowForm(false)
      setFormSubject('')
      setFormResult('')
      fetchResults()
    } catch {
      alert('Failed to save result. Please try again.')
    } finally {
      setSaving(false)
    }
  }

  // Group by year > term
  const grouped = results.reduce<GroupedResults>((acc, r) => {
    const key = `${r.year}-T${r.term}`
    if (!acc[key]) acc[key] = { year: r.year, term: r.term, results: [] }
    acc[key].results.push(r)
    return acc
  }, {})

  const sortedGroups = Object.values(grouped).sort((a, b) => {
    if (a.year !== b.year) return b.year - a.year
    return b.term - a.term
  })

  // Calculate averages per subject for trend comparison
  const subjectAverages = results.reduce<Record<string, number[]>>((acc, r) => {
    if (!acc[r.subject]) acc[r.subject] = []
    acc[r.subject].push(r.result)
    return acc
  }, {})

  const overallAverage = results.length > 0
    ? results.reduce((sum, r) => sum + r.result, 0) / results.length
    : null

  // Build a lookup for previous term results (for trend)
  const resultsBySubjectTerm = results.reduce<Record<string, number>>((acc, r) => {
    acc[`${r.subject}-${r.year}-${r.term}`] = r.result
    return acc
  }, {})

  const getPreviousResult = (subject: string, year: number, term: number) => {
    if (term === 1) {
      // Look at previous year term 4
      return resultsBySubjectTerm[`${subject}-${year - 1}-4`] ?? null
    }
    return resultsBySubjectTerm[`${subject}-${year}-${term - 1}`] ?? null
  }

  return (
    <div className="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
      {/* Page Header */}
      <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-6">
        <div>
          <div className="flex items-center gap-2 mb-1">
            <div
              className="w-8 h-8 rounded-lg flex items-center justify-center"
              style={{ background: BRAND.colors.primaryGradient }}
            >
              <BarChart3 className="w-4 h-4 text-white" />
            </div>
            <h1 className="text-2xl font-bold text-gray-900">Academic Results</h1>
          </div>
          <p className="text-sm text-gray-500">
            Track your academic performance term by term
          </p>
        </div>
        <Button
          onClick={() => setShowForm(true)}
          className="rounded-xl text-white"
          style={{ background: BRAND.colors.primaryGradient }}
        >
          <Plus className="w-4 h-4 mr-2" />
          Add Result
        </Button>
      </div>

      {/* Summary Cards */}
      <div className="grid grid-cols-2 sm:grid-cols-4 gap-3 mb-6">
        <Card>
          <CardContent className="p-4 text-center">
            <p className="text-2xl font-bold" style={{ color: BRAND.colors.primaryDark }}>
              {results.length}
            </p>
            <p className="text-xs text-gray-500 mt-1">Total Entries</p>
          </CardContent>
        </Card>
        <Card>
          <CardContent className="p-4 text-center">
            <p className="text-2xl font-bold" style={{ color: BRAND.colors.primaryDark }}>
              {sortedGroups.length}
            </p>
            <p className="text-xs text-gray-500 mt-1">Terms Recorded</p>
          </CardContent>
        </Card>
        <Card>
          <CardContent className="p-4 text-center">
            <p className="text-2xl font-bold" style={{ color: BRAND.colors.primaryDark }}>
              {overallAverage !== null ? overallAverage.toFixed(1) : '—'}
            </p>
            <p className="text-xs text-gray-500 mt-1">Average Score</p>
          </CardContent>
        </Card>
        <Card>
          <CardContent className="p-4 text-center">
            <p className="text-2xl font-bold" style={{ color: BRAND.colors.primaryDark }}>
              {Object.keys(subjectAverages).length}
            </p>
            <p className="text-xs text-gray-500 mt-1">Subjects</p>
          </CardContent>
        </Card>
      </div>

      {/* Loading */}
      {loading && (
        <div className="flex flex-col items-center justify-center py-16">
          <Loader2 className="w-8 h-8 text-[#5b9ebd] animate-spin mb-4" />
          <p className="text-gray-500">Loading results...</p>
        </div>
      )}

      {/* Error */}
      {error && !loading && (
        <div className="flex flex-col items-center justify-center py-16 text-center">
          <AlertCircle className="w-12 h-12 text-red-400 mb-4" />
          <h3 className="text-lg font-semibold text-gray-900 mb-2">Could not load results</h3>
          <p className="text-gray-500 mb-4 max-w-md">{error}</p>
          <Button variant="outline" onClick={fetchResults} className="rounded-xl">Try Again</Button>
        </div>
      )}

      {/* Empty State */}
      {!loading && !error && results.length === 0 && (
        <div className="flex flex-col items-center justify-center py-16 text-center">
          <div className="w-16 h-16 rounded-2xl bg-gray-100 flex items-center justify-center mb-4">
            <BookOpen className="w-8 h-8 text-gray-400" />
          </div>
          <h3 className="text-lg font-semibold text-gray-900 mb-2">No results yet</h3>
          <p className="text-gray-500 max-w-md mb-4">
            Start tracking your academic performance by adding your first result. Monitor your progress across terms and subjects!
          </p>
          <Button
            onClick={() => setShowForm(true)}
            className="rounded-xl text-white"
            style={{ background: BRAND.colors.primaryGradient }}
          >
            <Plus className="w-4 h-4 mr-2" />
            Add Your First Result
          </Button>
        </div>
      )}

      {/* Results by Year/Term */}
      {!loading && !error && sortedGroups.length > 0 && (
        <div className="space-y-6">
          {sortedGroups.map((group) => {
            const avg = group.results.reduce((s, r) => s + r.result, 0) / group.results.length
            return (
              <Card key={`${group.year}-T${group.term}`}>
                <CardHeader className="pb-3">
                  <div className="flex items-center justify-between">
                    <CardTitle className="text-base font-semibold">
                      <GraduationCap className="w-4 h-4 inline mr-2" />
                      Year {group.year} — Term {group.term}
                    </CardTitle>
                    <div className="flex items-center gap-3">
                      <Badge variant="secondary" className="text-xs">
                        {group.results.length} subject{group.results.length !== 1 ? 's' : ''}
                      </Badge>
                      <span className="text-sm font-bold" style={{ color: BRAND.colors.primaryDark }}>
                        Avg: {avg.toFixed(1)}%
                      </span>
                    </div>
                  </div>
                </CardHeader>
                <CardContent>
                  <Table>
                    <TableHeader>
                      <TableRow>
                        <TableHead>Subject</TableHead>
                        <TableHead className="text-center">Result</TableHead>
                        <TableHead className="text-center">Term Change</TableHead>
                        <TableHead className="text-center w-16">Level</TableHead>
                      </TableRow>
                    </TableHeader>
                    <TableBody>
                      {group.results
                        .sort((a, b) => b.result - a.result)
                        .map((r) => {
                          const prev = getPreviousResult(r.subject, r.year, r.term)
                          const trend = getTrend(r.result, prev)
                          let level = 'Fail'
                          if (r.result >= 80) level = 'Outstanding'
                          else if (r.result >= 60) level = 'Meritorious'
                          else if (r.result >= 50) level = 'Substantial'
                          else if (r.result >= 40) level = 'Adequate'

                          return (
                            <TableRow key={r.id}>
                              <TableCell className="font-medium text-sm">{r.subject}</TableCell>
                              <TableCell className="text-center">
                                <span className={`inline-flex items-center justify-center w-14 h-7 rounded-full text-sm font-bold ${getResultColor(r.result)}`}>
                                  {r.result}%
                                </span>
                              </TableCell>
                              <TableCell className="text-center">
                                <TrendIcon direction={trend.direction} change={trend.change} />
                              </TableCell>
                              <TableCell className="text-center">
                                <span className={`text-[10px] font-medium px-2 py-0.5 rounded-full ${getResultColor(r.result)}`}>
                                  {level}
                                </span>
                              </TableCell>
                            </TableRow>
                          )
                        })}
                    </TableBody>
                  </Table>
                </CardContent>
              </Card>
            )
          })}
        </div>
      )}

      {/* Add Result Dialog */}
      <Dialog open={showForm} onOpenChange={setShowForm}>
        <DialogContent className="sm:max-w-md">
          <DialogHeader>
            <DialogTitle>Add Academic Result</DialogTitle>
          </DialogHeader>
          <div className="space-y-4">
            <div className="grid grid-cols-2 gap-4">
              <div>
                <Label className="text-sm font-medium">Year</Label>
                <Select value={formYear} onValueChange={setFormYear}>
                  <SelectTrigger className="mt-1 rounded-lg">
                    <SelectValue placeholder="Year" />
                  </SelectTrigger>
                  <SelectContent>
                    {[currentYear, currentYear - 1, currentYear - 2, currentYear - 3, currentYear - 4].map((y) => (
                      <SelectItem key={y} value={y.toString()}>{y}</SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
              <div>
                <Label className="text-sm font-medium">Term</Label>
                <Select value={formTerm} onValueChange={setFormTerm}>
                  <SelectTrigger className="mt-1 rounded-lg">
                    <SelectValue placeholder="Term" />
                  </SelectTrigger>
                  <SelectContent>
                    {[1, 2, 3, 4].map((t) => (
                      <SelectItem key={t} value={t.toString()}>Term {t}</SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
            </div>

            <div>
              <Label className="text-sm font-medium">Subject</Label>
              <Select value={formSubject} onValueChange={setFormSubject}>
                <SelectTrigger className="mt-1 rounded-lg">
                  <SelectValue placeholder="Select a subject" />
                </SelectTrigger>
                <SelectContent>
                  {BRAND.saSubjects.map((s) => (
                    <SelectItem key={s} value={s}>{s}</SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>

            <div>
              <Label className="text-sm font-medium">Result (%)</Label>
              <Input
                type="number"
                min="0"
                max="100"
                value={formResult}
                onChange={(e) => setFormResult(e.target.value)}
                placeholder="Enter percentage (0-100)"
                className="mt-1 rounded-lg"
              />
            </div>
          </div>

          <DialogFooter className="gap-2">
            <Button variant="outline" onClick={() => setShowForm(false)} className="rounded-lg">
              Cancel
            </Button>
            <Button
              onClick={handleSubmit}
              disabled={!formTerm || !formSubject || !formResult || saving}
              className="rounded-lg text-white"
              style={{ background: BRAND.colors.primaryGradient }}
            >
              {saving ? <Loader2 className="w-4 h-4 mr-2 animate-spin" /> : null}
              Save Result
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  )
}
