"use client";

import React, { useEffect, useRef, useState, useCallback } from "react";
import Sidebar from "../components/Sidebar";
import TopBar from "../components/TopBar";
import {
  fetchJiraTickets,
  fetchJiraConfig,
  fetchJiraTicketStatus,
  createJiraTicket,
  searchJiraUsers,
  JiraTicket,
  JiraConfig,
  Group,
  fetchGroups,
  formatRelativeTime,
} from "../lib/api";

// ─── Helpers ──────────────────────────────────────────────────────────────────

function formatDate(iso: string): string {
  if (!iso) return "—";
  try {
    return new Date(iso).toLocaleString("en-GB", {
      day: "2-digit", month: "short", year: "numeric",
      hour: "2-digit", minute: "2-digit",
    });
  } catch {
    return iso;
  }
}

function priorityColor(priority: string): string {
  switch ((priority || "").toLowerCase()) {
    case "highest": return "#EF4444";
    case "high":    return "#F97316";
    case "medium":  return "#EAB308";
    case "low":     return "#3B82F6";
    case "lowest":  return "#71717A";
    default:        return "#A78BFA";
  }
}

function statusColor(status: string): string {
  const s = (status || "").toLowerCase();
  if (s.includes("done") || s.includes("closed") || s.includes("resolved")) return "#34D399";
  if (s.includes("progress") || s.includes("review")) return "#60A5FA";
  if (s.includes("todo") || s.includes("open") || s === "unknown") return "#A78BFA";
  return "#EAB308";
}

function PriorityBadge({ priority }: { priority: string }) {
  const color = priorityColor(priority);
  return (
    <span
      className="text-[9px] font-bold uppercase tracking-[0.1em] px-2 py-0.5 rounded-full border"
      style={{ color, borderColor: `${color}40`, background: `${color}15` }}
    >
      {priority || "Medium"}
    </span>
  );
}

function StatusBadge({ status }: { status: string }) {
  const color = statusColor(status);
  return (
    <span
      className="text-[9px] font-bold uppercase tracking-[0.1em] px-2 py-0.5 rounded-full border flex items-center gap-1"
      style={{ color, borderColor: `${color}40`, background: `${color}15` }}
    >
      <span className="w-1.5 h-1.5 rounded-full flex-shrink-0" style={{ background: color }} />
      {status === "Unknown" ? "Pending" : status}
    </span>
  );
}

// ─── Create Ticket Modal ───────────────────────────────────────────────────────

type JiraUser = { account_id: string; display_name: string; email: string };

function CreateTicketModal({
  config,
  onClose,
  onCreated,
}: {
  config: JiraConfig;
  onClose: () => void;
  onCreated: (ticket: { key: string; url: string }) => void;
}) {
  const [summary, setSummary] = useState("");
  const [description, setDescription] = useState("");
  const [projectKey, setProjectKey] = useState(config.default_project || "");
  const [issueType, setIssueType] = useState("Task");
  const [priority, setPriority] = useState("Medium");
  const [labels, setLabels] = useState("thirdeye");
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState("");
  const [errorDetails, setErrorDetails] = useState<string>("");

  // Assignee search
  const [assigneeQuery, setAssigneeQuery] = useState("");
  const [assigneeSuggestions, setAssigneeSuggestions] = useState<JiraUser[]>([]);
  const [selectedAssignee, setSelectedAssignee] = useState<JiraUser | null>(null);
  const [searchingAssignee, setSearchingAssignee] = useState(false);
  const assigneeTimeout = useRef<ReturnType<typeof setTimeout> | null>(null);

  const handleAssigneeInput = (val: string) => {
    setAssigneeQuery(val);
    setSelectedAssignee(null);
    if (assigneeTimeout.current) clearTimeout(assigneeTimeout.current);
    if (val.trim().length < 2) { setAssigneeSuggestions([]); return; }
    assigneeTimeout.current = setTimeout(async () => {
      setSearchingAssignee(true);
      try {
        const users = await searchJiraUsers(val.trim());
        setAssigneeSuggestions(users);
      } catch {
        setAssigneeSuggestions([]);
      } finally {
        setSearchingAssignee(false);
      }
    }, 350);
  };

  const selectAssignee = (user: JiraUser) => {
    setSelectedAssignee(user);
    setAssigneeQuery(user.display_name);
    setAssigneeSuggestions([]);
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!summary.trim()) return;
    setLoading(true);
    setError("");
    setErrorDetails("");
    try {
      const result = await createJiraTicket({
        summary: summary.trim(),
        description: description.trim(),
        project_key: projectKey || undefined,
        issue_type: issueType,
        priority,
        labels: labels.split(",").map((l) => l.trim()).filter(Boolean),
        assignee_account_id: selectedAssignee?.account_id || undefined,
      });
      if (result.ok && result.key) {
        onCreated({ key: result.key, url: result.url || "" });
      } else {
        setError(result.error || "Failed to create ticket");
        if (result.details) {
          const d = result.details;
          if (typeof d === "object" && d !== null) {
            setErrorDetails(JSON.stringify(d, null, 2));
          } else {
            setErrorDetails(String(d));
          }
        }
      }
    } catch (err: unknown) {
      setError(err instanceof Error ? err.message : String(err));
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center p-4">
      <div className="absolute inset-0 bg-black/60 backdrop-blur-sm" onClick={onClose} />
      <div
        className="relative neon-card-gradient rounded-2xl border border-[#A78BFA]/20 w-full max-w-lg shadow-2xl animate-fade-in-scale opacity-0 max-h-[90vh] overflow-y-auto"
        style={{ boxShadow: "0 0 60px rgba(167,139,250,0.12)" }}
      >
        <div className="p-6 border-b border-white/5">
          <div className="flex items-center justify-between">
            <div className="flex items-center gap-3">
              <div className="w-8 h-8 rounded-lg bg-[rgba(167,139,250,0.15)] flex items-center justify-center">
                <span className="material-symbols-outlined text-[#A78BFA]" style={{ fontSize: "16px" }}>add_task</span>
              </div>
              <div>
                <h3 className="text-[14px] font-bold text-white">Create Jira Ticket</h3>
                <p className="text-[10px] text-zinc-500 uppercase tracking-wider">Manual ticket creation</p>
              </div>
            </div>
            <button onClick={onClose} className="text-zinc-500 hover:text-zinc-300 transition-colors">
              <span className="material-symbols-outlined">close</span>
            </button>
          </div>
        </div>

        <form onSubmit={handleSubmit} className="p-6 space-y-4">
          {/* Summary */}
          <div>
            <label className="block text-[10px] font-bold text-zinc-400 uppercase tracking-wider mb-1.5">
              Summary *
            </label>
            <input
              type="text"
              value={summary}
              onChange={(e) => setSummary(e.target.value)}
              placeholder="Short, actionable ticket title..."
              required
              className="w-full bg-[#141419] border border-white/10 rounded-lg px-3 py-2.5 text-[13px] text-zinc-200 placeholder-zinc-600 focus:outline-none focus:border-[#A78BFA]/50"
            />
          </div>

          {/* Description */}
          <div>
            <label className="block text-[10px] font-bold text-zinc-400 uppercase tracking-wider mb-1.5">
              Description
            </label>
            <textarea
              value={description}
              onChange={(e) => setDescription(e.target.value)}
              placeholder="Full description, context, next steps..."
              rows={3}
              className="w-full bg-[#141419] border border-white/10 rounded-lg px-3 py-2.5 text-[13px] text-zinc-200 placeholder-zinc-600 focus:outline-none focus:border-[#A78BFA]/50 resize-none"
            />
          </div>

          {/* Project / Type / Priority */}
          <div className="grid grid-cols-3 gap-3">
            <div>
              <label className="block text-[10px] font-bold text-zinc-400 uppercase tracking-wider mb-1.5">
                Project Key
              </label>
              <input
                type="text"
                value={projectKey}
                onChange={(e) => setProjectKey(e.target.value.toUpperCase())}
                placeholder={config.default_project || "ENG"}
                className="w-full bg-[#141419] border border-white/10 rounded-lg px-3 py-2.5 text-[13px] text-zinc-200 placeholder-zinc-600 focus:outline-none focus:border-[#A78BFA]/50 font-mono-data"
              />
            </div>
            <div>
              <label className="block text-[10px] font-bold text-zinc-400 uppercase tracking-wider mb-1.5">
                Type
              </label>
              <select
                value={issueType}
                onChange={(e) => setIssueType(e.target.value)}
                className="w-full bg-[#141419] border border-white/10 rounded-lg px-3 py-2.5 text-[13px] text-zinc-200 focus:outline-none focus:border-[#A78BFA]/50"
              >
                {["Task", "Bug", "Story", "Epic"].map((t) => (
                  <option key={t} value={t}>{t}</option>
                ))}
              </select>
            </div>
            <div>
              <label className="block text-[10px] font-bold text-zinc-400 uppercase tracking-wider mb-1.5">
                Priority
              </label>
              <select
                value={priority}
                onChange={(e) => setPriority(e.target.value)}
                className="w-full bg-[#141419] border border-white/10 rounded-lg px-3 py-2.5 text-[13px] text-zinc-200 focus:outline-none focus:border-[#A78BFA]/50"
              >
                {["Highest", "High", "Medium", "Low", "Lowest"].map((p) => (
                  <option key={p} value={p}>{p}</option>
                ))}
              </select>
            </div>
          </div>

          {/* Assignee search */}
          <div className="relative">
            <label className="block text-[10px] font-bold text-zinc-400 uppercase tracking-wider mb-1.5">
              Assignee
            </label>
            <div className="relative">
              <span className="material-symbols-outlined absolute left-3 top-1/2 -translate-y-1/2 text-zinc-500" style={{ fontSize: "15px" }}>
                {selectedAssignee ? "account_circle" : "person_search"}
              </span>
              <input
                type="text"
                value={assigneeQuery}
                onChange={(e) => handleAssigneeInput(e.target.value)}
                placeholder="Search by name or email..."
                className="w-full bg-[#141419] border border-white/10 rounded-lg pl-9 pr-9 py-2.5 text-[13px] text-zinc-200 placeholder-zinc-600 focus:outline-none focus:border-[#A78BFA]/50"
                style={{ borderColor: selectedAssignee ? "rgba(167,139,250,0.4)" : undefined }}
              />
              {searchingAssignee && (
                <div className="absolute right-3 top-1/2 -translate-y-1/2 w-3 h-3 border-2 border-[#A78BFA]/30 border-t-[#A78BFA] rounded-full animate-spin" />
              )}
              {selectedAssignee && (
                <button
                  type="button"
                  onClick={() => { setSelectedAssignee(null); setAssigneeQuery(""); }}
                  className="absolute right-3 top-1/2 -translate-y-1/2 text-zinc-500 hover:text-zinc-300"
                >
                  <span className="material-symbols-outlined" style={{ fontSize: "15px" }}>close</span>
                </button>
              )}
            </div>
            {/* Dropdown suggestions */}
            {assigneeSuggestions.length > 0 && (
              <div className="absolute z-10 w-full mt-1 bg-[#1a1a20] border border-white/10 rounded-lg shadow-2xl overflow-hidden">
                {assigneeSuggestions.map((u) => (
                  <button
                    key={u.account_id}
                    type="button"
                    onClick={() => selectAssignee(u)}
                    className="w-full flex items-center gap-3 px-3 py-2.5 text-left hover:bg-[#A78BFA]/10 transition-colors"
                  >
                    <div className="w-7 h-7 rounded-full bg-[#A78BFA]/20 flex items-center justify-center flex-shrink-0">
                      <span className="material-symbols-outlined text-[#A78BFA]" style={{ fontSize: "14px" }}>person</span>
                    </div>
                    <div className="min-w-0">
                      <p className="text-[12px] text-zinc-200 truncate">{u.display_name}</p>
                      <p className="text-[10px] text-zinc-500 truncate">{u.email}</p>
                    </div>
                  </button>
                ))}
              </div>
            )}
            {assigneeQuery.trim().length >= 2 && !searchingAssignee && assigneeSuggestions.length === 0 && !selectedAssignee && (
              <p className="mt-1 text-[10px] text-zinc-600">No users found for &ldquo;{assigneeQuery}&rdquo;</p>
            )}
          </div>

          {/* Labels */}
          <div>
            <label className="block text-[10px] font-bold text-zinc-400 uppercase tracking-wider mb-1.5">
              Labels <span className="text-zinc-600 normal-case font-normal">(comma-separated, no spaces in label)</span>
            </label>
            <input
              type="text"
              value={labels}
              onChange={(e) => setLabels(e.target.value)}
              placeholder="thirdeye,dashboard"
              className="w-full bg-[#141419] border border-white/10 rounded-lg px-3 py-2.5 text-[13px] text-zinc-200 placeholder-zinc-600 focus:outline-none focus:border-[#A78BFA]/50"
            />
          </div>

          {/* Error */}
          {error && (
            <div className="p-3 rounded-lg bg-red-500/10 border border-red-500/20 space-y-1">
              <p className="text-[12px] text-red-400 font-semibold">{error}</p>
              {errorDetails && (
                <pre className="text-[10px] text-red-500/70 whitespace-pre-wrap break-all font-mono-data max-h-24 overflow-y-auto">
                  {errorDetails}
                </pre>
              )}
            </div>
          )}

          <div className="flex gap-3 pt-2">
            <button
              type="button"
              onClick={onClose}
              className="flex-1 px-4 py-2.5 rounded-lg border border-white/10 text-[12px] text-zinc-400 hover:text-zinc-200 hover:border-white/20 transition-colors"
            >
              Cancel
            </button>
            <button
              type="submit"
              disabled={loading || !summary.trim()}
              className="flex-1 px-4 py-2.5 rounded-lg bg-[#A78BFA] text-[12px] font-semibold text-[#1a0040] hover:bg-[#c4b5fd] transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2"
            >
              {loading ? (
                <div className="w-4 h-4 border-2 border-[#1a0040]/30 border-t-[#1a0040] rounded-full animate-spin" />
              ) : (
                <span className="material-symbols-outlined" style={{ fontSize: "16px" }}>add_task</span>
              )}
              {loading ? "Creating..." : "Create Ticket"}
            </button>
          </div>
        </form>
      </div>
    </div>
  );
}

// ─── Ticket Detail Modal ───────────────────────────────────────────────────────

function TicketDetailModal({
  ticket,
  onClose,
  onRefreshStatus,
}: {
  ticket: JiraTicket;
  onClose: () => void;
  onRefreshStatus: (key: string) => void;
}) {
  const [refreshing, setRefreshing] = useState(false);

  const handleRefresh = async () => {
    setRefreshing(true);
    await onRefreshStatus(ticket.jira_key);
    setRefreshing(false);
  };

  const openInJira = () => {
    if (ticket.jira_url) window.open(ticket.jira_url, "_blank", "noopener,noreferrer");
  };

  const priorColor = priorityColor(ticket.jira_priority);

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center p-4" onClick={onClose}>
      <div className="absolute inset-0 bg-black/60 backdrop-blur-sm" />
      <div
        className="relative w-full max-w-md rounded-2xl border border-[#A78BFA]/20 shadow-2xl overflow-hidden"
        style={{ background: "linear-gradient(135deg,#0f0c18 0%,#13101f 100%)", boxShadow: "0 0 60px rgba(167,139,250,0.15)" }}
        onClick={(e) => e.stopPropagation()}
      >
        {/* Top accent bar coloured by priority */}
        <div className="h-[3px] w-full" style={{ background: `linear-gradient(90deg, ${priorColor}, transparent)` }} />

        {/* Header */}
        <div className="px-6 pt-5 pb-4 flex items-start justify-between gap-3 border-b border-white/5">
          <div className="flex items-center gap-3 min-w-0">
            <div className="w-9 h-9 rounded-lg flex items-center justify-center flex-shrink-0 bg-[rgba(167,139,250,0.15)]">
              <span className="material-symbols-outlined text-[#A78BFA]" style={{ fontSize: "18px" }}>confirmation_number</span>
            </div>
            <div className="min-w-0">
              <p className="text-[11px] font-mono-data text-[#A78BFA] tracking-widest uppercase mb-0.5">{ticket.jira_key || "—"}</p>
              <h3 className="text-[14px] font-bold text-white leading-snug line-clamp-2">
                {ticket.jira_summary || "(no summary)"}
              </h3>
            </div>
          </div>
          <button onClick={onClose} className="text-zinc-500 hover:text-zinc-300 transition-colors flex-shrink-0 mt-0.5">
            <span className="material-symbols-outlined">close</span>
          </button>
        </div>

        {/* Body */}
        <div className="px-6 py-5 space-y-4">
          {/* Status + Priority row */}
          <div className="grid grid-cols-2 gap-3">
            <div className="bg-[#0c0814]/60 rounded-xl p-3.5 border border-white/5">
              <p className="text-[9px] font-mono-data text-zinc-500 uppercase tracking-widest mb-2">Status</p>
              <StatusBadge status={ticket.status} />
            </div>
            <div className="bg-[#0c0814]/60 rounded-xl p-3.5 border border-white/5">
              <p className="text-[9px] font-mono-data text-zinc-500 uppercase tracking-widest mb-2">Priority</p>
              <PriorityBadge priority={ticket.jira_priority} />
            </div>
          </div>

          {/* Meta grid */}
          <div className="grid grid-cols-2 gap-3 text-[12px]">
            <div className="bg-[#0c0814]/60 rounded-xl p-3.5 border border-white/5">
              <p className="text-[9px] font-mono-data text-zinc-500 uppercase tracking-widest mb-1.5">Raised</p>
              <p className="text-zinc-300 font-medium">{formatDate(ticket.raised_at)}</p>
            </div>
            <div className="bg-[#0c0814]/60 rounded-xl p-3.5 border border-white/5">
              <p className="text-[9px] font-mono-data text-zinc-500 uppercase tracking-widest mb-1.5">Group</p>
              <p className="text-zinc-300 font-mono-data truncate">{ticket.group_id || "—"}</p>
            </div>
            {ticket.assignee && (
              <div className="col-span-2 bg-[#0c0814]/60 rounded-xl p-3.5 border border-white/5">
                <p className="text-[9px] font-mono-data text-zinc-500 uppercase tracking-widest mb-1.5">Assignee</p>
                <div className="flex items-center gap-2">
                  <span className="material-symbols-outlined text-zinc-400" style={{ fontSize: "16px" }}>account_circle</span>
                  <p className="text-zinc-300">{ticket.assignee}</p>
                </div>
              </div>
            )}
          </div>

          {/* Jira URL preview */}
          {ticket.jira_url && (
            <div className="flex items-center gap-2 px-3 py-2.5 rounded-lg bg-[#0c0814]/60 border border-white/5">
              <span className="material-symbols-outlined text-zinc-600" style={{ fontSize: "14px" }}>link</span>
              <p className="text-[10px] font-mono-data text-zinc-600 truncate flex-1">{ticket.jira_url}</p>
            </div>
          )}
        </div>

        {/* Footer actions */}
        <div className="px-6 pb-6 flex items-center gap-3">
          {/* Primary — open in Jira */}
          <button
            onClick={openInJira}
            disabled={!ticket.jira_url}
            className="flex-1 flex items-center justify-center gap-2 px-4 py-3 rounded-xl bg-[#A78BFA] text-[13px] font-bold text-[#1a0040] hover:bg-[#c4b5fd] active:scale-95 transition-all disabled:opacity-40 disabled:cursor-not-allowed shadow-[0_0_20px_rgba(167,139,250,0.3)]"
          >
            <span className="material-symbols-outlined" style={{ fontSize: "17px" }}>open_in_new</span>
            Open in Jira
          </button>

          {/* Secondary — refresh */}
          <button
            onClick={handleRefresh}
            disabled={refreshing || !ticket.jira_key}
            className="w-11 h-11 flex items-center justify-center rounded-xl border border-white/10 text-zinc-400 hover:text-[#A78BFA] hover:border-[#A78BFA]/30 active:scale-95 transition-all disabled:opacity-40"
            title="Refresh status from Jira"
          >
            <span className={`material-symbols-outlined ${refreshing ? "animate-spin" : ""}`} style={{ fontSize: "18px" }}>refresh</span>
          </button>
        </div>
      </div>
    </div>
  );
}

// ─── Ticket Row ────────────────────────────────────────────────────────────────

function TicketRow({
  ticket,
  onSelect,
  onRefreshStatus,
}: {
  ticket: JiraTicket;
  onSelect: (t: JiraTicket) => void;
  onRefreshStatus: (key: string) => void;
}) {
  return (
    <tr
      className="border-b border-white/5 cursor-pointer hover:bg-[rgba(167,139,250,0.07)] active:bg-[rgba(167,139,250,0.12)] transition-colors group"
      onClick={() => onSelect(ticket)}
    >
      <td className="px-4 py-3">
        <div className="flex items-center gap-1.5">
          <span className="text-[#A78BFA] font-bold text-[12px] font-mono-data group-hover:underline underline-offset-2">
            {ticket.jira_key || "—"}
          </span>
          <span className="material-symbols-outlined text-zinc-700 group-hover:text-[#A78BFA] transition-colors" style={{ fontSize: "11px" }}>
            chevron_right
          </span>
        </div>
      </td>
      <td className="px-4 py-3 max-w-[300px]">
        <p className="text-[12px] text-zinc-300 truncate group-hover:text-white transition-colors">{ticket.jira_summary || "—"}</p>
      </td>
      <td className="px-4 py-3">
        <StatusBadge status={ticket.status} />
      </td>
      <td className="px-4 py-3">
        <PriorityBadge priority={ticket.jira_priority} />
      </td>
      <td className="px-4 py-3">
        <span className="text-[11px] text-zinc-500 font-mono-data">{ticket.group_id || "—"}</span>
      </td>
      <td className="px-4 py-3">
        <span className="text-[11px] text-zinc-500">{formatDate(ticket.raised_at)}</span>
      </td>
      <td className="px-4 py-3">
        {ticket.jira_key && (
          <button
            onClick={(e) => { e.stopPropagation(); onRefreshStatus(ticket.jira_key); }}
            className="text-zinc-600 hover:text-[#A78BFA] transition-colors"
            title="Refresh status from Jira"
          >
            <span className="material-symbols-outlined" style={{ fontSize: "16px" }}>refresh</span>
          </button>
        )}
      </td>
    </tr>
  );
}

// ─── Main Page ─────────────────────────────────────────────────────────────────

type SortKey = "raised_at" | "jira_key" | "jira_priority" | "status";

export default function JiraPage() {
  const [tickets, setTickets] = useState<JiraTicket[]>([]);
  const [config, setConfig] = useState<JiraConfig | null>(null);
  const [groups, setGroups] = useState<Group[]>([]);
  const [loading, setLoading] = useState(true);
  const [showCreate, setShowCreate] = useState(false);
  const [selectedTicket, setSelectedTicket] = useState<JiraTicket | null>(null);
  const [successMsg, setSuccessMsg] = useState("");

  // Filters
  const [filterGroup, setFilterGroup] = useState("");
  const [filterStatus, setFilterStatus] = useState("");
  const [filterPriority, setFilterPriority] = useState("");
  const [dateFrom, setDateFrom] = useState("");
  const [dateTo, setDateTo] = useState("");
  const [search, setSearch] = useState("");

  // Sorting
  const [sortKey, setSortKey] = useState<SortKey>("raised_at");
  const [sortAsc, setSortAsc] = useState(false);

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const [tix, cfg, grps] = await Promise.all([
        fetchJiraTickets({ group_id: filterGroup || undefined, date_from: dateFrom || undefined, date_to: dateTo || undefined }),
        fetchJiraConfig(),
        fetchGroups(),
      ]);
      setTickets(tix);
      setConfig(cfg);
      setGroups(grps);
    } catch (e) {
      console.error(e);
    } finally {
      setLoading(false);
    }
  }, [filterGroup, dateFrom, dateTo]);

  useEffect(() => { load(); }, [load]);

  const refreshStatus = async (key: string) => {
    try {
      const data = await fetchJiraTicketStatus(key);
      setTickets((prev) =>
        prev.map((t) =>
          t.jira_key === key
            ? { ...t, status: data.status, assignee: data.assignee, jira_summary: data.summary || t.jira_summary }
            : t
        )
      );
    } catch (e) {
      console.error("Status refresh failed:", e);
    }
  };

  const handleCreated = (ticket: { key: string; url: string }) => {
    setShowCreate(false);
    setSuccessMsg(`Ticket ${ticket.key} created successfully!`);
    setTimeout(() => setSuccessMsg(""), 4000);
    load();
  };

  // Filter + sort
  const severityRank: Record<string, number> = { Highest: 5, High: 4, Medium: 3, Low: 2, Lowest: 1 };

  const displayed = tickets
    .filter((t) => {
      if (filterStatus && t.status !== filterStatus) return false;
      if (filterPriority && (t.jira_priority || "").toLowerCase() !== filterPriority.toLowerCase()) return false;
      if (search && !t.jira_key.toLowerCase().includes(search.toLowerCase()) &&
          !t.jira_summary.toLowerCase().includes(search.toLowerCase())) return false;
      return true;
    })
    .sort((a, b) => {
      let cmp = 0;
      if (sortKey === "raised_at") cmp = a.raised_at.localeCompare(b.raised_at);
      else if (sortKey === "jira_key") cmp = a.jira_key.localeCompare(b.jira_key);
      else if (sortKey === "jira_priority")
        cmp = (severityRank[a.jira_priority] || 3) - (severityRank[b.jira_priority] || 3);
      else if (sortKey === "status") cmp = a.status.localeCompare(b.status);
      return sortAsc ? cmp : -cmp;
    });

  const toggleSort = (key: SortKey) => {
    if (sortKey === key) setSortAsc((a) => !a);
    else { setSortKey(key); setSortAsc(false); }
  };

  const SortIcon = ({ k }: { k: SortKey }) => (
    <span className="material-symbols-outlined" style={{ fontSize: "12px" }}>
      {sortKey !== k ? "unfold_more" : sortAsc ? "expand_less" : "expand_more"}
    </span>
  );

  const openCount = tickets.filter(t => !["Done", "Closed", "Resolved"].includes(t.status)).length;
  const doneCount = tickets.filter(t => ["Done", "Closed", "Resolved"].includes(t.status)).length;
  const criticalCount = tickets.filter(t => ["Highest", "High"].includes(t.jira_priority)).length;

  const exportCSV = () => {
    const header = ["Key", "Summary", "Status", "Priority", "Group", "Raised At"].join(",");
    const rows = displayed.map((t) =>
      [t.jira_key, `"${t.jira_summary.replace(/"/g, '""')}"`, t.status, t.jira_priority, t.group_id, t.raised_at].join(",")
    );
    const blob = new Blob([[header, ...rows].join("\n")], { type: "text/csv" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url; a.download = "jira_tickets.csv"; a.click();
    URL.revokeObjectURL(url);
  };

  return (
    <div className="min-h-screen flex" style={{ backgroundColor: "#09090B" }}>
      <Sidebar />
      <div className="flex-1 ml-[240px] flex flex-col min-h-screen">
        <TopBar />
        <main className="flex-1 p-8">
          {/* Header */}
          <div className="flex items-start justify-between mb-8 animate-fade-in-up opacity-0">
            <div className="flex items-center gap-3">
              <div className="w-10 h-10 rounded-xl bg-[rgba(167,139,250,0.15)] flex items-center justify-center">
                <span className="material-symbols-outlined text-[#A78BFA]">bug_report</span>
              </div>
              <div>
                <h1 className="text-2xl font-bold text-white tracking-tight">Jira Tickets</h1>
                <p className="text-[11px] text-zinc-500 uppercase tracking-[0.2em]">
                  ThirdEye-raised · {config?.default_project || "All Projects"}
                </p>
              </div>
            </div>
            <div className="flex items-center gap-3">
              {config?.configured && (
                <div className="flex items-center gap-1.5 px-3 py-1.5 rounded-lg bg-emerald-500/10 border border-emerald-500/20">
                  <span className="w-1.5 h-1.5 rounded-full bg-emerald-400 animate-pulse" />
                  <span className="text-[10px] font-bold text-emerald-400 uppercase tracking-wider">
                    Jira Connected
                  </span>
                </div>
              )}
              <button
                onClick={exportCSV}
                className="flex items-center gap-2 px-3 py-2 rounded-lg border border-white/10 text-[11px] text-zinc-400 hover:text-zinc-200 hover:border-white/20 transition-colors"
              >
                <span className="material-symbols-outlined" style={{ fontSize: "15px" }}>download</span>
                Export CSV
              </button>
              {config?.configured && (
                <button
                  onClick={() => setShowCreate(true)}
                  className="flex items-center gap-2 px-4 py-2 rounded-lg bg-[#A78BFA] text-[12px] font-semibold text-[#1a0040] hover:bg-[#c4b5fd] transition-colors"
                >
                  <span className="material-symbols-outlined" style={{ fontSize: "16px" }}>add</span>
                  New Ticket
                </button>
              )}
            </div>
          </div>

          {/* Success message */}
          {successMsg && (
            <div className="mb-4 p-3 rounded-lg bg-emerald-500/10 border border-emerald-500/20 text-[12px] text-emerald-400 flex items-center gap-2 animate-fade-in-up opacity-0">
              <span className="material-symbols-outlined" style={{ fontSize: "16px" }}>check_circle</span>
              {successMsg}
            </div>
          )}

          {/* Jira not configured banner */}
          {config && !config.configured && (
            <div className="mb-6 p-4 rounded-xl bg-amber-500/10 border border-amber-500/20 flex items-center gap-3">
              <span className="material-symbols-outlined text-amber-400">warning</span>
              <div>
                <p className="text-[13px] font-semibold text-amber-300">Jira not configured</p>
                <p className="text-[11px] text-amber-600 mt-0.5">
                  Set JIRA_BASE_URL, JIRA_EMAIL, JIRA_API_TOKEN and ENABLE_JIRA=true in your .env to connect Jira.
                </p>
              </div>
            </div>
          )}

          {/* Stats */}
          <div className="grid grid-cols-4 gap-4 mb-6 animate-fade-in-up opacity-0 delay-100">
            {[
              { label: "Total Raised", value: tickets.length, icon: "confirmation_number", color: "#A78BFA" },
              { label: "Open", value: openCount, icon: "radio_button_unchecked", color: "#60A5FA" },
              { label: "Resolved", value: doneCount, icon: "check_circle", color: "#34D399" },
              { label: "High Priority", value: criticalCount, icon: "priority_high", color: "#F87171" },
            ].map((s) => (
              <div key={s.label} className="neon-card-gradient rounded-xl p-4 border border-white/5 flex items-center gap-4">
                <div className="w-10 h-10 rounded-lg flex items-center justify-center flex-shrink-0" style={{ background: `${s.color}18` }}>
                  <span className="material-symbols-outlined" style={{ fontSize: "18px", color: s.color }}>{s.icon}</span>
                </div>
                <div>
                  <p className="text-2xl font-bold text-white">{s.value}</p>
                  <p className="text-[10px] text-zinc-500 uppercase tracking-wider">{s.label}</p>
                </div>
              </div>
            ))}
          </div>

          {/* Filters */}
          <div className="flex items-center gap-3 flex-wrap mb-5 animate-fade-in-up opacity-0 delay-200">
            <div className="relative">
              <span className="material-symbols-outlined absolute left-3 top-1/2 -translate-y-1/2 text-zinc-500" style={{ fontSize: "15px" }}>
                search
              </span>
              <input
                type="text"
                placeholder="Search key or summary..."
                value={search}
                onChange={(e) => setSearch(e.target.value)}
                className="bg-[#141419] border border-white/10 rounded-lg pl-9 pr-4 py-2 text-[12px] text-zinc-200 placeholder-zinc-600 focus:outline-none focus:border-[#A78BFA]/50 w-52"
              />
            </div>

            <select
              value={filterGroup}
              onChange={(e) => setFilterGroup(e.target.value)}
              className="bg-[#141419] border border-white/10 rounded-lg px-3 py-2 text-[12px] text-zinc-300 focus:outline-none focus:border-[#A78BFA]/50"
            >
              <option value="">All Groups</option>
              {groups.map((g) => (
                <option key={g.group_id} value={g.group_id}>{g.group_name}</option>
              ))}
            </select>

            <select
              value={filterStatus}
              onChange={(e) => setFilterStatus(e.target.value)}
              className="bg-[#141419] border border-white/10 rounded-lg px-3 py-2 text-[12px] text-zinc-300 focus:outline-none focus:border-[#A78BFA]/50"
            >
              <option value="">All Statuses</option>
              {["To Do", "In Progress", "In Review", "Done", "Unknown"].map((s) => (
                <option key={s} value={s}>{s}</option>
              ))}
            </select>

            <select
              value={filterPriority}
              onChange={(e) => setFilterPriority(e.target.value)}
              className="bg-[#141419] border border-white/10 rounded-lg px-3 py-2 text-[12px] text-zinc-300 focus:outline-none focus:border-[#A78BFA]/50"
            >
              <option value="">All Priorities</option>
              {["Highest", "High", "Medium", "Low", "Lowest"].map((p) => (
                <option key={p} value={p}>{p}</option>
              ))}
            </select>

            <input
              type="date"
              title="From date"
              value={dateFrom ? dateFrom.slice(0, 10) : ""}
              onChange={(e) => setDateFrom(e.target.value ? new Date(e.target.value).toISOString() : "")}
              className="bg-[#141419] border border-white/10 rounded-lg px-3 py-2 text-[12px] text-zinc-300 focus:outline-none focus:border-[#A78BFA]/50"
            />
            <input
              type="date"
              title="To date"
              value={dateTo ? dateTo.slice(0, 10) : ""}
              onChange={(e) => setDateTo(e.target.value ? new Date(e.target.value).toISOString() : "")}
              className="bg-[#141419] border border-white/10 rounded-lg px-3 py-2 text-[12px] text-zinc-300 focus:outline-none focus:border-[#A78BFA]/50"
            />

            {(filterGroup || filterStatus || filterPriority || dateFrom || dateTo || search) && (
              <button
                onClick={() => { setFilterGroup(""); setFilterStatus(""); setFilterPriority(""); setDateFrom(""); setDateTo(""); setSearch(""); }}
                className="text-[10px] text-zinc-500 hover:text-zinc-300 uppercase tracking-wider px-3 py-2 rounded-lg border border-white/10 transition-colors flex items-center gap-1"
              >
                <span className="material-symbols-outlined" style={{ fontSize: "13px" }}>filter_alt_off</span>
                Clear
              </button>
            )}

            <button
              onClick={load}
              className="ml-auto flex items-center gap-1.5 text-[11px] text-zinc-500 hover:text-[#A78BFA] transition-colors"
            >
              <span className="material-symbols-outlined" style={{ fontSize: "15px" }}>refresh</span>
              Refresh
            </button>
          </div>

          {/* Table */}
          <div className="neon-card-gradient rounded-2xl border border-white/5 overflow-hidden animate-fade-in-up opacity-0 delay-300">
            {loading ? (
              <div className="flex flex-col items-center justify-center h-64 text-zinc-600">
                <div className="w-8 h-8 border-2 border-[#A78BFA]/30 border-t-[#A78BFA] rounded-full animate-spin mb-3" />
                <p className="text-[11px] uppercase tracking-wider">Loading tickets...</p>
              </div>
            ) : displayed.length === 0 ? (
              <div className="flex flex-col items-center justify-center h-64 text-zinc-600">
                <span className="material-symbols-outlined text-4xl mb-2">confirmation_number</span>
                <p className="text-[13px] uppercase tracking-wider">No tickets found</p>
                <p className="text-[10px] text-zinc-700 mt-1">Tickets appear after ThirdEye raises them via /jira or auto-raise</p>
              </div>
            ) : (
              <div className="overflow-x-auto">
                <table className="w-full">
                  <thead>
                    <tr className="border-b border-white/5 bg-[rgba(255,255,255,0.02)]">
                      {(
                        [
                          { label: "Key", key: "jira_key" },
                          { label: "Summary", key: null },
                          { label: "Status", key: "status" },
                          { label: "Priority", key: "jira_priority" },
                          { label: "Group", key: null },
                          { label: "Raised", key: "raised_at" },
                          { label: "", key: null },
                        ] as { label: string; key: SortKey | null }[]
                      ).map(({ label, key }) => (
                        <th
                          key={label}
                          className={`px-4 py-3 text-left text-[10px] font-bold text-zinc-500 uppercase tracking-wider ${key ? "cursor-pointer hover:text-zinc-300" : ""}`}
                          onClick={key ? () => toggleSort(key) : undefined}
                        >
                          <div className="flex items-center gap-1">
                            {label}
                            {key && <SortIcon k={key} />}
                          </div>
                        </th>
                      ))}
                    </tr>
                  </thead>
                  <tbody>
                    {displayed.map((ticket) => (
                      <TicketRow
                        key={ticket.id}
                        ticket={ticket}
                        onSelect={setSelectedTicket}
                        onRefreshStatus={refreshStatus}
                      />
                    ))}
                  </tbody>
                </table>
              </div>
            )}
          </div>

          <p className="text-[10px] text-zinc-700 mt-3">
            Showing {displayed.length} of {tickets.length} tickets
          </p>
        </main>
      </div>

      {showCreate && config && (
        <CreateTicketModal config={config} onClose={() => setShowCreate(false)} onCreated={handleCreated} />
      )}

      {selectedTicket && (
        <TicketDetailModal
          ticket={selectedTicket}
          onClose={() => setSelectedTicket(null)}
          onRefreshStatus={async (key) => {
            await refreshStatus(key);
            // Update the selected ticket's status in-place
            setSelectedTicket((prev) =>
              prev
                ? { ...prev, status: tickets.find((t) => t.jira_key === key)?.status ?? prev.status }
                : null
            );
          }}
        />
      )}
    </div>
  );
}
