import { useEffect, useMemo, useState } from 'react';
import { motion, AnimatePresence } from 'motion/react';
import { codingQuestions, type CodingQuestion } from '@/data/codingQuestions';
import { fetchDSAQuestions } from '@/lib/dsaQuestionsClient';
import { getQuestionReward } from '@/lib/codingProgress';
import type { ProgressLeaderboardEntry } from '@/lib/authClient';
import { cn } from '@/lib/utils';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { useSubscription } from '@/contexts/SubscriptionContext';
import ProgressHeader from './ProgressHeader';
import {
  ArrowLeft,
  BookOpen,
  CheckCircle2,
  ChevronLeft,
  ChevronRight,
  Circle,
  Code2,
  Coins,
  Filter,
  FolderOpen,
  Layers,
  Search,
  Terminal,
  Trophy,
  Zap, Lock
} from 'lucide-react';
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';

interface CodingSectionProps {
  onSelectQuestion: (question: CodingQuestion, mode: 'code' | 'solution') => void;
  solvedQuestionIds: string[];
  solvedCount?: number;
  userId?: string;
  leaderboard?: ProgressLeaderboardEntry[];
  onViewFullLeaderboard?: () => void;
}

const BLIND_56_DATA: Record<string, string[]> = {
  Array: ['Pair Sum Target', 'Optimal Stock Trading', 'Duplicate Finder', 'Array Product Exclusion', 'Maximum Sum Segment', 'Maximum Product Subarray', 'Find Minimum in Rotated Sorted Array', 'Search in Rotated Sorted Array'],
  Binary: ['Sum of Two Integers', 'Number of 1 Bits', 'Counting Bits', 'Missing Number', 'Reverse Bits'],
  DP: ['Climbing Stairs', 'Coin Change II', 'Longest Increasing Subsequence', 'Longest Common Subsequence', 'Word Break', 'Combination Sum', 'Maximum Sum of Non-Adjacent Elements', 'House Robber', 'Decode Ways'],
  Graph: ['Clone Graph', 'Course Schedule I', 'Pacific Atlantic Water Flow', 'Number of Islands', 'Longest Consecutive Sequence', 'Alien Dictionary', 'Graph Valid Tree'],
  Interval: ['Insert Interval', 'Merge Intervals', 'Non-overlapping Intervals', 'Repeating and Missing Number'],
  'Linked List': ['Reverse a Linked List', 'Detect a Loop in Linked List', 'Merge Two Sorted Lists', 'Merge K Sorted Lists', 'Remove Nth Node From End of List'],
  Matrix: ['Set Matrix Zeroes', 'Spiral Matrix', 'Rotate Image'],
  Tree: ['Maximum Depth in BT', 'Check if two trees are identical', 'Invert/Flip Binary Tree', 'Maximum Path Sum', 'Level Order Traversal', 'Serialize and De-serialize BT'],
  String: ['Longest Substring Without Repeating Characters', 'Longest Repeating Character Replacement', 'Minimum Window Substring', 'Valid Anagram', 'Group Words by Anagrams', 'Balanced Paranthesis', 'Palindrome Number', 'Longest Palindromic Substring', 'Palindromic Substrings'],
};

type SheetCategory = {
  name: string;
  count: number;
  completedCount: number;
  progress: number;
};

const COMPANY_DOMAINS: Record<string, string> = {
  accenture: 'accenture.com',
  adobe: 'adobe.com',
  airbnb: 'airbnb.com',
  amazon: 'amazon.com',
  apple: 'apple.com',
  atlassian: 'atlassian.com',
  baidu: 'baidu.com',
  bloomberg: 'bloomberg.com',
  bookingcom: 'booking.com',
  bytedance: 'bytedance.com',
  capgemini: 'capgemini.com',
  cisco: 'cisco.com',
  citadel: 'citadel.com',
  citrix: 'citrix.com',
  codeforces: 'codeforces.com',
  codesignal: 'codesignal.com',
  coursera: 'coursera.org',
  cred: 'cred.club',
  databricks: 'databricks.com',
  dhl: 'dhl.com',
  directi: 'directi.com',
  doordash: 'doordash.com',
  dropbox: 'dropbox.com',
  expedia: 'expedia.com',
  facebook: 'facebook.com',
  flipkart: 'flipkart.com',
  freshworks: 'freshworks.com',
  goldmansachs: 'goldmansachs.com',
  google: 'google.com',
  grab: 'grab.com',
  hackerrank: 'hackerrank.com',
  hcl: 'hcltech.com',
  ibm: 'ibm.com',
  infosys: 'infosys.com',
  intuit: 'intuit.com',
  janestreet: 'janestreet.com',
  jio: 'jio.com',
  jpmorgan: 'jpmorgan.com',
  juspay: 'juspay.in',
  leetcode: 'leetcode.com',
  linkedin: 'linkedin.com',
  lyft: 'lyft.com',
  meta: 'meta.com',
  microsoft: 'microsoft.com',
  mindtree: 'ltimindtree.com',
  morganstanley: 'morganstanley.com',
  netflix: 'netflix.com',
  nvidia: 'nvidia.com',
  ola: 'olacabs.com',
  oracle: 'oracle.com',
  palantir: 'palantir.com',
  paypal: 'paypal.com',
  paytm: 'paytm.com',
  pinterest: 'pinterest.com',
  qualcomm: 'qualcomm.com',
  quora: 'quora.com',
  razorpay: 'razorpay.com',
  robinhood: 'robinhood.com',
  salesforce: 'salesforce.com',
  samsung: 'samsung.com',
  sap: 'sap.com',
  shopee: 'shopee.com',
  shopify: 'shopify.com',
  snap: 'snap.com',
  snapchat: 'snapchat.com',
  snapdeal: 'snapdeal.com',
  spotify: 'spotify.com',
  stripe: 'stripe.com',
  swiggy: 'swiggy.com',
  tcs: 'tcs.com',
  tomtom: 'tomtom.com',
  twitch: 'twitch.tv',
  twitter: 'twitter.com',
  uber: 'uber.com',
  walmart: 'walmart.com',
  wipro: 'wipro.com',
  yahoo: 'yahoo.com',
  yelp: 'yelp.com',
  zenefits: 'zenefits.com',
  zillow: 'zillow.com',
  zoho: 'zoho.com',
};

const COMPANY_ICON_SLUGS: Record<string, string> = {
  adobe: 'adobe',
  airbnb: 'airbnb',
  amazon: 'amazon',
  apple: 'apple',
  atlassian: 'atlassian',
  baidu: 'baidu',
  bookingcom: 'bookingdotcom',
  bytedance: 'bytedance',
  cisco: 'cisco',
  codeforces: 'codeforces',
  coursera: 'coursera',
  databricks: 'databricks',
  dhl: 'dhl',
  doordash: 'doordash',
  dropbox: 'dropbox',
  expedia: 'expedia',
  facebook: 'facebook',
  flipkart: 'flipkart',
  freshworks: 'freshworks',
  google: 'google',
  hackerrank: 'hackerrank',
  ibm: 'ibm',
  infosys: 'infosys',
  intuit: 'intuit',
  leetcode: 'leetcode',
  linkedin: 'linkedin',
  lyft: 'lyft',
  meta: 'meta',
  microsoft: 'microsoft',
  netflix: 'netflix',
  nvidia: 'nvidia',
  oracle: 'oracle',
  paypal: 'paypal',
  pinterest: 'pinterest',
  qualcomm: 'qualcomm',
  quora: 'quora',
  robinhood: 'robinhood',
  salesforce: 'salesforce',
  samsung: 'samsung',
  sap: 'sap',
  shopify: 'shopify',
  snapchat: 'snapchat',
  spotify: 'spotify',
  stripe: 'stripe',
  twitch: 'twitch',
  twitter: 'x',
  uber: 'uber',
  walmart: 'walmart',
  wipro: 'wipro',
  yahoo: 'yahoo',
  yelp: 'yelp',
  zillow: 'zillow',
  zoho: 'zoho',
};

const COMPANY_LOGO_OVERRIDES: Record<string, string[]> = {
  apple: [
    'https://cdn.simpleicons.org/apple/white',
  ],
  google: [
    'https://www.google.com/images/branding/googleg/1x/googleg_standard_color_128dp.png',
  ],
  ibm: [
    '/images/ibm-white.svg',
  ],
  ola: [
    'https://cdn.simpleicons.org/olacabs/white',
  ],
  paytm: [
    'https://upload.wikimedia.org/wikipedia/commons/2/24/Paytm_Logo_%28standalone%29.svg',
  ],
  samsung: [
    'https://cdn.simpleicons.org/samsung/white',
  ],
  uber: [
    'https://cdn.simpleicons.org/uber/white',
  ],
  wipro: [
    'https://cdn.simpleicons.org/wipro/white',
  ],
};

export default function CodingSection({
  onSelectQuestion,
  solvedQuestionIds,
  solvedCount = 0,
  userId = '',
  leaderboard = [],
  onViewFullLeaderboard,
}: CodingSectionProps) {
  const [searchQuery, setSearchQuery] = useState('');
  const [currentPage, setCurrentPage] = useState(1);
  const ITEMS_PER_PAGE = 30;
  const [selectedForDialog, setSelectedForDialog] = useState<CodingQuestion | null>(null);
  const [selectedSheet, setSelectedSheet] = useState<string | null>(null);
  const [showSheets, setShowSheets] = useState(false);
  const [sheetContext, setSheetContext] = useState<'all' | 'blind56' | 'rypquest'>('all');
  const [questions, setQuestions] = useState<CodingQuestion[]>([]);
  const [isLoadingQuestions, setIsLoadingQuestions] = useState(true);
  const [questionsError, setQuestionsError] = useState<string | null>(null);

  const solvedSet = useMemo(() => new Set(solvedQuestionIds), [solvedQuestionIds]);

  useEffect(() => {
    let cancelled = false;

    async function loadQuestions() {
      setIsLoadingQuestions(true);
      setQuestionsError(null);

      try {
        const mongoQuestions = await fetchDSAQuestions();
        if (cancelled) return;

        setQuestions(mongoQuestions.length > 0 ? mongoQuestions : codingQuestions);
        if (mongoQuestions.length === 0) {
          setQuestionsError('MongoDB returned no DSA questions, so local fallback data is shown.');
        }
      } catch (error) {
        if (cancelled) return;

        console.error('Failed to load DSA questions from MongoDB:', error);
        setQuestions(codingQuestions);
        setQuestionsError(error instanceof Error ? error.message : 'Failed to load DSA questions from MongoDB.');
      } finally {
        if (!cancelled) {
          setIsLoadingQuestions(false);
        }
      }
    }

    loadQuestions();

    return () => {
      cancelled = true;
    };
  }, []);

  const categories = useMemo<SheetCategory[]>(() => {
    if (sheetContext === 'blind56') {
      return Object.entries(BLIND_56_DATA).map(([name, titles]) => {
        const questionsInCategory = questions.filter((question) =>
          titles.some((title) => matchesBlind56Question(question, title)),
        );
        const completedCount = questionsInCategory.filter((question) => solvedSet.has(question.id)).length;

        return {
          name,
          count: questionsInCategory.length,
          completedCount,
          progress: questionsInCategory.length > 0 ? (completedCount / questionsInCategory.length) * 100 : 0,
        };
      });
    }

    return Array.from(new Set(questions.map((question) => question.category))).map((category) => {
      const questionsInCategory = questions.filter((question) => question.category === category);
      const completedCount = questionsInCategory.filter((question) => solvedSet.has(question.id)).length;

      return {
        name: category,
        count: questionsInCategory.length,
        completedCount,
        progress: questionsInCategory.length > 0 ? (completedCount / questionsInCategory.length) * 100 : 0,
      };
    });
  }, [questions, sheetContext, solvedSet]);

  const rootQuestions = useMemo(() => {
    const normalizedSearch = searchQuery.toLowerCase();

    return questions.filter((question) => (
      question.title.toLowerCase().includes(normalizedSearch) ||
      question.category.toLowerCase().includes(normalizedSearch) ||
      question.difficulty.toLowerCase().includes(normalizedSearch) ||
      (question.companies ?? []).some((company) => company.toLowerCase().includes(normalizedSearch))
    ));
  }, [questions, searchQuery]);

  const filteredQuestions = useMemo(() => {
    return questions.filter((question) => {
      const matchesSearch =
        question.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
        question.category.toLowerCase().includes(searchQuery.toLowerCase()) ||
        (question.companies ?? []).some((company) => company.toLowerCase().includes(searchQuery.toLowerCase()));

      if (!matchesSearch) {
        return false;
      }

      if (selectedSheet) {
        if (sheetContext === 'blind56') {
          const titles = BLIND_56_DATA[selectedSheet] || [];
          return titles.some((title) => matchesBlind56Question(question, title));
        }

        return question.category === selectedSheet;
      }

      if (sheetContext === 'blind56') {
        const blind56Titles = Object.values(BLIND_56_DATA).flat();
        return blind56Titles.some((title) => matchesBlind56Question(question, title));
      }

      return true;
    });
  }, [questions, searchQuery, selectedSheet, sheetContext]);

  const progressStats = useMemo(() => {
    const easyQuestions = filteredQuestions.filter((question) => question.difficulty === 'Easy');
    const mediumQuestions = filteredQuestions.filter((question) => question.difficulty === 'Medium');
    const hardQuestions = filteredQuestions.filter((question) => question.difficulty === 'Hard');

    return {
      totalQuestions: filteredQuestions.length,
      totalSolved: filteredQuestions.filter((question) => solvedSet.has(question.id)).length,
      categories: [
        {
          label: 'EASY',
          solved: easyQuestions.filter((question) => solvedSet.has(question.id)).length,
          total: easyQuestions.length,
          color: 'text-emerald-400',
          barColor: 'bg-emerald-500',
          chartColor: '#10b981',
        },
        {
          label: 'MED.',
          solved: mediumQuestions.filter((question) => solvedSet.has(question.id)).length,
          total: mediumQuestions.length,
          color: 'text-amber-400',
          barColor: 'bg-amber-500',
          chartColor: '#f59e0b',
        },
        {
          label: 'HARD',
          solved: hardQuestions.filter((question) => solvedSet.has(question.id)).length,
          total: hardQuestions.length,
          color: 'text-rose-400',
          barColor: 'bg-rose-500',
          chartColor: '#ef4444',
        },
      ],
    };
  }, [filteredQuestions, solvedSet]);

  const leaderboardEntries = leaderboard;
  const visibleEntries = useMemo(() => leaderboardEntries.slice(0, 3), [leaderboardEntries]);
  const currentUserEntry = leaderboardEntries.find((entry) => entry.id === userId) || leaderboardEntries.find((entry) => entry.isCurrentUser);
  const leaderboardRank = currentUserEntry?.rank ?? leaderboardEntries.length + 1;
  const leaderboardGap = useMemo(() => {
    const currentIndex = leaderboardEntries.findIndex((entry) => entry.id === userId || entry.isCurrentUser);
    if (currentIndex <= 0) return 0;
    return Math.max(0, leaderboardEntries[currentIndex - 1].score - leaderboardEntries[currentIndex].score + 1);
  }, [leaderboardEntries, userId]);

  const codingSolvedIds = useMemo(() => solvedQuestionIds.filter(id => !id.startsWith('sd-') && !id.startsWith('cs-') && !id.startsWith('apt-')), [solvedQuestionIds]);
  const recordedSolvedCount = Math.max(solvedCount, codingSolvedIds.length);

  return (
    <div className="mx-auto w-full max-w-[1400px] pb-12">

      {/* MAIN GRID: Content + Sidebar */}
      <div className="grid grid-cols-1 xl:grid-cols-[1fr_340px] gap-6 xl:gap-8 items-start">
        <div className="space-y-6 min-h-0">
          {/* Header */}
          <div className="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
            <div className="flex items-center gap-3">
              {showSheets || selectedSheet ? (
                <Button
                  variant="ghost"
                  size="icon"
                  onClick={() => {
                    if (selectedSheet) {
                      setSelectedSheet(null);
                    } else {
                      setShowSheets(false);
                    }
                    setCurrentPage(1);
                  }}
                  className="mr-2 h-12 w-12 text-zinc-400 hover:bg-white/5 hover:text-white"
                >
                  <ArrowLeft size={24} />
                </Button>
              ) : (
                <div className="flex h-12 w-12 items-center justify-center rounded-2xl border border-cyan-500/20 bg-cyan-500/10 text-cyan-400">
                  <Code2 size={24} />
                </div>
              )}
              <div>
                <h2 className="text-2xl font-black tracking-tight text-white">
                  {!showSheets
                    ? 'Coding Hub'
                    : selectedSheet
                      ? selectedSheet
                      : sheetContext === 'all'
                        ? 'All Questions'
                        : sheetContext === 'blind56'
                          ? 'Blind 56 Sheets'
                          : 'RYP Quest Sheet'}
                </h2>
              </div>
            </div>
            <div className="flex items-center gap-3">
              <div className="relative group">
                <Search className="absolute left-3 top-1/2 -translate-y-1/2 text-zinc-600 transition-colors group-focus-within:text-cyan-400" size={18} />
                <input
                  type="text"
                  placeholder="Search problems..."
                  value={searchQuery}
                  onChange={(event) => { setSearchQuery(event.target.value); setCurrentPage(1); }}
                  className="w-full rounded-xl border border-zinc-800/80 bg-[#111] py-2.5 pl-10 pr-4 text-sm text-zinc-200 transition-all focus:border-cyan-500/50 focus:outline-none focus:ring-2 focus:ring-cyan-500/10 md:w-72 placeholder:text-zinc-600"
                />
              </div>
              <Button variant="outline" size="icon" className="border-zinc-800/80 bg-[#111] text-zinc-500 hover:text-cyan-400 hover:border-cyan-500/30">
                <Filter size={18} />
              </Button>
            </div>
          </div>

          {questionsError && (
            <div className="rounded-2xl border border-amber-500/20 bg-amber-500/5 px-4 py-3 text-xs font-semibold text-amber-300">
              {questionsError}
            </div>
          )}

          <AnimatePresence mode="wait">
            {!showSheets ? (
              <motion.div
                key="root"
                initial={{ opacity: 0, y: 20 }}
                animate={{ opacity: 1, y: 0 }}
                exit={{ opacity: 0, scale: 0.95 }}
                className="grid grid-cols-1 gap-4 md:grid-cols-2"
              >
                <motion.div
                  whileHover={{ y: -4, scale: 1.01 }}
                  className="group relative cursor-pointer overflow-hidden rounded-2xl border border-teal-500/10 bg-[#0d0d0d] p-6 transition-all hover:border-teal-500/30"
                  onClick={() => {
                    setSheetContext('all');
                    setShowSheets(true);
                    setCurrentPage(1);
                  }}
                >
                  <div className="absolute -top-8 -right-8 h-28 w-28 rounded-full blur-3xl opacity-10 bg-teal-500 transition-opacity group-hover:opacity-20" />
                  <div className="absolute bottom-0 left-0 right-0 h-[2px] bg-gradient-to-r from-teal-400 to-cyan-500 opacity-0 transition-opacity group-hover:opacity-100" />
                  <div className="flex items-center gap-4">
                    <div className="flex h-14 w-14 shrink-0 items-center justify-center rounded-2xl bg-gradient-to-br from-teal-400/15 to-cyan-500/15 transition-transform group-hover:scale-110">
                      <FolderOpen size={28} className="text-teal-400" />
                    </div>
                    <div className="flex-1">
                      <h3 className="text-lg font-black text-white transition-colors group-hover:text-teal-400">All Questions</h3>
                      <p className="text-xs text-zinc-600 font-semibold mt-0.5">
                        {isLoadingQuestions ? 'Loading from MongoDB...' : `${questions.length} problems · All categories`}
                      </p>
                    </div>
                    <ChevronRight size={20} className="text-zinc-700 transition-all group-hover:text-teal-400 group-hover:translate-x-1" />
                  </div>
                </motion.div>

                <motion.div
                  whileHover={{ y: -4, scale: 1.01 }}
                  className="group relative cursor-pointer overflow-hidden rounded-2xl border border-violet-500/10 bg-[#0d0d0d] p-6 transition-all hover:border-violet-500/30"
                  onClick={() => {
                    setSheetContext('blind56');
                    setShowSheets(true);
                    setSelectedSheet(null);
                    setCurrentPage(1);
                  }}
                >
                  <div className="absolute -top-8 -right-8 h-28 w-28 rounded-full blur-3xl opacity-10 bg-violet-500 transition-opacity group-hover:opacity-20" />
                  <div className="absolute bottom-0 left-0 right-0 h-[2px] bg-gradient-to-r from-violet-400 to-purple-600 opacity-0 transition-opacity group-hover:opacity-100" />
                  <div className="flex items-center gap-4">
                    <div className="flex h-14 w-14 shrink-0 items-center justify-center rounded-2xl bg-gradient-to-br from-violet-400/15 to-purple-600/15 transition-transform group-hover:scale-110">
                      <Zap size={28} className="text-violet-400" />
                    </div>
                    <div className="flex-1">
                      <h3 className="text-lg font-black text-white transition-colors group-hover:text-violet-400">Blind 56</h3>
                      <p className="text-xs text-zinc-600 font-semibold mt-0.5">Curated interview essentials</p>
                    </div>
                    <ChevronRight size={20} className="text-zinc-700 transition-all group-hover:text-violet-400 group-hover:translate-x-1" />
                  </div>
                </motion.div>

                <motion.div
                  whileHover={{ y: -4, scale: 1.01 }}
                  className="group relative cursor-pointer overflow-hidden rounded-2xl border border-amber-500/10 bg-[#0d0d0d] p-6 transition-all hover:border-amber-500/30"
                  onClick={() => {
                    setSheetContext('rypquest');
                    setShowSheets(true);
                    setSelectedSheet(null);
                    setCurrentPage(1);
                  }}
                >
                  <div className="absolute -top-8 -right-8 h-28 w-28 rounded-full blur-3xl opacity-10 bg-amber-500 transition-opacity group-hover:opacity-20" />
                  <div className="absolute bottom-0 left-0 right-0 h-[2px] bg-gradient-to-r from-amber-400 to-orange-500 opacity-0 transition-opacity group-hover:opacity-100" />
                  <div className="flex items-center gap-4">
                    <div className="flex h-14 w-14 shrink-0 items-center justify-center rounded-2xl bg-gradient-to-br from-amber-400/15 to-orange-500/15 transition-transform group-hover:scale-110">
                      <Trophy size={28} className="text-amber-400" />
                    </div>
                    <div className="flex-1">
                      <h3 className="text-lg font-black text-white transition-colors group-hover:text-amber-400">RYP Quest Sheet</h3>
                      <p className="text-xs text-zinc-600 font-semibold mt-0.5">Platform-curated problem set</p>
                    </div>
                    <ChevronRight size={20} className="text-zinc-700 transition-all group-hover:text-amber-400 group-hover:translate-x-1" />
                  </div>
                </motion.div>

                <motion.div
                  initial={{ opacity: 0, y: 12 }}
                  animate={{ opacity: 1, y: 0 }}
                  transition={{ duration: 0.35, delay: 0.08 }}
                  className="space-y-3 md:col-span-2"
                >
                  <div className="flex flex-wrap items-end justify-between gap-3 px-1">
                    <div>
                      <h3 className="text-lg font-black tracking-tight text-white">Problems</h3>
                      <p className="mt-0.5 text-xs font-semibold text-zinc-600">
                        {isLoadingQuestions ? 'Loading questions...' : `${rootQuestions.length} questions`}
                      </p>
                    </div>
                    <button
                      type="button"
                      onClick={() => {
                        setSheetContext('all');
                        setShowSheets(true);
                        setCurrentPage(1);
                      }}
                      className="inline-flex items-center gap-1.5 rounded-xl border border-cyan-500/20 bg-cyan-500/5 px-3 py-2 text-[10px] font-black uppercase tracking-wider text-cyan-400 transition-all hover:border-cyan-500/40 hover:bg-cyan-500/10"
                    >
                      View Sheets
                      <ChevronRight size={13} />
                    </button>
                  </div>
                  <QuestionTable
                    questions={rootQuestions}
                    solvedSet={solvedSet}
                    onOpenQuestion={setSelectedForDialog}
                    currentPage={currentPage}
                    onPageChange={setCurrentPage}
                    itemsPerPage={12}
                    emptyMessage={isLoadingQuestions ? 'Loading DSA questions...' : 'No DSA questions match this view.'}
                  />
                </motion.div>
              </motion.div>
            ) : sheetContext === 'all' && !selectedSheet ? (
              <motion.div
                key="sheets"
                initial={{ opacity: 0, y: 20 }}
                animate={{ opacity: 1, y: 0 }}
                exit={{ opacity: 0, y: -20 }}
                className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3"
              >
                {categories.map((category, index) => (
                  <motion.div
                    key={category.name}
                    initial={{ opacity: 0, y: 20 }}
                    animate={{ opacity: 1, y: 0 }}
                    transition={{ delay: index * 0.05 }}
                  >
                    <Card
                      className="group relative flex h-full cursor-pointer flex-col overflow-hidden border-zinc-800 bg-zinc-900/50 transition-all hover:border-emerald-500/50 hover:bg-zinc-900"
                      onClick={() => setSelectedSheet(category.name)}
                    >
                      <CardContent className="flex h-full flex-col p-8">
                        <div className="absolute right-0 top-0 p-8 text-emerald-500 opacity-5 transition-opacity group-hover:opacity-10">
                          <Layers size={100} />
                        </div>
                        <div className="mb-6 flex items-start justify-between">
                          <div className="flex h-14 w-14 items-center justify-center rounded-2xl bg-emerald-500/10 text-emerald-400 transition-transform group-hover:scale-110 group-hover:bg-emerald-500/20">
                            <Layers size={28} />
                          </div>
                          <Badge variant="outline" className="border-emerald-500/20 bg-emerald-500/10 text-emerald-300">
                            {category.completedCount}/{category.count}
                          </Badge>
                        </div>
                        <h3 className="mb-2 text-xl font-bold text-white transition-colors group-hover:text-emerald-400">
                          {category.name} Sheet
                        </h3>
                        <div className="mt-auto space-y-4 pt-4">
                          <div className="h-1.5 w-full overflow-hidden rounded-full bg-zinc-800/80">
                            <div
                              className="h-full rounded-full bg-emerald-500 transition-all duration-700"
                              style={{ width: `${Math.round(category.progress)}%` }}
                            />
                          </div>
                          <div className="relative z-10 flex items-center justify-between border-t border-white/5 pt-4">
                            <span className="text-xs font-bold uppercase tracking-widest text-zinc-500">
                              {category.count} Questions
                            </span>
                            <div className="flex items-center gap-1 text-xs font-bold uppercase tracking-wider text-emerald-400">
                              Open Sheet
                              <ChevronRight size={14} className="transition-transform group-hover:translate-x-1" />
                            </div>
                          </div>
                        </div>
                      </CardContent>
                    </Card>
                  </motion.div>
                ))}
              </motion.div>
            ) : (
              <motion.div
                key="questions"
                initial={{ opacity: 0, x: 20 }}
                animate={{ opacity: 1, x: 0 }}
                exit={{ opacity: 0, x: -20 }}
                className="space-y-8"
              >
                {sheetContext === 'blind56' ? (
                  Object.entries(BLIND_56_DATA).map(([category, titles]) => {
                    const categoryQuestions = filteredQuestions.filter((question) =>
                      titles.some((title) => matchesBlind56Question(question, title)),
                    );

                    if (categoryQuestions.length === 0) {
                      return null;
                    }

                    return (
                      <div key={category} className="space-y-4">
                        <div className="flex items-center gap-3 px-2">
                          <h3 className="flex items-center gap-2 text-lg font-bold uppercase tracking-widest text-purple-400">
                            <Layers size={18} />
                            {category}
                          </h3>
                          <div className="h-px flex-1 bg-zinc-800/50" />
                          <Badge variant="outline" className="border-purple-500/20 bg-purple-500/10 text-purple-400">
                            {categoryQuestions.filter((question) => solvedSet.has(question.id)).length} / {categoryQuestions.length}
                          </Badge>
                        </div>
                        <QuestionTable
                          questions={categoryQuestions}
                          solvedSet={solvedSet}
                          onOpenQuestion={setSelectedForDialog}
                        />
                      </div>
                    );
                  })
                ) : (
                  <QuestionTable
                    questions={filteredQuestions}
                    solvedSet={solvedSet}
                    onOpenQuestion={setSelectedForDialog}
                    currentPage={currentPage}
                    onPageChange={setCurrentPage}
                    itemsPerPage={ITEMS_PER_PAGE}
                  />
                )}
              </motion.div>
            )}
          </AnimatePresence>

          <Dialog open={Boolean(selectedForDialog)} onOpenChange={(open) => !open && setSelectedForDialog(null)}>
            <DialogContent className="border-zinc-800 bg-zinc-950 text-zinc-200 sm:max-w-[425px]">
              <DialogHeader>
                <DialogTitle className="text-xl font-bold text-white">{selectedForDialog?.title}</DialogTitle>
              </DialogHeader>
              <div className="grid grid-cols-2 gap-4 py-4">
                <Button
                  onClick={() => {
                    if (selectedForDialog) {
                      onSelectQuestion(selectedForDialog, 'code');
                    }
                    setSelectedForDialog(null);
                  }}
                  className="group flex h-24 flex-col gap-2 border border-zinc-800 bg-zinc-900 text-zinc-200 hover:border-emerald-500/50 hover:bg-zinc-800"
                >
                  <Terminal className="text-emerald-400 transition-transform group-hover:scale-110" size={24} />
                  <span className="font-bold">Solve Code</span>
                </Button>
                <Button
                  onClick={() => {
                    if (selectedForDialog) {
                      onSelectQuestion(selectedForDialog, 'solution');
                    }
                    setSelectedForDialog(null);
                  }}
                  className="group flex h-24 flex-col gap-2 border border-zinc-800 bg-zinc-900 text-zinc-200 hover:border-cyan-500/50 hover:bg-zinc-800"
                >
                  <BookOpen className="text-cyan-400 transition-transform group-hover:scale-110" size={24} />
                  <span className="font-bold">View Solution</span>
                </Button>
              </div>
            </DialogContent>
          </Dialog>
        </div>

        {/* Right Sidebar: Session Progress + Leaderboard */}
        <div className="flex flex-col gap-6 xl:sticky xl:top-6 w-full">
          {/* Leaderboard Rank - Compact */}
          <motion.div
            initial={{ opacity: 0, y: 12 }}
            animate={{ opacity: 1, y: 0 }}
            className="relative overflow-hidden rounded-2xl border border-violet-500/10 bg-[#0d0d0d] p-4 backdrop-blur-xl shadow-xl"
          >
            <div className="absolute bottom-0 left-0 right-0 h-[2px] bg-gradient-to-r from-violet-400 to-purple-600" />
            <div className="flex items-center gap-3">
              <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-gradient-to-br from-violet-400/20 to-purple-600/20">
                <Zap size={18} className="text-violet-400" />
              </div>
              <div className="flex-1 min-w-0">
                <p className="text-[9px] uppercase tracking-[0.2em] text-zinc-600 font-black">Rank</p>
                <p className="text-2xl font-black text-white tracking-tighter" style={{ fontFamily: 'JetBrains Mono, monospace' }}>#{leaderboardRank}</p>
              </div>
              <span className="text-[8px] font-black uppercase tracking-[0.2em] text-violet-500/60 border border-violet-500/15 bg-violet-500/5 rounded-full px-2 py-0.5">● LIVE</span>
            </div>
            {leaderboardGap > 0 && <p className="text-[10px] text-zinc-600 mt-2 font-semibold">{leaderboardGap} pts to next</p>}
          </motion.div>

          {/* Session Progress */}
          <ProgressHeader
            totalQuestions={progressStats.totalQuestions}
            totalSolved={progressStats.totalSolved}
            categories={progressStats.categories}
          />

          {/* Leaderboard */}
          <motion.div
            initial={{ opacity: 0, x: 20 }}
            animate={{ opacity: 1, x: 0 }}
            transition={{ duration: 0.5, delay: 0.2 }}
            className="rounded-2xl border border-purple-500/10 bg-[#0d0d0d] p-5 backdrop-blur-xl shadow-xl overflow-hidden"
          >
            <div className="absolute bottom-0 left-0 right-0 h-[2px] bg-gradient-to-r from-purple-500 to-violet-600" />
            <div className="flex items-center justify-between mb-4">
              <div className="flex items-center gap-2">
                <div className="flex h-8 w-8 items-center justify-center rounded-xl bg-gradient-to-br from-purple-400/20 to-violet-600/20">
                  <Trophy size={15} className="text-purple-400" />
                </div>
                <div>
                  <h2 className="text-sm font-black text-white">Leaderboard</h2>
                  <p className="text-[10px] text-zinc-600 font-semibold">Rank #{leaderboardRank}</p>
                </div>
              </div>
              <span className="text-[9px] font-black border border-purple-500/15 bg-purple-500/5 text-purple-400 rounded-full px-2.5 py-1 uppercase tracking-[0.2em]">● Live</span>
            </div>
            <div className="space-y-2">
              {visibleEntries.map((entry, index) => (
                <motion.div
                  key={entry.id}
                  initial={{ opacity: 0, x: 10 }}
                  animate={{ opacity: 1, x: 0 }}
                  transition={{ delay: 0.3 + index * 0.07 }}
                  className={cn(
                    'flex items-center gap-3 rounded-xl border px-3 py-2.5',
                    entry.isCurrentUser
                      ? 'border-purple-400/25 bg-gradient-to-r from-purple-500/10 to-violet-500/5'
                      : 'border-white/[0.04] bg-white/[0.02]',
                  )}
                >
                  <div
                    className={cn(
                      'flex h-7 w-7 shrink-0 items-center justify-center rounded-full text-[11px] font-black',
                      entry.rank === 1
                        ? 'bg-gradient-to-br from-yellow-400/30 to-amber-500/20 text-yellow-300'
                        : entry.rank === 2
                          ? 'bg-gradient-to-br from-slate-300/20 to-zinc-400/10 text-slate-300'
                          : entry.rank === 3
                            ? 'bg-gradient-to-br from-orange-400/20 to-amber-600/10 text-orange-300'
                            : 'bg-white/[0.05] text-zinc-500',
                    )}
                    style={{ fontFamily: 'JetBrains Mono, monospace' }}
                  >
                    #{entry.rank}
                  </div>
                  <div className="flex-1 min-w-0">
                    <p className={cn('text-xs font-bold truncate', entry.isCurrentUser ? 'text-white' : 'text-zinc-300')}>{entry.displayName}</p>
                    <p className="text-[10px] text-zinc-600">{entry.solvedCount} solved · {entry.codingStreak ?? entry.currentStreak}d streak</p>
                  </div>
                  <div className="text-[11px] font-black text-zinc-400 bg-white/[0.04] rounded-lg px-2 py-1" style={{ fontFamily: 'JetBrains Mono, monospace' }}>{entry.score} pt</div>
                </motion.div>
              ))}
            </div>
            {leaderboardGap > 0 && (
              <p className="mt-3 text-[10px] text-zinc-600 text-center font-semibold">{leaderboardGap} more points to climb up</p>
            )}
            <motion.button
              type="button"
              onClick={onViewFullLeaderboard}
              whileHover={{ scale: 1.02 }}
              whileTap={{ scale: 0.97 }}
              className="mt-4 w-full rounded-xl border border-purple-500/20 bg-purple-500/5 py-2.5 text-xs font-black text-purple-400 transition-all hover:bg-purple-500/10 flex items-center justify-center gap-2 uppercase tracking-wider"
            >
              <Trophy size={13} />
              View Full Leaderboard
            </motion.button>
          </motion.div>
        </div>
      </div>
    </div>
  );
}

type QuestionTableProps = {
  questions: CodingQuestion[];
  solvedSet: Set<string>;
  onOpenQuestion: (question: CodingQuestion) => void;
  startIndex?: number;
  currentPage?: number;
  onPageChange?: (page: number) => void;
  itemsPerPage?: number;
  emptyMessage?: string;
};

function QuestionTable({
  questions,
  solvedSet,
  onOpenQuestion,
  startIndex = 0,
  currentPage = 1,
  onPageChange,
  itemsPerPage = 30,
  emptyMessage = 'No DSA questions match this view.',
}: QuestionTableProps) {
  const { tier } = useSubscription();
  const totalPages = Math.ceil(questions.length / itemsPerPage);
  const paginatedQuestions = onPageChange
    ? questions.slice((currentPage - 1) * itemsPerPage, currentPage * itemsPerPage)
    : questions;
  const pageStartIndex = onPageChange ? (currentPage - 1) * itemsPerPage : startIndex;

  return (
    <div className="space-y-3">
      <div className="overflow-hidden rounded-2xl border border-zinc-800/60 bg-[#0a0a0a] shadow-2xl">
        <div className="overflow-hidden">
          <table className="w-full table-fixed text-left text-[13px]">
            <thead className="border-b border-zinc-800 bg-[#111] text-[10px] uppercase tracking-[0.2em] text-zinc-600 font-black">
              <tr>
                <th className="w-10 px-3 py-3 text-center sm:w-12">#</th>
                <th className="w-12 px-2 py-3 text-center">Status</th>
                <th className="px-3 py-3">Title</th>
                <th className="w-24 px-3 py-3 sm:w-28">Difficulty</th>
                <th className="w-32 px-2 py-3 text-center sm:w-40">Companies</th>
                <th className="hidden w-24 px-3 py-3 text-right 2xl:table-cell">Reward</th>
              </tr>
            </thead>
            <tbody>
              {paginatedQuestions.length === 0 && (
                <tr>
                  <td colSpan={6} className="px-4 py-10 text-center text-sm font-semibold text-zinc-500">
                    {emptyMessage}
                  </td>
                </tr>
              )}
              {paginatedQuestions.map((question, index) => {
                const isSolved = solvedSet.has(question.id);
                const reward = getQuestionReward(question.difficulty);
                const displayIndex = pageStartIndex + index + 1;
                const isLocked = tier === 'free' && displayIndex > 200;

                return (
                  <motion.tr
                    key={question.id}
                    initial={{ opacity: 0 }}
                    animate={{ opacity: 1 }}
                    transition={{ delay: Math.min(index * 0.015, 0.5) }}
                    className={cn(
                      'group h-12 border-b border-zinc-800/30 transition-all duration-200 relative',
                      isLocked ? 'cursor-not-allowed opacity-40 grayscale' : 'cursor-pointer hover:bg-cyan-500/[0.03] hover:border-l-2 hover:border-l-cyan-500/50',
                      index % 2 === 0 ? 'bg-[#0a0a0a]' : 'bg-[#0d0d0d]',
                    )}
                    onClick={() => {
                      if (!isLocked) onOpenQuestion(question);
                    }}
                  >
                    <td className="px-3 py-2 text-center">
                      <span className="text-xs text-zinc-600 font-bold" style={{ fontFamily: 'JetBrains Mono, monospace' }}>{displayIndex}</span>
                    </td>
                    <td className="px-2 py-2 text-center">
                      <div className={cn('mx-auto flex h-4 w-4 items-center justify-center rounded-full', isSolved ? 'bg-emerald-500/15 text-emerald-400' : 'text-zinc-700')}>
                        {isSolved ? <CheckCircle2 size={14} /> : <Circle size={14} />}
                      </div>
                    </td>
                    <td className="min-w-0 px-3 py-2 font-bold text-zinc-300 transition-colors group-hover:text-cyan-400">
                      <span className="block max-w-full truncate">{question.title}</span>
                    </td>
                    <td className="px-3 py-2">
                      <span className={cn(
                        'text-[10px] font-black uppercase tracking-wider px-2 py-0.5 rounded-md',
                        question.difficulty === 'Easy' ? 'text-teal-400 bg-teal-500/10' : question.difficulty === 'Medium' ? 'text-orange-400 bg-orange-500/10' : 'text-rose-400 bg-rose-500/10',
                      )}>{question.difficulty}</span>
                    </td>
                    <td className="px-2 py-2 relative">
                      <CompanyLogos companies={question.companies ?? []} />
                      {isLocked && <div className="absolute inset-0 flex items-center justify-center backdrop-blur-[1px]"><Lock size={12} className="text-zinc-500" /></div>}
                    </td>
                    <td className="hidden px-3 py-2 text-right 2xl:table-cell">
                      <div className="inline-flex items-center gap-1 rounded-md border border-amber-500/15 bg-amber-500/5 px-2 py-0.5 text-amber-400">
                        <Coins size={11} />
                        <span className="text-[10px] font-black" style={{ fontFamily: 'JetBrains Mono, monospace' }}>{reward}</span>
                      </div>
                    </td>
                  </motion.tr>
                );
              })}
            </tbody>
          </table>
        </div>
      </div>

      {/* Pagination */}
      {onPageChange && totalPages > 1 && (
        <div className="flex items-center justify-between px-2">
          <p className="text-[10px] font-black text-zinc-600 uppercase tracking-wider">
            Showing {pageStartIndex + 1}-{Math.min(pageStartIndex + itemsPerPage, questions.length)} of {questions.length}
          </p>
          <div className="flex items-center gap-1">
            <button
              onClick={() => onPageChange(Math.max(1, currentPage - 1))}
              disabled={currentPage === 1}
              className="flex h-8 w-8 items-center justify-center rounded-lg border border-zinc-800/60 bg-[#111] text-zinc-500 transition-all hover:text-white hover:border-cyan-500/30 disabled:opacity-30 disabled:cursor-not-allowed"
            >
              <ChevronLeft size={14} />
            </button>
            {Array.from({ length: Math.min(5, totalPages) }, (_, i) => {
              let page: number;
              if (totalPages <= 5) { page = i + 1; }
              else if (currentPage <= 3) { page = i + 1; }
              else if (currentPage >= totalPages - 2) { page = totalPages - 4 + i; }
              else { page = currentPage - 2 + i; }
              return (
                <button
                  key={page}
                  onClick={() => onPageChange(page)}
                  className={cn(
                    'flex h-8 w-8 items-center justify-center rounded-lg text-xs font-black transition-all',
                    currentPage === page
                      ? 'bg-cyan-500/15 text-cyan-400 border border-cyan-500/30'
                      : 'border border-zinc-800/60 bg-[#111] text-zinc-500 hover:text-white hover:border-cyan-500/20',
                  )}
                  style={{ fontFamily: 'JetBrains Mono, monospace' }}
                >
                  {page}
                </button>
              );
            })}
            <button
              onClick={() => onPageChange(Math.min(totalPages, currentPage + 1))}
              disabled={currentPage === totalPages}
              className="flex h-8 w-8 items-center justify-center rounded-lg border border-zinc-800/60 bg-[#111] text-zinc-500 transition-all hover:text-white hover:border-cyan-500/30 disabled:opacity-30 disabled:cursor-not-allowed"
            >
              <ChevronRight size={14} />
            </button>
          </div>
        </div>
      )}
    </div>
  );
}

function CompanyLogos({ companies }: { companies: string[] }) {
  const { tier } = useSubscription();
  const uniqueCompanies = Array.from(new Set(companies.map((company) => company.trim()).filter(Boolean)));
  const visibleCompanies = uniqueCompanies.slice(0, 3);
  const extraCompanyCount = Math.max(uniqueCompanies.length - visibleCompanies.length, 0);

  if (uniqueCompanies.length === 0) {
    return (
      <div className="flex h-7 items-center justify-center overflow-hidden">
        <span
          title="No company listed"
          className="inline-flex h-7 w-7 items-center justify-center text-[9px] font-black text-zinc-700"
        >
          NA
        </span>
      </div>
    );
  }

  return (
    <div className={`flex h-7 max-w-full items-center justify-center gap-1.5 overflow-hidden relative ${tier === 'free' ? 'blur-sm opacity-50' : ''}`}>
      {visibleCompanies.map((company, index) => (
        <CompanyLogo key={company} company={company} index={index} />
      ))}
      {extraCompanyCount > 0 && (
        <span
          title={uniqueCompanies.slice(visibleCompanies.length).join(', ')}
          className="inline-flex h-7 min-w-7 shrink-0 items-center justify-center rounded-md border border-zinc-800 bg-zinc-900/80 px-1.5 text-[9px] font-black text-zinc-500"
          style={{ fontFamily: 'JetBrains Mono, monospace' }}
        >
          +{extraCompanyCount}
        </span>
      )}
    </div>
  );
}

function CompanyLogo({ company, index }: { company: string; index: number }) {
  const logoUrls = useMemo(() => getCompanyLogoUrls(company), [company]);
  const [logoIndex, setLogoIndex] = useState(0);
  const initials = getCompanyInitials(company);
  const logoUrl = logoUrls[logoIndex];

  return (
    <span
      title={company}
      aria-label={company}
      className="company-logo-mark inline-flex h-7 w-7 shrink-0 items-center justify-center text-[10px] font-black text-cyan-300 transition-transform hover:scale-110"
      style={{ animationDelay: `${index * 0.22}s` }}
    >
      {logoUrl ? (
        <img
          src={logoUrl}
          alt={`${company} logo`}
          loading="lazy"
          onError={() => setLogoIndex((current) => current + 1)}
          className="company-logo-icon h-full w-full object-contain"
        />
      ) : (
        <span>{initials}</span>
      )}
    </span>
  );
}

function getCompanyLogoUrls(company: string) {
  const normalizedCompany = normalizeCompanyName(company);
  const overrides = COMPANY_LOGO_OVERRIDES[normalizedCompany] ?? [];
  const domain = COMPANY_DOMAINS[normalizedCompany] ?? `${normalizedCompany}.com`;
  const simpleIconSlug = COMPANY_ICON_SLUGS[normalizedCompany] ?? normalizedCompany;

  return [
    ...overrides,
    `https://cdn.simpleicons.org/${simpleIconSlug}`,
    `https://logo.clearbit.com/${domain}`,
    `https://www.google.com/s2/favicons?sz=64&domain=${domain}`,
  ];
}

function normalizeCompanyName(company: string) {
  return company.toLowerCase().replace(/[^a-z0-9]/g, '');
}

function getCompanyInitials(company: string) {
  const words = company.match(/[a-z0-9]+/gi) ?? [];
  const initials = words.slice(0, 2).map((word) => word[0]?.toUpperCase()).join('');

  return initials || '?';
}

function matchesBlind56Question(question: CodingQuestion, title: string) {
  const questionTitle = question.title.toLowerCase();
  const blind56Title = title.toLowerCase();
  return questionTitle.includes(blind56Title) || blind56Title.includes(questionTitle);
}
