"use client";

import { useCallback, useMemo, useState, useRef, useEffect } from "react";
import Link from "next/link";

import { AdminRulesPanel } from "@/components/admin-rules-panel";
import { Footer } from "@/components/footer";
import { useTenant } from "@/contexts/TenantContext";
import { TenantSelector } from "@/components/tenant-selector";

const BACKEND_BASE_URL = process.env.NEXT_PUBLIC_BACKEND_BASE_URL ?? "http://localhost:8000";

type StatusState = { tone: "info" | "success" | "error"; message: string } | null;

export default function AdminRulesPage() {
  const { tenantId } = useTenant();
  const [rulesInput, setRulesInput] = useState("");
  const [deleteInput, setDeleteInput] = useState("");
  const [rules, setRules] = useState<string[]>([]);
  const [loading, setLoading] = useState(false);
  const [status, setStatus] = useState<StatusState>(null);
  const [isDragging, setIsDragging] = useState(false);
  const [lastUpdated, setLastUpdated] = useState<string>("");
  const fileInputRef = useRef<HTMLInputElement>(null);

  // Set initial time only on client side to avoid hydration mismatch
  useEffect(() => {
    setLastUpdated(new Date().toLocaleTimeString());
  }, []);

  const headers = useMemo(() => {
    if (!tenantId.trim()) return undefined;
    return {
      "Content-Type": "application/json",
      "x-tenant-id": tenantId.trim(),
    };
  }, [tenantId]);

  const requireTenant = useCallback(() => {
    if (!tenantId.trim()) {
      setStatus({ tone: "error", message: "Enter a tenant ID in the navbar first." });
      return false;
    }
    return true;
  }, [tenantId]);

  const handleRefresh = useCallback(async () => {
    if (!requireTenant()) return;
    try {
      setLoading(true);
      setStatus({ tone: "info", message: "Loading rules..." });
      const response = await fetch(`${BACKEND_BASE_URL}/admin/rules`, {
        method: "GET",
        headers,
      });
      if (!response.ok) {
        throw new Error(`Backend error ${response.status}`);
      }
      const data = await response.json();
      setRules(data.rules ?? []);
      setLastUpdated(new Date().toLocaleTimeString());
      setStatus({ tone: "success", message: "Rules synced." });
    } catch (error: any) {
      setStatus({ tone: "error", message: error.message || "Failed to fetch rules" });
    } finally {
      setLoading(false);
    }
  }, [headers, requireTenant]);

  const handleUpload = useCallback(async () => {
    if (!requireTenant()) return;
    const lines = rulesInput
      .split("\n")
      .map((line) => line.trim())
      .filter((line) => line && !line.startsWith("#")); // Filter out comments and empty lines

    if (!lines.length) {
      setStatus({ tone: "error", message: "Add at least one rule to upload. (Comment lines starting with # are ignored)" });
      return;
    }

    try {
      setLoading(true);
      setStatus({ tone: "info", message: `Uploading ${lines.length} rule(s)...` });
      const response = await fetch(`${BACKEND_BASE_URL}/admin/rules/bulk?enhance=true`, {
        method: "POST",
        headers,
        body: JSON.stringify({ rules: lines }),
      });
      if (!response.ok) {
        const details = await response.text();
        throw new Error(details || `Backend error ${response.status}`);
      }
      const data = await response.json();
      await handleRefresh();
      setRulesInput("");
      const enhancedMsg = data.enhanced ? " (enhanced by LLM)" : "";
      setStatus({ tone: "success", message: `Uploaded ${data.added_rules?.length || lines.length} rule(s)${enhancedMsg}.` });
    } catch (error: any) {
      setStatus({ tone: "error", message: error.message || "Failed to upload rules" });
    } finally {
      setLoading(false);
    }
  }, [handleRefresh, headers, requireTenant, rulesInput]);

  const processFile = useCallback(async (file: File) => {
    if (!requireTenant()) return;

    const fileExt = file.name.split('.').pop()?.toLowerCase();
    if (!fileExt || !['txt', 'pdf', 'doc', 'docx', 'md'].includes(fileExt)) {
      setStatus({ tone: "error", message: "Unsupported file type. Supported: TXT, PDF, DOC, DOCX, MD" });
      return;
    }

    try {
      setLoading(true);
      setStatus({ tone: "info", message: `Uploading and processing ${file.name}...` });

      // For TXT files, read client-side for faster processing
      if (fileExt === 'txt' || fileExt === 'md') {
        const fileContent = await file.text();
        const lines = fileContent
          .split("\n")
          .map((line) => line.trim())
          .filter((line) => line && !line.startsWith("#"));

        if (!lines.length) {
          setStatus({ tone: "error", message: "No valid rules found in file (after filtering comments)." });
          setLoading(false);
          return;
        }

        // Upload rules via bulk endpoint
        setStatus({ tone: "info", message: `Uploading ${lines.length} rule(s)...` });
        const response = await fetch(`${BACKEND_BASE_URL}/admin/rules/bulk?enhance=true`, {
          method: "POST",
          headers,
          body: JSON.stringify({ rules: lines }),
        });

        if (!response.ok) {
          const details = await response.text();
          throw new Error(details || `Backend error ${response.status}`);
        }

        const data = await response.json();
        await handleRefresh();
        const enhancedMsg = data.enhanced ? " (enhanced by LLM)" : "";
        setStatus({ tone: "success", message: `Uploaded ${data.added_rules?.length || lines.length} rule(s) from ${file.name}${enhancedMsg}.` });
        return;
      }

      // For PDF, DOC, DOCX - use backend file upload endpoint
      const formData = new FormData();
      formData.append('file', file);

      setStatus({ tone: "info", message: `Extracting text from ${file.name}...` });
      const response = await fetch(`${BACKEND_BASE_URL}/admin/rules/upload-file?enhance=true`, {
        method: "POST",
        headers: {
          "x-tenant-id": tenantId.trim(),
        },
        body: formData,
      });

      if (!response.ok) {
        const details = await response.text();
        throw new Error(details || `Backend error ${response.status}`);
      }

      const data = await response.json();
      await handleRefresh();
      const enhancedMsg = data.enhanced ? " (enhanced by LLM)" : "";
      setStatus({ 
        tone: "success", 
        message: `Uploaded ${data.added_rules?.length || data.total_extracted || 0} rule(s) from ${file.name}${enhancedMsg}.` 
      });
    } catch (error: any) {
      setStatus({ tone: "error", message: error.message || "Failed to upload rules from file" });
    } finally {
      setLoading(false);
    }
  }, [handleRefresh, headers, requireTenant, tenantId]);

  const handleFileUpload = useCallback(async (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    if (!file) return;
    await processFile(file);
    if (fileInputRef.current) {
      fileInputRef.current.value = "";
    }
  }, [processFile]);

  const handleDragOver = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
    setIsDragging(true);
  }, []);

  const handleDragLeave = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
    setIsDragging(false);
  }, []);

  const handleDrop = useCallback(async (e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
    setIsDragging(false);

    const file = e.dataTransfer.files?.[0];
    if (!file) return;

    const fileExt = file.name.split('.').pop()?.toLowerCase();
    if (!fileExt || !['txt', 'pdf', 'doc', 'docx', 'md'].includes(fileExt)) {
      setStatus({ tone: "error", message: "Unsupported file type. Supported: TXT, PDF, DOC, DOCX, MD" });
      return;
    }

    await processFile(file);
  }, [processFile]);

  const handleDelete = useCallback(async () => {
    if (!requireTenant()) return;
    if (!deleteInput.trim()) {
      setStatus({ tone: "error", message: "Enter the rule text you want to delete." });
      return;
    }

    try {
      setLoading(true);
      setStatus({ tone: "info", message: "Deleting rule..." });
      const response = await fetch(
        `${BACKEND_BASE_URL}/admin/rules/${encodeURIComponent(deleteInput.trim())}`,
        {
          method: "DELETE",
          headers,
        }
      );
      if (!response.ok) {
        const details = await response.text();
        throw new Error(details || `Backend error ${response.status}`);
      }
      await handleRefresh();
      setDeleteInput("");
      setStatus({ tone: "success", message: "Rule deleted." });
    } catch (error: any) {
      setStatus({ tone: "error", message: error.message || "Failed to delete rule" });
    } finally {
      setLoading(false);
    }
  }, [deleteInput, handleRefresh, headers, requireTenant]);

  return (
    <main className="mx-auto flex min-h-screen max-w-5xl flex-col gap-10 px-4 pb-16 pt-12 sm:px-6 lg:px-8">
      <header className="flex flex-col gap-4 rounded-2xl border border-white/10 bg-white/5 px-6 py-6 text-slate-100 shadow-lg shadow-slate-950/40">
        <div className="flex items-center justify-between gap-3">
          <div className="flex items-center gap-3 text-base font-semibold">
            <span className="inline-flex h-10 w-10 items-center justify-center rounded-2xl bg-gradient-to-br from-sky-400 to-cyan-500 text-slate-950">
              IC
            </span>
            IntegraChat · Admin Rule Ingestion
          </div>
          <div className="flex items-center gap-4">
            <TenantSelector />
            <Link href="/" className="text-xs font-semibold uppercase tracking-[0.3em] text-cyan-300 hover:text-white">
              ← Back Home
            </Link>
          </div>
        </div>
        <div className="space-y-2">
          <p className="text-sm text-slate-300">
            Upload governance policies, compliance workflows, and red-flag patterns. Rules are automatically enhanced by LLM and stored in the backend.
          </p>
          <div className="flex flex-wrap gap-2 text-xs text-slate-400">
            <span className="flex items-center gap-1 rounded-full bg-white/5 px-3 py-1">
              <span>✨</span>
              <span>LLM Enhanced</span>
            </span>
            <span className="flex items-center gap-1 rounded-full bg-white/5 px-3 py-1">
              <span>📄</span>
              <span>File Upload</span>
            </span>
            <span className="flex items-center gap-1 rounded-full bg-white/5 px-3 py-1">
              <span>🔄</span>
              <span>Chunk Processing</span>
            </span>
          </div>
        </div>
      </header>

      <AdminRulesPanel />

      <section className="rounded-3xl border border-white/10 bg-white/5 p-6 shadow-2xl shadow-slate-950/40">
        <div className="flex flex-col gap-6">
          <div className="flex items-center justify-between gap-3">
            {lastUpdated && (
              <div className="flex items-center gap-2 text-sm text-slate-400">
                <span>🔄</span>
                <span>Last updated: {lastUpdated}</span>
              </div>
            )}
            {!lastUpdated && <div></div>}
            <button
              onClick={handleRefresh}
              disabled={loading}
              className="flex items-center gap-2 rounded-xl bg-gradient-to-r from-cyan-400 to-blue-500 px-6 py-3 text-sm font-semibold text-slate-950 shadow-lg shadow-cyan-500/30 transition hover:shadow-cyan-500/50 disabled:opacity-50 disabled:cursor-not-allowed"
            >
              {loading ? (
                <>
                  <span className="animate-spin">⏳</span>
                  <span>Refreshing...</span>
                </>
              ) : (
                <>
                  <span>🔄</span>
                  <span>Refresh Rules</span>
                </>
              )}
            </button>
          </div>

          <div className="grid gap-6 lg:grid-cols-2">
            {/* Left Column: Upload Rules */}
            <div className="flex flex-col gap-4 rounded-2xl border border-white/10 bg-slate-900/30 p-6">
              <div className="flex items-center gap-2">
                <span className="text-lg">📝</span>
                <h3 className="text-lg font-semibold text-slate-200">Add Rules</h3>
              </div>
              
              <label className="flex flex-col gap-2 text-sm font-semibold text-slate-200">
                <span>Bulk Upload Rules (one per line)</span>
                <textarea
                  value={rulesInput}
                  onChange={(e) => setRulesInput(e.target.value)}
                  placeholder="Block password disclosure requests\nPrevent sharing of API keys\nNo sharing of credit card information"
                  rows={8}
                  className="rounded-xl border border-white/10 bg-slate-900/50 px-4 py-3 text-sm text-white placeholder:text-slate-500 outline-none ring-0 transition focus:border-cyan-400 focus:ring-2 focus:ring-cyan-400/20"
                />
                <span className="text-xs text-slate-400">
                  💡 Tip: Comment lines (starting with #) are automatically ignored
                </span>
              </label>
              
              <button
                onClick={handleUpload}
                disabled={loading || !rulesInput.trim()}
                className="rounded-xl bg-gradient-to-r from-emerald-400 to-lime-400 px-6 py-3 text-sm font-semibold text-slate-900 shadow-lg shadow-emerald-500/30 transition hover:shadow-emerald-500/50 disabled:opacity-50 disabled:cursor-not-allowed"
              >
                {loading ? "⏳ Uploading..." : "✅ Upload / Append Rules"}
              </button>
              
              <div className="flex items-center gap-3 py-2">
                <span className="h-px flex-1 bg-white/10"></span>
                <span className="text-xs font-semibold uppercase tracking-wider text-slate-400">OR</span>
                <span className="h-px flex-1 bg-white/10"></span>
              </div>
              
              <label className="flex flex-col gap-2 text-sm font-semibold text-slate-200">
                <span>📄 Upload Rules from File</span>
                <div
                  onDragOver={handleDragOver}
                  onDragLeave={handleDragLeave}
                  onDrop={handleDrop}
                  className={`relative rounded-xl border-2 border-dashed transition-all ${
                    isDragging
                      ? "border-cyan-400 bg-cyan-500/10 scale-[1.02]"
                      : "border-white/20 bg-slate-900/50 hover:border-cyan-400/50 hover:bg-slate-900/70"
                  }`}
                >
                  <input
                    ref={fileInputRef}
                    type="file"
                    accept=".txt,.pdf,.doc,.docx,.md"
                    onChange={handleFileUpload}
                    disabled={loading}
                    className="hidden"
                    id="file-upload-input"
                  />
                  <label
                    htmlFor="file-upload-input"
                    className="flex flex-col items-center justify-center gap-3 p-8 cursor-pointer"
                  >
                    {isDragging ? (
                      <>
                        <span className="text-4xl animate-bounce">📥</span>
                        <span className="text-sm font-semibold text-cyan-300">Drop file here</span>
                      </>
                    ) : (
                      <>
                        <span className="text-4xl">📄</span>
                        <div className="text-center">
                          <span className="text-sm font-semibold text-slate-200">
                            Drag & drop file here
                          </span>
                          <span className="text-xs text-slate-400 block mt-1">or click to browse</span>
                        </div>
                        <button
                          type="button"
                          disabled={loading}
                          className="mt-2 rounded-lg bg-gradient-to-r from-cyan-500 to-blue-500 px-4 py-2 text-xs font-semibold text-slate-900 transition hover:from-cyan-400 hover:to-blue-400 disabled:opacity-50"
                        >
                          Choose File
                        </button>
                      </>
                    )}
                  </label>
                </div>
                <span className="text-xs text-slate-400">
                  Supported: TXT, PDF, DOC, DOCX, MD • Files processed server-side with LLM enhancement
                </span>
              </label>
            </div>

            {/* Right Column: Delete Rules */}
            <div className="flex flex-col gap-4 rounded-2xl border border-white/10 bg-slate-900/30 p-6">
              <div className="flex items-center gap-2">
                <span className="text-lg">🗑️</span>
                <h3 className="text-lg font-semibold text-slate-200">Delete Rule</h3>
              </div>
              
              <label className="flex flex-col gap-2 text-sm font-semibold text-slate-200">
                <span>Enter exact rule text to remove</span>
                <textarea
                  value={deleteInput}
                  onChange={(e) => setDeleteInput(e.target.value)}
                  placeholder="Paste the exact rule text here to delete it..."
                  rows={8}
                  className="rounded-xl border border-white/10 bg-slate-900/50 px-4 py-3 text-sm text-white placeholder:text-slate-500 outline-none ring-0 transition focus:border-rose-400 focus:ring-2 focus:ring-rose-400/20"
                />
                <span className="text-xs text-slate-400">
                  ⚠️ This action cannot be undone. Make sure the text matches exactly.
                </span>
              </label>
              
              <button
                onClick={handleDelete}
                disabled={loading || !deleteInput.trim()}
                className="rounded-xl border-2 border-rose-500 bg-rose-500/10 px-6 py-3 text-sm font-semibold text-rose-300 transition hover:bg-rose-500/20 hover:border-rose-400 disabled:opacity-50 disabled:cursor-not-allowed"
              >
                {loading ? "⏳ Deleting..." : "🗑️ Delete Rule"}
              </button>
            </div>
          </div>

          {status && (
            <div
              className={`rounded-xl border-2 px-5 py-4 text-sm font-medium shadow-lg ${
                status.tone === "error"
                  ? "border-rose-500/50 bg-rose-500/10 text-rose-200 shadow-rose-500/20"
                  : status.tone === "success"
                    ? "border-emerald-500/50 bg-emerald-500/10 text-emerald-200 shadow-emerald-500/20"
                    : "border-cyan-500/50 bg-cyan-500/10 text-cyan-200 shadow-cyan-500/20"
              }`}
            >
              <div className="flex items-start gap-3">
                <span className="text-lg">
                  {status.tone === "error" ? "❌" : status.tone === "success" ? "✅" : "ℹ️"}
                </span>
                <span className="flex-1">{status.message}</span>
              </div>
            </div>
          )}

          <div className="rounded-2xl border border-white/10 bg-gradient-to-br from-slate-900/60 to-slate-950/60 shadow-xl">
            <div className="flex items-center justify-between border-b border-white/10 bg-white/5 px-6 py-4">
              <div className="flex items-center gap-3">
                <span className="text-xl">📋</span>
                <h3 className="text-base font-semibold uppercase tracking-[0.2em] text-slate-300">Rule Set</h3>
              </div>
              <div className="flex items-center gap-3">
                <button
                  onClick={handleRefresh}
                  disabled={loading}
                  className="flex items-center gap-2 rounded-lg border border-cyan-500/30 bg-cyan-500/10 px-4 py-2 text-xs font-semibold text-cyan-300 transition hover:bg-cyan-500/20 hover:border-cyan-400/50 disabled:opacity-50 disabled:cursor-not-allowed"
                  title="Refresh rules from database"
                >
                  {loading ? (
                    <>
                      <span className="animate-spin">⏳</span>
                      <span>Refreshing...</span>
                    </>
                  ) : (
                    <>
                      <span>🔄</span>
                      <span>Refresh</span>
                    </>
                  )}
                </button>
                <div className="flex items-center gap-2 rounded-full bg-cyan-500/20 px-4 py-2">
                  <span className="text-sm font-semibold text-cyan-300">{rules.length}</span>
                  <span className="text-xs text-slate-400">entries</span>
                </div>
              </div>
            </div>
            <div className="overflow-x-auto max-h-[500px] overflow-y-auto">
              <table className="w-full text-left text-sm">
                <thead className="sticky top-0 bg-slate-900/95 backdrop-blur-sm text-xs uppercase tracking-[0.2em] text-slate-400">
                  <tr>
                    <th className="px-6 py-4 font-semibold">#</th>
                    <th className="px-6 py-4 font-semibold">Rule</th>
                  </tr>
                </thead>
                <tbody>
                  {rules.length === 0 && (
                    <tr>
                      <td colSpan={2} className="px-6 py-12 text-center">
                        <div className="flex flex-col items-center gap-3">
                          <span className="text-4xl">📝</span>
                          <p className="text-slate-400">No rules loaded</p>
                          <p className="text-xs text-slate-500">Use the refresh button above to load rules</p>
                        </div>
                      </td>
                    </tr>
                  )}
                  {rules.map((rule, idx) => (
                    <tr 
                      key={`${rule}-${idx}`} 
                      className="border-t border-white/5 transition hover:bg-white/5"
                    >
                      <td className="px-6 py-4 text-slate-400 font-mono">{idx + 1}</td>
                      <td className="px-6 py-4 text-slate-200">{rule}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </div>
        </div>
      </section>

      <Footer />
    </main>
  );
}

