"use client"

import React, { useState, useMemo, useEffect, useCallback, memo, useRef } from "react"
import {
  Lock,
  Globe,
  RefreshCw,
  Zap,
  Gauge,
  FolderGit2,
  BookOpen,
  CalendarDays,
  ChevronDown,
} from "lucide-react"
import { getDashboardData, RepositoryWithUsage } from "./action"
import { getUserIdAndUsername } from "@/app/utils/auth"
import { format, subDays } from "date-fns"
import { ActiveUsersLeaderboard } from "@/components/dashboard/ActiveUsersLeaderboard"
import { CompactPullRequestActivityCard } from "@/components/dashboard/CompactPullRequestActivityCard"
import { DashboardErrorBoundary } from "@/components/dashboard/DashboardErrorBoundary"
import { MetricCard } from "@/components/dashboard/MetricCard"
import { OptimizationPRsTable } from "@/components/dashboard/OptimizationPRsTable"
import { DashboardSkeleton } from "@/components/dashboard/DashboardSkeleton"
import { useViewMode } from "../app/ViewModeContext"
import { useOutsideClick } from "@/components/hooks/useOutsideClick"
import { AccountPayload } from "@codeflash-ai/common"

const ErrorDisplay = memo(({ error, onRetry }: { error: string; onRetry: () => void }) => (
  <div className="flex justify-center items-center h-[70vh]">
    <div className="bg-red-50 text-red-800 p-6 sm:p-8 rounded-xl max-w-md border border-red-200">
      <h3 className="text-base sm:text-lg font-medium mb-2 sm:mb-3">Unable to Load Dashboard</h3>
      <p className="mb-3 sm:mb-4 text-sm sm:text-base">{error}</p>
      <button
        onClick={onRetry}
        className="flex items-center gap-1 sm:gap-2 w-full justify-center px-3 sm:px-4 py-2 sm:py-2.5 bg-red-100 hover:bg-red-200 text-red-800 rounded-lg text-xs sm:text-sm font-medium transition-colors"
      >
        <RefreshCw size={14} className="sm:w-4 sm:h-4" /> Try Again
      </button>
    </div>
  </div>
))
ErrorDisplay.displayName = "ErrorDisplay"

interface OptimizationStats {
  totalAttempts: number
  successfulAttempts: number
  activeReposLast30Days: number
}

interface PrActivityData {
  month: string
  pr_created: number
  pr_merged: number
  pr_closed: number
}

interface ActiveUserData {
  username: string
  eventCount: number
  avatarUrl: string
}

function Dashboard() {
  const { currentOrg } = useViewMode()
  const currentYear = new Date().getFullYear()

  const [repositories, setRepositories] = useState<RepositoryWithUsage[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)

  const [optimizationStats, setOptimizationStats] = useState<OptimizationStats>({
    totalAttempts: 0,
    successfulAttempts: 0,
    activeReposLast30Days: 0,
  })

  const [prActivityData, setPrActivityData] = useState<PrActivityData[]>([])
  const [selectedYear, setSelectedYear] = useState<number>(currentYear)
  const [isYearDropdownOpen, setIsYearDropdownOpen] = useState(false)
  const yearDropdownRef = useOutsideClick(() => setIsYearDropdownOpen(false))

  const [activeUsersData, setActiveUsersData] = useState<ActiveUserData[]>([])
  const [optimizationsTrend, setOptimizationsTrend] = useState<number[]>([])
  const [optimizationsTrendDates, setOptimizationsTrendDates] = useState<string[]>([])
  const [successfulOptimizationsTrend, setSuccessfulOptimizationsTrend] = useState<number[]>([])
  const [successfulOptimizationsTrendDates, setSuccessfulOptimizationsTrendDates] = useState<
    string[]
  >([])
  const [accountPayload, setAccountPayload] = useState<AccountPayload | null>(null)

  const [isMobile, setIsMobile] = useState<boolean>(false)

  const dateValues = useMemo(() => {
    const now = new Date()
    const last30DaysStart = subDays(now, 30)
    const startMonth = format(last30DaysStart, "MMMM")
    const endMonth = format(now, "MMMM")
    const startYear = format(last30DaysStart, "yyyy")
    const endYear = format(now, "yyyy")

    function getDateRangeDisplay(): string {
      if (startMonth === endMonth && startYear === endYear) {
        return `${startMonth} ${format(last30DaysStart, "d")}-${format(now, "d")}, ${startYear}`
      }
      if (startYear === endYear) {
        return `${format(last30DaysStart, "MMMM d")} - ${format(now, "MMMM d")}, ${startYear}`
      }
      return `${format(last30DaysStart, "MMMM d, yyyy")} - ${format(now, "MMMM d, yyyy")}`
    }

    return { now, last30DaysStart, dateRangeDisplay: getDateRangeDisplay() }
  }, [])

  const repoCounts = useMemo(() => {
    if (!Array.isArray(repositories) || repositories.length === 0) {
      return { privateRepos: 0, publicRepos: 0, totalRepos: 0 }
    }
    const privateRepos = repositories.filter(repo => repo?.is_private).length
    const publicRepos = repositories.length - privateRepos
    return { privateRepos, publicRepos, totalRepos: repositories.length }
  }, [repositories])

  const availableYears = useMemo(() => {
    const baseYear = 2025
    return Array.from(
      { length: Math.max(1, currentYear - baseYear + 1) },
      (_, i) => baseYear + i,
    ).filter(year => year <= currentYear)
  }, [currentYear])

  useEffect(() => {
    let timeoutId: NodeJS.Timeout
    const handleResize = () => {
      clearTimeout(timeoutId)
      timeoutId = setTimeout(() => setIsMobile(window.innerWidth < 640), 150)
    }

    if (typeof window !== "undefined") {
      setIsMobile(window.innerWidth < 640)
      window.addEventListener("resize", handleResize)
      return () => {
        clearTimeout(timeoutId)
        window.removeEventListener("resize", handleResize)
      }
    }
  }, [])

  const currentOrgId = currentOrg?.id
  const fetchingRef = useRef(false)

  const fetchDashboardData = useCallback(async () => {
    if (fetchingRef.current) return
    fetchingRef.current = true

    try {
      setLoading(true)
      setError(null)

      const currentUser = await getUserIdAndUsername()
      if (!currentUser?.userId || !currentUser?.username) {
        throw new Error("User authentication data not found")
      }

      const payload: AccountPayload = currentOrgId
        ? { orgId: currentOrgId }
        : { userId: currentUser.userId, username: currentUser.username }

      // Store payload for the PR table component
      setAccountPayload(payload)

      const { stats, repos } = await getDashboardData(payload, selectedYear)

      setRepositories(Array.isArray(repos) ? repos : [])

      setOptimizationStats({
        totalAttempts: stats.optimizations.total,
        successfulAttempts: stats.optimizations.successful,
        activeReposLast30Days: stats.activeReposLast30Days.length,
      })

      const optimizationValues = stats.optimizations.timeSeries.map(item => item.count)
      const optimizationDates = stats.optimizations.timeSeries.map(item => item.date)
      setOptimizationsTrend(optimizationValues)
      setOptimizationsTrendDates(optimizationDates)

      const successfulValues = stats.optimizations.successfulTimeSeries.map(item => item.count)
      const successfulDates = stats.optimizations.successfulTimeSeries.map(item => item.date)
      setSuccessfulOptimizationsTrend(successfulValues)
      setSuccessfulOptimizationsTrendDates(successfulDates)

      setPrActivityData(stats.pullRequests)
      setActiveUsersData(stats.activeUsersLast30Days)
    } catch (err) {
      console.error("Dashboard data fetch error:", err)
      setError("Failed to load dashboard data. Please try again later.")
      setRepositories([])
      setPrActivityData([])
      setActiveUsersData([])
      setOptimizationsTrend([])
      setOptimizationsTrendDates([])
      setSuccessfulOptimizationsTrend([])
      setSuccessfulOptimizationsTrendDates([])
    } finally {
      setLoading(false)
      fetchingRef.current = false
    }
  }, [selectedYear, currentOrgId])

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

  const handleYearChange = useCallback((year: number) => {
    setSelectedYear(year)
    setIsYearDropdownOpen(false)
  }, [])

  if (loading) return <DashboardSkeleton />
  if (error) return <ErrorDisplay error={error} onRetry={fetchDashboardData} />

  return (
    <div className="min-h-screen pb-8 py-6 sm:py-8 px-4 sm:px-6 max-w-[1400px] mx-auto">
      <div className="mb-6 sm:mb-8">
        <div className="flex items-center justify-between mb-2">
          <h1 className="text-xl sm:text-2xl font-bold">Dashboard</h1>

          <div className="relative" ref={yearDropdownRef}>
            <button
              onClick={() => setIsYearDropdownOpen(!isYearDropdownOpen)}
              className="flex items-center gap-1 px-2 py-1 text-xs bg-background border border-border rounded-md hover:border-primary/50 transition-colors"
              disabled={availableYears.length <= 1}
            >
              <CalendarDays size={12} className="text-muted-foreground" />
              <span>{selectedYear}</span>
              {availableYears.length > 1 && (
                <ChevronDown
                  size={12}
                  className={`transition-transform text-muted-foreground ${isYearDropdownOpen ? "rotate-180" : ""}`}
                />
              )}
            </button>

            {isYearDropdownOpen && availableYears.length > 1 && (
              <div className="absolute right-0 z-10 mt-1 w-32 bg-card rounded-md shadow-lg overflow-hidden border border-border animate-in fade-in-50 slide-in-from-top-5">
                <div className="py-1">
                  {availableYears.map(year => (
                    <button
                      key={year}
                      onClick={() => handleYearChange(year)}
                      className={`w-full px-3 py-1.5 text-left hover:bg-muted flex items-center ${selectedYear === year ? "bg-primary/10 text-primary font-medium" : ""}`}
                    >
                      <span className="w-4 h-4 mr-1.5 flex items-center justify-center">
                        {selectedYear === year && (
                          <span className="w-1.5 h-1.5 rounded-full bg-primary"></span>
                        )}
                      </span>
                      {year}
                    </button>
                  ))}
                </div>
              </div>
            )}
          </div>
        </div>
      </div>

      {repoCounts.totalRepos === 0 && (
        <div className="mb-6 sm:mb-8">
          <div className="rounded-xl border border-dashed border-border bg-muted/10 px-5 py-4 sm:px-6 sm:py-5 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3">
            <div>
              <h2 className="text-sm sm:text-base font-semibold text-foreground">
                Connect a repository to unlock insights
              </h2>
              <p className="text-xs sm:text-sm text-muted-foreground max-w-xl">
                Install the Codeflash GitHub App and grant access to at least one repository so we
                can populate your dashboard with optimization activity.
              </p>
            </div>
            <div className="flex flex-col sm:flex-row gap-2 sm:gap-3">
              <a
                href="https://github.com/apps/codeflash-ai/installations/select_target"
                target="_blank"
                rel="noopener noreferrer"
                className="inline-flex items-center justify-center rounded-lg bg-primary px-4 py-2 text-xs sm:text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors"
              >
                Install GitHub App
              </a>
              <a
                href="https://docs.codeflash.ai/getting-started/local-installation"
                target="_blank"
                rel="noopener noreferrer"
                className="inline-flex items-center justify-center rounded-lg border border-border px-4 py-2 text-xs sm:text-sm font-medium text-foreground hover:bg-muted/40 transition-colors"
              >
                View setup guide
              </a>
            </div>
          </div>
        </div>
      )}

      {/* Optimization PRs Table - Positioned at the top */}
      {accountPayload && (
        <div className="mb-6 sm:mb-8">
          <OptimizationPRsTable payload={accountPayload} />
        </div>
      )}

      <div className="grid grid-cols-1 gap-3 sm:gap-5 mb-6 sm:mb-8">
        <div className="grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-5">
          <MetricCard
            title="Optimization Attempts"
            value={optimizationStats.totalAttempts}
            icon={<Zap size={isMobile ? 16 : 20} />}
            gradientFrom="bg-gradient-to-br from-blue-500/20"
            gradientTo="to-blue-600/20"
            iconColor="text-blue-500"
            chartData={optimizationsTrend}
            chartDates={optimizationsTrendDates}
            chartColor="rgba(59, 130, 246, 1)"
            chartFillColor="rgba(59, 130, 246, 0.2)"
            timeText={`Year ${selectedYear}`}
            emptyStateMessage="No data"
            cumulativeChart={true}
          />
          <MetricCard
            title="Optimizations Found"
            value={optimizationStats.successfulAttempts}
            subtitle=""
            icon={<Gauge size={isMobile ? 16 : 20} />}
            gradientFrom="bg-gradient-to-br from-emerald-500/20"
            gradientTo="to-emerald-600/20"
            iconColor="text-emerald-500"
            chartData={successfulOptimizationsTrend}
            chartDates={successfulOptimizationsTrendDates}
            chartColor="rgba(16, 185, 129, 1)"
            chartFillColor="rgba(16, 185, 129, 0.2)"
            emptyStateMessage="No data"
            timeText={`Year ${selectedYear}`}
            cumulativeChart={true}
            showChart={successfulOptimizationsTrend.length > 0}
          />
        </div>

        <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-3 sm:gap-5">
          <MetricCard
            title="Total Repositories"
            value={repoCounts.totalRepos}
            icon={<BookOpen size={isMobile ? 16 : 20} />}
            gradientFrom="bg-gradient-to-br from-blue-500/20"
            gradientTo="to-blue-600/20"
            iconColor="text-blue-500"
            timeText=""
            showChart={false}
          />

          <MetricCard
            title="Active Repositories"
            value={optimizationStats.activeReposLast30Days}
            subtitle="last 30 days"
            icon={<FolderGit2 size={isMobile ? 16 : 20} />}
            gradientFrom="bg-gradient-to-br from-purple-500/20"
            gradientTo="to-purple-600/20"
            iconColor="text-purple-500"
            timeText={dateValues.dateRangeDisplay}
            showChart={false}
          />

          <MetricCard
            title="Private Repositories"
            value={repoCounts.privateRepos}
            icon={<Lock size={isMobile ? 16 : 20} />}
            gradientFrom="bg-gradient-to-br from-amber-500/20"
            gradientTo="to-amber-600/20"
            iconColor="text-amber-500"
            timeText=""
            showChart={false}
          />

          <MetricCard
            title="Public Repositories"
            value={repoCounts.publicRepos}
            icon={<Globe size={isMobile ? 16 : 20} />}
            gradientFrom="bg-gradient-to-br from-violet-500/20"
            gradientTo="to-violet-600/20"
            iconColor="text-violet-500"
            timeText=""
            showChart={false}
          />
        </div>
      </div>

      <div className="grid grid-cols-1 md:grid-cols-2 gap-3 sm:gap-5 mb-6 sm:mb-8 h-96 md:h-[500px]">
        <CompactPullRequestActivityCard
          prData={prActivityData}
          selectedYear={selectedYear}
          onYearChange={handleYearChange}
          className="h-full"
        />

        <div className="h-full">
          <ActiveUsersLeaderboard leaderboardData={activeUsersData} />
        </div>
      </div>
    </div>
  )
}

const MemoizedDashboard = memo(Dashboard)
MemoizedDashboard.displayName = "Dashboard"

export default function DashboardWrapper() {
  return (
    <DashboardErrorBoundary>
      <MemoizedDashboard />
    </DashboardErrorBoundary>
  )
}
