// src/pages/CipherAI.tsx
import React, { useEffect, useRef, useState } from "react";
import { Send, Volume2, VolumeX, Cpu, Sparkles, User } from "lucide-react";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";

/**
 * CipherAI.tsx
 * Single-file React + TypeScript chatbot component.
 *
 * Requirements:
 * - Your project should already supply Button, cn, and lucide-react icons.
 * - Optional server endpoint: http://localhost:3001/api/chat
 *
 * Behavior:
 * - Attempts to call server; if it fails, uses localGenerateResponse (safe, educational, no exploit instructions).
 * - Detects a short list of malicious-looking user inputs and refuses.
 * - Contains a tools registry so the bot can explain each tool in English.
 */

type Role = "user" | "assistant" | "system";

interface Message {
  role: Role;
  content: string;
  meta?: any;
}

interface ToolInfo {
  id: string;
  name: string;
  summary: string;
  safeUsage: string;
  highLevelArchitecture?: string;
  exampleCode?: string;
  references?: string[];
  tags?: string[];
}

const quickCommands = [
  "Teach me cybersecurity",
  "Analyze message",
  "Explain like I'm 10",
  "Expert explanation",
  "Career in security",
  "Bug bounty & legal",
  "Cloud security basics",
  "Incident response plan",
];

const CipherAI: React.FC = () => {
  const [messages, setMessages] = useState<Message[]>([
    {
      role: "assistant",
      content:
        "Hello — I'm Cipher-AI, your cybersecurity assistant. I can help you understand security concepts, analyze potential threats, and answer cyber-related questions. How can I assist you today?",
    },
  ]);
  const [input, setInput] = useState("");
  const [isTyping, setIsTyping] = useState(false);
  const [soundEnabled, setSoundEnabled] = useState(true);
  const [mode, setMode] = useState<"normal" | "expert">("normal");
  const messagesEndRef = useRef<HTMLDivElement | null>(null);
  const inputRef = useRef<HTMLTextAreaElement | null>(null);

  // rotating fallback index to avoid identical replies every time
  const fallbackIndexRef = useRef(0);

  useEffect(() => {
    messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
  }, [messages]);

  // -------------------- Tools registry --------------------
  // Populate this array with tools from your ToolsDashboard (safe descriptions only)
  const toolsList: ToolInfo[] = [
    {
      id: "password-strength",
      name: "Password Strength Analyzer",
      summary:
        "Analyzes password composition, estimates entropy and gives a simple strength score and rough crack-time category.",
      safeUsage:
        "Use this for user education and demo checks. Do not paste production credentials; use examples or test strings. Encourage password managers and MFA.",
      highLevelArchitecture:
        "Client-side regex checks for categories (upper/lower/number/symbol), estimate of charset size, entropy = length * log2(charset), and heuristic mapping to a human-friendly strength scale.",
      exampleCode:
        `// entropy example (JS)
const length = pwd.length;
const charset = (hasUpper?26:0) + (hasLower?26:0) + (hasNumber?10:0) + (hasSpecial?32:0);
const entropyBits = length * Math.log2(Math.max(1, charset));`,
      references: ["NIST SP 800-63B", "OWASP Password Guidance"],
      tags: ["identity", "education"],
    },
    {
      id: "phishing-detector",
      name: "Email Phishing Detector",
      summary:
        "Simple heuristic scanner to flag common phishing indicators like urgency, suspicious CTAs, and requests for sensitive information.",
      safeUsage:
        "Paste only redacted or non-sensitive examples. Pair with header checks (SPF/DKIM/DMARC) and link-reputation services for higher-fidelity deployments.",
      highLevelArchitecture:
        "Client-side keyword/pattern matching and simple scoring => status (Safe / Suspicious / Dangerous). Intended for triage and education.",
      exampleCode:
        `// rule example
if (content.includes('verify your account') || content.includes('click here')) {
  issues.push('Contains suspicious call-to-action phrases');
}`,
      references: ["CISA phishing guidance", "OWASP phishing resources"],
      tags: ["phishing", "email", "triage"],
    },
    {
      id: "url-checker",
      name: "URL / File Risk Checker",
      summary:
        "Heuristic URL analyzer that checks for insecure protocol, typosquatting patterns, suspicious TLDs, and harmful file extensions.",
      safeUsage:
        "Useful for triage. Do not auto-open flagged links. For production, enrich with WHOIS, passive DNS, and threat-intel feeds.",
      highLevelArchitecture:
        "Parse the URL, run regex and rule checks, collect issues, and map to Safe/Suspicious/Dangerous status.",
      exampleCode:
        `try {
  const u = new URL(input);
  if (u.protocol === 'http:') issues.push('Insecure protocol');
} catch(e) { /* not a URL */ }`,
      references: ["Public research on phishing URL heuristics"],
      tags: ["url", "phishing"],
    },
    {
      id: "qr-scanner",
      name: "QR Code Security Scanner",
      summary:
        "Decodes camera/uploaded QR codes and performs URL heuristics and payment-URI extraction (e.g., UPI VPA). Warns about suspicious links.",
      safeUsage:
        "Use to triage QR payloads. Do not open untrusted links automatically. Combine with link reputation services in production.",
      highLevelArchitecture:
        "Capture image -> decode (jsQR) -> heuristics (URL checks, payment parsing) -> status + optional extracted fields.",
      exampleCode:
        `// simple VPA regex
const vpa = s.match(/[a-z0-9.\\-_]{2,}@[a-z0-9.\\-]{2,}/i);`,
      references: ["jsQR", "UPI/Payment URI formats (public docs)"],
      tags: ["qr", "scanner", "triage"],
    },
  ];

  const toolsIndex: Record<string, ToolInfo> = {};
  toolsList.forEach((t) => (toolsIndex[t.id.toLowerCase()] = t));

  // -------------------- Safety guard --------------------
  const isClearlyMalicious = (text: string) => {
    const t = (text || "").toLowerCase();
    const triggers = [
      "write ransomware",
      "how to hack",
      "exploit ",
      "zero-day",
      "privilege escalation step",
      "build a botnet",
      "ddos",
      "ddos script",
      "bypass authentication",
      "crack password",
      "steal",
      "delete all",
      "root exploit",
      "malicious payload",
    ];
    return triggers.some((tr) => t.includes(tr));
  };

  // -------------------- Tool info renderer --------------------
  const renderToolInfo = (tool: ToolInfo, ask: string) => {
    const parts: string[] = [];
    parts.push(`${tool.name} — short summary:`);
    parts.push(tool.summary);
    parts.push("");
    parts.push("Safe usage and defensive context:");
    parts.push(tool.safeUsage);
    if (tool.highLevelArchitecture) {
      parts.push("");
      parts.push("High-level architecture / components:");
      parts.push(tool.highLevelArchitecture);
    }
    if (tool.exampleCode) {
      parts.push("");
      parts.push("Example (benign):");
      const snippet = tool.exampleCode.length > 600 ? tool.exampleCode.slice(0, 600) + "\n... (truncated)" : tool.exampleCode;
      parts.push(snippet);
    }
    if (tool.references && tool.references.length) {
      parts.push("");
      parts.push("References:");
      tool.references.slice(0, 6).forEach((r) => parts.push(`• ${r}`));
    }
    parts.push("");
    parts.push("Note: I provide educational and defensive information only. I will not provide exploit code, step-by-step attack instructions, or operational guidance for illegal activity.");
    if (ask.toLowerCase().includes("how to use") || ask.toLowerCase().includes("usage")) {
      parts.push("");
      parts.push("If you want authorized deployment guidance, say 'authorized usage' and describe your role and scope.");
    }
    return parts.join("\n");
  };

  // -------------------- Local fallback generator --------------------
  const localGenerateResponse = (userMessage: string): string => {
    const lowerMessage = (userMessage || "").toLowerCase().trim();

    if (isClearlyMalicious(lowerMessage)) {
      return [
        "I cannot assist with requests that are illegal or intended to cause harm.",
        "If you are an authorized security researcher, please confirm:",
        "• Do you have written permission to test the target? (Yes/No)",
        "• What is your objective — defensive research, authorized testing, or vulnerability disclosure?",
        "",
        "If you are authorized, I can provide high-level, non-actionable guidance on safe testing practices, lab setups (isolated VMs, sandboxing), and defensive mitigations.",
        "I will not provide exploit code or step-by-step attack instructions.",
      ].join("\n");
    }

    // If user asks about a tool by id or name, return tool info
    for (const key of Object.keys(toolsIndex)) {
      const tool = toolsIndex[key];
      if (!tool) continue;
      const nameLower = tool.name.toLowerCase();
      if (lowerMessage.includes(key) || lowerMessage.includes(nameLower)) {
        return renderToolInfo(tool, userMessage);
      }
    }

    // Topic matches (safe educational responses)
    if (lowerMessage.includes("teach me") || lowerMessage.includes("teach") || lowerMessage.includes("learn")) {
      return [
        "I can teach cybersecurity from basics to advanced topics. Suggested starting path:",
        "1) Basics: networking (TCP/IP, ports), OS fundamentals (Linux/Windows), and basic scripting.",
        "2) Defensive skills: logging, monitoring, SIEM, incident response, and forensics.",
        "3) Hands-on: TryHackMe / Hack The Box (authorized labs), and build a portfolio of safe exercises.",
        "Ask me 'beginner path' or a specific topic (e.g., 'teach me about phishing').",
      ].join("\n");
    }

    if (lowerMessage.includes("network") || lowerMessage.includes("tcp") || lowerMessage.includes("osi")) {
      return mode === "expert"
        ? "Networking fundamentals: OSI/TCP stacks, TCP/UDP/ICMP, subnetting and CIDR, routing basics, NAT, and common attack surfaces. Defenders focus on segmentation, least-privilege ACLs, encrypted transit (TLS), and comprehensive logging."
        : "Network basics: data travels in layers. Firewalls and keeping services updated reduce risk. Start with learning TCP/IP and common ports.";
    }

    if (lowerMessage.includes("password")) {
      return mode === "expert"
        ? "Password security: measure entropy (bits) using charset*length, resist brute force via length and entropy, store with Argon2id/bcrypt, and adopt hardware-backed MFA where possible."
        : "Use long passphrases (12+ characters), unique for each account, and a password manager. Enable 2FA for important accounts.";
    }

    if (lowerMessage.includes("phishing") || lowerMessage.includes("email")) {
      return mode === "expert"
        ? "Phishing: use SPF/DKIM/DMARC for email authentication, analyze headers, check DKIM/SPF results, and use ML-based email filters. Train users with simulated phishing and provide easy reporting channels."
        : "Phishing is when attackers pretend to be someone you trust. Check the sender address, avoid clicking links from unknown emails, and report suspicious emails.";
    }

    if (lowerMessage.includes("resources") || lowerMessage.includes("learn") || lowerMessage.includes("labs")) {
      return [
        "Learning resources (safe & legal):",
        "• TryHackMe, Hack The Box — use official lab environments only.",
        "• OWASP Top 10 and Juice Shop for web security practice.",
        "• MITRE ATT&CK for adversary behaviors.",
        "• Vendor advisories (CISA, CERTs) and NIST guidance.",
      ].join("\n");
    }

    if (lowerMessage.includes("analyze") || lowerMessage.includes("check this email") || lowerMessage.includes("suspicious")) {
      return "I can analyze text, email, or a scenario from a defensive perspective — I will NOT click links. Paste headers+body for email checks (redact sensitive fields) and I will point out indicators and recommended next steps.";
    }

    // default rotating reply
    const defaultResponses = [
      "Cybersecurity is broad — tell me if you're a beginner or have experience so I can tailor the explanation.",
      "Pick a topic (cloud security, incident response, bug bounty), or say 'Teach me cybersecurity' for a learning path.",
      "Security fundamentals include networking, operating systems, identity, and monitoring — which area interests you most?",
      "If you are an authorized researcher, say 'I have permission' and I can provide high-level testing methodology and lab setup advice (no exploit code).",
    ];
    const idx = fallbackIndexRef.current % defaultResponses.length;
    fallbackIndexRef.current += 1;
    return defaultResponses[idx];
  };

  // -------------------- send code (server + fallback) --------------------
  const handleSend = async () => {
    if (!input.trim()) return;

    const userMessage = input.trim();
    setInput("");
    setMessages((prev) => [...prev, { role: "user", content: userMessage }]);
    setIsTyping(true);

    try {
      const res = await fetch("/api/chat", {
        // Recommendation: use relative path and set up a server proxy, or use your local server url.
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ message: userMessage, mode }),
      });

      if (!res.ok) throw new Error("server returned non-OK");

      const data = await res.json();

      // server expected to return { answer: string } or { text: string } or similar
      let assistantText: string | undefined = data.answer ?? data.text ?? undefined;

      // Fallback to local generator if server returned empty/invalid
      if (!assistantText || typeof assistantText !== "string" || !assistantText.trim()) {
        assistantText = localGenerateResponse(userMessage);
      }

      // guard: if assistantText looks malicious, use local safe fallback
      if (isClearlyMalicious(assistantText)) {
        assistantText = localGenerateResponse(userMessage);
      }

      setMessages((prev) => [
        ...prev,
        {
          role: "assistant",
          content: assistantText!,
          meta: { citations: data.citations ?? null, webSummary: data.webSummary ?? null },
        },
      ]);

      // If server provided citations array, append a 'Sources' message
      if (data.citations && Array.isArray(data.citations) && data.citations.length > 0) {
        const citationsText = data.citations
          .slice(0, 6)
          .map((c: any, i: number) => `${i + 1}. ${c.title ?? c.source ?? c.url ?? "source"}`.trim())
          .join("\n");
        setMessages((prev) => [
          ...prev,
          { role: "assistant", content: `Sources:\n${citationsText}`, meta: { citations: data.citations } },
        ]);
      }
    } catch (err) {
      // Server failed -> use local fallback
      const response = localGenerateResponse(userMessage);
      setMessages((prev) => [...prev, { role: "assistant", content: response }]);
      // console for debugging
      // eslint-disable-next-line no-console
      console.error("API call failed, used local fallback:", err);
    } finally {
      setIsTyping(false);
    }
  };

  // -------------------- keyboard handlers + quick commands --------------------
  const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
    if (e.key === "Enter" && !e.shiftKey) {
      e.preventDefault();
      handleSend();
    }
  };

  const handleQuickCommand = (command: string) => {
    setInput(command);
    inputRef.current?.focus();
  };

  // -------------------- render message --------------------
  const renderMessage = (message: Message, index: number) => {
    const isUser = message.role === "user";
    return (
      <div key={index} className={cn("flex gap-3 animate-fade-in-up", isUser ? "flex-row-reverse" : "")}>
        <div
          className={cn(
            "w-10 h-10 rounded-lg flex items-center justify-center shrink-0",
            isUser ? "bg-secondary/20 text-secondary" : "bg-primary/20 text-primary"
          )}
        >
          {isUser ? <User className="w-5 h-5" /> : <Sparkles className="w-5 h-5" />}
        </div>

        <div className={cn("max-w-[80%] p-4 rounded-xl", isUser ? "bg-secondary/20 text-foreground" : "bg-muted/50 text-foreground border border-primary/30")}>
          <p className="whitespace-pre-wrap">{message.content}</p>

          {message.meta?.citations && Array.isArray(message.meta.citations) && (
            <div className="mt-3 text-xs text-muted-foreground space-y-1">
              <div className="font-medium">Citations:</div>
              {message.meta.citations.slice(0, 5).map((c: any, i: number) => (
                <div key={i} className="break-all">
                  {i + 1}. {c.title ?? c.url ?? c.source ?? "source"}{" "}
                  {c.url ? (
                    <a className="underline ml-1" href={c.url} target="_blank" rel="noreferrer">
                      open
                    </a>
                  ) : null}
                </div>
              ))}
            </div>
          )}
        </div>
      </div>
    );
  };

  // -------------------- UI --------------------
  return (
    <div className="min-h-screen flex flex-col py-8 px-4">
      <div className="container mx-auto max-w-4xl flex-1 flex flex-col">
        {/* Header */}
        <div className="text-center mb-6">
          <div className="inline-flex items-center gap-3 mb-4">
            <div className="relative">
              <Cpu className="w-10 h-10 text-primary animate-float" />
              <div className="absolute inset-0 blur-xl bg-primary/50" />
            </div>
            <h1 className="font-display text-3xl lg:text-4xl font-bold text-gradient-primary">Cipher-AI</h1>
          </div>
          <p className="text-muted-foreground">Your intelligent cybersecurity assistant</p>
        </div>

        {/* Controls */}
        <div className="flex items-center justify-between mb-4">
          <div className="flex gap-2">
            <button
              onClick={() => setMode("normal")}
              className={cn(
                "px-4 py-2 rounded-lg text-sm font-medium transition-all",
                mode === "normal" ? "bg-primary text-primary-foreground" : "bg-muted/50 text-muted-foreground hover:text-foreground"
              )}
            >
              Normal Mode
            </button>
            <button
              onClick={() => setMode("expert")}
              className={cn(
                "px-4 py-2 rounded-lg text-sm font-medium transition-all",
                mode === "expert" ? "bg-secondary text-secondary-foreground" : "bg-muted/50 text-muted-foreground hover:text-foreground"
              )}
            >
              Expert Mode
            </button>
          </div>

          <button onClick={() => setSoundEnabled((s) => !s)} className="p-2 rounded-lg bg-muted/50 text-muted-foreground hover:text-foreground transition-colors">
            {soundEnabled ? <Volume2 className="w-5 h-5" /> : <VolumeX className="w-5 h-5" />}
          </button>
        </div>

        {/* Chat Container */}
        <div className="flex-1 glass-card rounded-xl overflow-hidden flex flex-col">
          <div className="flex-1 overflow-y-auto p-6 space-y-4 scrollbar-cyber">
            {messages.map((m, i) => renderMessage(m, i))}

            {isTyping && (
              <div className="flex gap-3 animate-fade-in-up">
                <div className="w-10 h-10 rounded-lg bg-primary/20 text-primary flex items-center justify-center">
                  <Sparkles className="w-5 h-5" />
                </div>
                <div className="bg-muted/50 p-4 rounded-xl border border-primary/30">
                  <div className="flex gap-1">
                    <span className="w-2 h-2 bg-primary rounded-full animate-bounce" />
                    <span className="w-2 h-2 bg-primary rounded-full animate-bounce" style={{ animationDelay: "0.1s" }} />
                    <span className="w-2 h-2 bg-primary rounded-full animate-bounce" style={{ animationDelay: "0.2s" }} />
                  </div>
                </div>
              </div>
            )}

            <div ref={messagesEndRef} />
          </div>

          {/* Quick Commands (border removed) */}
          <div className="px-4 py-2 flex gap-2 overflow-x-auto">
            {quickCommands.map((command) => (
              <button
                key={command}
                onClick={() => handleQuickCommand(command)}
                className="px-3 py-1.5 text-xs rounded-full bg-muted/50 text-muted-foreground hover:text-primary hover:bg-primary/10 transition-all whitespace-nowrap"
              >
                {command}
              </button>
            ))}
          </div>

          {/* Input (border removed) */}
          <div className="p-4">
            <div className="flex gap-3">
              <textarea
                ref={inputRef}
                value={input}
                onChange={(e) => setInput(e.target.value)}
                onKeyDown={handleKeyDown}
                placeholder="Type your message... (Shift+Enter for new line)"
                className="flex-1 min-h-[50px] max-h-[150px] resize-none bg-muted/50 border border-border/50 rounded-lg px-4 py-3 text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary transition-all"
                rows={1}
              />
              <Button variant="neon" size="icon" onClick={handleSend} disabled={!input.trim() || isTyping} className="h-[50px] w-[50px]">
                <Send className="w-5 h-5" />
              </Button>
            </div>
          </div>
        </div>

        {/* Disclaimer */}
        <p className="text-center text-xs text-muted-foreground mt-4">
          Cipher-AI provides cybersecurity education only. For professional security assessments, consult a certified expert. Never test systems without written
          permission.
        </p>
      </div>
    </div>
  );
};

export default CipherAI;
