"use client";

import { useState, useEffect, use } from "react";
import { useRouter } from "next/navigation";
import Link from "next/link";
import { formatDistanceToNow } from "date-fns";
import { ArrowLeftIcon, SendIcon, PaperclipIcon } from "lucide-react";
import {
  getTicket,
  getTicketTransactions,
  getQueues,
  previewTicket,
  updateTicket,
} from "@/lib/api";
import type {
  Ticket,
  Transaction,
  Queue,
  PreviewResult,
  UpdateResult,
} from "@/lib/types";
import { Separator } from "@/components/ui/separator";
import { cn } from "@/lib/utils";

const STATUS_COLORS: Record<string, string> = {
  new: "#8a8f98",
  open: "#7170ff",
  in_progress: "#f59e0b",
  resolved: "#22c55e",
  closed: "#6b7280",
};

const STATUS_LABELS: Record<string, string> = {
  new: "New",
  open: "Open",
  in_progress: "In progress",
  resolved: "Resolved",
  closed: "Closed",
};

const ALL_STATUSES = ["new", "open", "in_progress", "resolved", "closed"];

function getInitial(name: string): string {
  if (!name) return "?";
  return name.charAt(0).toUpperCase();
}

function getInitialColor(name: string): string {
  const colors = ["#5e6ad2", "#7170ff", "#828fff", "#f59e0b", "#22c55e"];
  let hash = 0;
  for (let i = 0; i < name.length; i++) {
    hash = name.charCodeAt(i) + ((hash << 5) - hash);
  }
  return colors[Math.abs(hash) % colors.length];
}

function TransactionBubble({
  tx,
}: {
  tx: Transaction;
}) {
  const isSystem =
    tx.transaction_type === "StatusChange" ||
    tx.transaction_type === "SetOwner" ||
    tx.transaction_type === "Create";
  const isAgent = tx.transaction_type === "Correspond" || tx.transaction_type === "Comment";

  if (isSystem) {
    const timeAgo = formatDistanceToNow(new Date(tx.created_at), {
      addSuffix: true,
    });
    let message = "";
    if (tx.transaction_type === "Create") {
      message = `Ticket created`;
    } else if (tx.transaction_type === "StatusChange") {
      const oldLabel = tx.old_value ? STATUS_LABELS[tx.old_value] || tx.old_value : "?";
      const newLabel = tx.new_value ? STATUS_LABELS[tx.new_value] || tx.new_value : "?";
      message = `${getInitial(tx.creator_id)} changed status from ${oldLabel} to ${newLabel}`;
    } else if (tx.transaction_type === "SetOwner") {
      message = tx.new_value
        ? `${getInitial(tx.creator_id)} assigned to ${tx.new_value}`
        : `${getInitial(tx.creator_id)} unassigned`;
    } else {
      message = tx.transaction_type;
    }

    return (
      <div className="flex justify-center py-2">
        <span className="text-xs text-muted-foreground">
          {message} · {timeAgo}
        </span>
      </div>
    );
  }

  const isInternal = tx.transaction_type === "Comment";
  const timeAgo = formatDistanceToNow(new Date(tx.created_at), {
    addSuffix: true,
  });

  return (
    <div
      className={cn(
        "flex gap-3 py-3 px-4",
        isAgent ? "flex-row-reverse" : ""
      )}
    >
      <div
        className="w-6 h-6 rounded-full flex items-center justify-center flex-shrink-0"
        style={{
          backgroundColor: isAgent
            ? getInitialColor(tx.creator_id)
            : "var(--muted)",
        }}
      >
        <span
          className="text-[11px] font-semibold"
          style={{ color: isAgent ? "#f7f8f8" : "var(--muted-foreground)" }}
        >
          {getInitial(tx.creator_id)}
        </span>
      </div>
      <div
        className={cn(
          "max-w-[75%] rounded-lg px-3 py-2 transition-all duration-150",
          isAgent
            ? "bg-primary/15 text-foreground"
            : isInternal
              ? "bg-muted border border-border text-foreground"
              : "bg-muted text-foreground"
        )}
      >
        {isInternal && (
          <div className="text-[10px] font-semibold text-chart-3 mb-0.5 uppercase tracking-wider">
            Internal note
          </div>
        )}
        <p className="text-sm whitespace-pre-wrap">
          {typeof tx.data === "object" && tx.data !== null && "body" in (tx.data as Record<string, unknown>)
            ? String((tx.data as Record<string, unknown>).body)
            : tx.transaction_type}
        </p>
        <p className="text-[10px] text-muted-foreground mt-1">{timeAgo}</p>
      </div>
    </div>
  );
}

export default function TicketDetailPage({
  params,
}: {
  params: Promise<{ id: string }>;
}) {
  const { id } = use(params);
  const router = useRouter();

  const [ticket, setTicket] = useState<Ticket | null>(null);
  const [transactions, setTransactions] = useState<Transaction[]>([]);
  const [queue, setQueue] = useState<Queue | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  // Reply
  const [replyText, setReplyText] = useState("");
  const [replyMode, setReplyMode] = useState<"public" | "internal">("public");

  // Status change
  const [statusSelectOpen, setStatusSelectOpen] = useState(false);
  const [pendingStatus, setPendingStatus] = useState<string | null>(null);
  const [preview, setPreview] = useState<PreviewResult | null>(null);
  const [previewLoading, setPreviewLoading] = useState(false);
  const [previewError, setPreviewError] = useState<string | null>(null);
  const [applyLoading, setApplyLoading] = useState(false);
  const [scripResults, setScripResults] = useState<UpdateResult["scrip_results"] | null>(null);

  const fetchData = async () => {
    setLoading(true);
    setError(null);

    const [ticketRes, txRes, queuesRes] = await Promise.all([
      getTicket(id),
      getTicketTransactions(id),
      getQueues(),
    ]);

    if (ticketRes.error) {
      setError(ticketRes.error);
    } else {
      setTicket(ticketRes.data);
    }

    if (txRes.error) {
      setError((prev) => prev || txRes.error);
    } else {
      setTransactions(txRes.data ?? []);
    }

    if (queuesRes.data && ticketRes.data) {
      const q = queuesRes.data.find((q) => q.id === ticketRes.data!.queue_id);
      if (q) setQueue(q);
    }

    setLoading(false);
  };

  useEffect(() => {
    fetchData();
  }, [id]);

  const handleStatusSelect = async (newStatus: string) => {
    setPendingStatus(newStatus);
    setStatusSelectOpen(false);
    setPreview(null);
    setPreviewError(null);
    setScripResults(null);

    if (newStatus === ticket?.status) return;

    setPreviewLoading(true);
    const { data, error } = await previewTicket(id, { status: newStatus });
    setPreviewLoading(false);

    if (error) {
      setPreviewError(error);
      setPendingStatus(null);
    } else {
      setPreview(data);
    }
  };

  const handleApplyStatus = async () => {
    if (!pendingStatus) return;
    setApplyLoading(true);
    setPreviewError(null);

    const { data, error } = await updateTicket(id, { status: pendingStatus });

    setApplyLoading(false);

    if (error) {
      setPreviewError(error);
    } else if (data) {
      setTicket(data.ticket);
      setScripResults(data.scrip_results);
      setPreview(null);
      setPendingStatus(null);
      // Refresh transactions
      const txRes = await getTicketTransactions(id);
      if (txRes.data) setTransactions(txRes.data);
    }
  };

  const handleCancelStatus = () => {
    setPendingStatus(null);
    setPreview(null);
    setPreviewError(null);
    setScripResults(null);
  };

  if (loading) {
    return (
      <div className="flex h-full">
        <div className="flex-1 p-4 space-y-4">
          {Array.from({ length: 6 }).map((_, i) => (
            <div key={i} className="flex gap-3">
              <div className="w-6 h-6 rounded-full bg-muted animate-pulse" />
              <div className="flex-1 space-y-2">
                <div className="h-3 bg-muted rounded animate-pulse w-3/4" />
                <div className="h-3 bg-muted rounded animate-pulse w-1/2" />
              </div>
            </div>
          ))}
        </div>
        <div className="w-80 bg-sidebar border-l border-border p-4 space-y-3">
          {Array.from({ length: 5 }).map((_, i) => (
            <div key={i} className="h-6 bg-muted rounded animate-pulse" />
          ))}
        </div>
      </div>
    );
  }

  if (error && !ticket) {
    return (
      <div className="flex flex-col items-center justify-center h-full">
        <p className="text-destructive text-sm">{error}</p>
        <button
          onClick={fetchData}
          className="mt-2 text-sm text-primary hover:text-primary/80 transition-all duration-150"
        >
          Retry
        </button>
      </div>
    );
  }

  if (!ticket) {
    return (
      <div className="flex flex-col items-center justify-center h-full">
        <p className="text-muted-foreground text-sm">Ticket not found</p>
      </div>
    );
  }

  const currentStatusColor =
    STATUS_COLORS[ticket.status] || STATUS_COLORS.new;
  const currentStatusLabel =
    STATUS_LABELS[ticket.status] || ticket.status;

  return (
    <div className="flex h-full">
      {/* Left panel — conversation */}
      <div className="flex-1 flex flex-col min-w-0">
        {/* Header */}
        <div className="flex items-center gap-3 px-4 py-2.5 border-b border-border">
          <Link
            href="/"
            className="flex items-center gap-1.5 text-xs text-muted-foreground hover:text-foreground transition-all duration-150"
          >
            <ArrowLeftIcon className="w-3.5 h-3.5" />
            All tickets
          </Link>
        </div>

        {/* Title */}
        <div className="px-4 py-3 border-b border-border">
          <h1 className="text-sm font-semibold text-foreground truncate">
            {ticket.subject}
          </h1>
          <p className="text-xs text-muted-foreground mt-0.5">
            <span className="font-mono">{ticket.id.slice(0, 8)}</span> · {queue?.name || ticket.queue_id}
          </p>
        </div>

        {/* Conversation */}
        <div className="flex-1 overflow-y-auto">
          {transactions.length === 0 && (
            <div className="flex flex-col items-center justify-center py-20">
              <p className="text-sm text-muted-foreground">
                No activity yet
              </p>
            </div>
          )}
          {transactions.map((tx) => (
            <TransactionBubble key={tx.id} tx={tx} />
          ))}
        </div>

        {/* Reply box */}
        <div className="border-t border-border bg-sidebar p-3">
          {/* Toggle tabs */}
          <div className="flex gap-0.5 mb-2 p-0.5 rounded-lg bg-background w-fit">
            <button
              onClick={() => setReplyMode("public")}
              className={cn(
                "px-2.5 py-1 rounded-md text-xs font-medium transition-all duration-150",
                replyMode === "public"
                  ? "bg-primary text-primary-foreground"
                  : "text-muted-foreground hover:text-foreground"
              )}
            >
              Reply
            </button>
            <button
              onClick={() => setReplyMode("internal")}
              className={cn(
                "px-2.5 py-1 rounded-md text-xs font-medium transition-all duration-150",
                replyMode === "internal"
                  ? "bg-primary text-primary-foreground"
                  : "text-muted-foreground hover:text-foreground"
              )}
            >
              Internal note
            </button>
          </div>

          <div className="flex items-end gap-2">
            <textarea
              value={replyText}
              onChange={(e) => setReplyText(e.target.value)}
              placeholder="Reply to this ticket..."
              rows={2}
              className="flex-1 px-3 py-2 rounded-lg bg-background border border-border text-sm text-foreground placeholder:text-muted-foreground outline-none focus:border-primary focus:ring-1 focus:ring-primary resize-none transition-all duration-150"
            />
            <div className="flex items-center gap-1">
              <button className="w-8 h-8 flex items-center justify-center rounded-lg text-muted-foreground hover:text-foreground hover:bg-accent transition-all duration-150" title="Attach file (coming soon)">
                <PaperclipIcon className="w-4 h-4" />
              </button>
              <button
                disabled={!replyText.trim()}
                className={cn(
                  "w-8 h-8 flex items-center justify-center rounded-lg transition-all duration-150",
                  replyText.trim()
                    ? "bg-primary text-primary-foreground hover:bg-primary/80"
                    : "bg-muted text-muted-foreground cursor-not-allowed"
                )}
              >
                <SendIcon className="w-4 h-4" />
              </button>
            </div>
          </div>
        </div>
      </div>

      {/* Right panel — properties */}
      <div className="w-80 flex-shrink-0 bg-sidebar border-l border-border flex flex-col overflow-y-auto">
        <div className="p-4 space-y-5">
          {/* Section: Status */}
          <div>
            <h3 className="text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-2">
              Status
            </h3>
            <div className="relative">
              <button
                onClick={() => setStatusSelectOpen(!statusSelectOpen)}
                className="w-full flex items-center gap-3 px-4 py-2.5 rounded-lg border border-border bg-background text-sm hover:border-foreground/20 transition-all duration-150"
              >
                <span
                  className="w-3 h-3 rounded-full flex-shrink-0"
                  style={{ backgroundColor: currentStatusColor }}
                />
                <span className="text-foreground font-medium flex-1 text-left">
                  {currentStatusLabel}
                </span>
                <svg
                  className="w-4 h-4 text-muted-foreground"
                  fill="none"
                  stroke="currentColor"
                  viewBox="0 0 24 24"
                >
                  <path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    strokeWidth={2}
                    d="M19 9l-7 7-7-7"
                  />
                </svg>
              </button>

              {statusSelectOpen && (
                <div className="absolute top-full left-0 right-0 mt-1 z-10 bg-popover border border-border rounded-lg shadow-xl overflow-hidden">
                  {ALL_STATUSES.map((status) => {
                    const color = STATUS_COLORS[status];
                    const label = STATUS_LABELS[status];
                    const isCurrent = status === ticket.status;
                    return (
                      <button
                        key={status}
                        onClick={() => handleStatusSelect(status)}
                        disabled={isCurrent}
                        className={cn(
                          "w-full flex items-center gap-3 px-4 py-2.5 text-sm text-left transition-all duration-150",
                          isCurrent
                            ? "bg-accent text-muted-foreground cursor-default"
                            : "text-foreground hover:bg-accent"
                        )}
                      >
                        <span
                          className="w-3 h-3 rounded-full flex-shrink-0"
                          style={{ backgroundColor: color }}
                        />
                        {label}
                        {isCurrent && (
                          <span className="text-xs text-muted-foreground ml-auto">
                            current
                          </span>
                        )}
                      </button>
                    );
                  })}
                </div>
              )}
            </div>
          </div>

          {/* Status change preview */}
          {preview && (
            <div className="p-3 rounded-lg bg-background border border-border">
              <p className="text-xs text-muted-foreground mb-2">
                Preview: changing to{" "}
                <span className="text-foreground font-medium">
                  {STATUS_LABELS[pendingStatus || ""]}
                </span>
              </p>
              {preview.prepared_scrips.length > 0 ? (
                <div className="space-y-1 mb-3">
                  {preview.prepared_scrips.map((scrip) => (
                    <div
                      key={scrip.scripId}
                      className="text-xs text-foreground flex items-center gap-1.5"
                    >
                      <span className="w-2 h-2 rounded-full bg-chart-3 flex-shrink-0" />
                      {scrip.scripName}
                    </div>
                  ))}
                </div>
              ) : (
                <p className="text-xs text-muted-foreground mb-3">
                  No scrips will fire
                </p>
              )}
              <div className="flex items-center gap-2">
                <button
                  onClick={handleApplyStatus}
                  disabled={applyLoading}
                  className="px-2.5 py-1 rounded-md text-xs font-medium bg-primary hover:bg-primary/80 text-primary-foreground disabled:opacity-50 transition-all duration-150"
                >
                  {applyLoading
                    ? "Applying..."
                    : `Apply — ${preview.prepared_scrips.length} scrip${preview.prepared_scrips.length !== 1 ? "s" : ""} will fire`}
                </button>
                <button
                  onClick={handleCancelStatus}
                  disabled={applyLoading}
                  className="px-2.5 py-1 rounded-md text-xs font-medium text-muted-foreground hover:text-foreground transition-all duration-150"
                >
                  Cancel
                </button>
              </div>
            </div>
          )}

          {previewError && (
            <div className="p-2 rounded-lg bg-destructive/5 border border-destructive/10">
              <p className="text-xs text-destructive">{previewError}</p>
            </div>
          )}

          {scripResults && (
            <div className="p-3 rounded-lg bg-background border border-border">
              <p className="text-xs text-muted-foreground mb-2">Scrip results:</p>
              <div className="space-y-1">
                {scripResults.map((result) => (
                  <div
                    key={result.scripId}
                    className={cn(
                      "text-xs flex items-center gap-1.5",
                      result.success ? "text-[#22c55e]" : "text-destructive"
                    )}
                  >
                    <span
                      className={cn(
                        "w-2 h-2 rounded-full flex-shrink-0",
                        result.success ? "bg-[#22c55e]" : "bg-destructive"
                      )}
                    />
                    {result.message}
                  </div>
                ))}
              </div>
              <button
                onClick={() => setScripResults(null)}
                className="mt-2 text-xs text-muted-foreground hover:text-foreground transition-all duration-150"
              >
                Dismiss
              </button>
            </div>
          )}

          <Separator />

          {/* Section: Assignment */}
          <div>
            <h3 className="text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-2">
              Assignment
            </h3>

            {/* Assignee */}
            <div className="mb-3">
              <label className="block text-[11px] font-medium text-muted-foreground mb-1">
                Assignee
              </label>
              {ticket.owner_id ? (
                <div className="flex items-center gap-2 px-3 py-2 rounded-lg border border-border bg-background transition-all duration-150 hover:border-foreground/20">
                  <div
                    className="w-5 h-5 rounded-full flex items-center justify-center flex-shrink-0"
                    style={{
                      backgroundColor: getInitialColor(ticket.owner_id),
                    }}
                  >
                    <span className="text-[10px] font-semibold text-primary-foreground">
                      {getInitial(ticket.owner_id)}
                    </span>
                  </div>
                  <span className="text-sm text-foreground">
                    {ticket.owner_id}
                  </span>
                </div>
              ) : (
                <div className="px-3 py-2 rounded-lg border border-border bg-background text-sm text-muted-foreground">
                  Unassigned
                </div>
              )}
            </div>

            {/* Priority (placeholder) */}
            <div>
              <label className="block text-[11px] font-medium text-muted-foreground mb-1">
                Priority
              </label>
              <div className="px-3 py-2 rounded-lg border border-border bg-background text-sm text-muted-foreground">
                Not set
              </div>
            </div>
          </div>

          <Separator />

          {/* Section: Details */}
          <div>
            <h3 className="text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-2">
              Details
            </h3>

            {/* Queue */}
            <div className="mb-3">
              <label className="block text-[11px] font-medium text-muted-foreground mb-1">
                Queue
              </label>
              <div className="px-3 py-2 rounded-lg border border-border bg-background">
                <span className="text-sm text-foreground">
                  {queue?.name || ticket.queue_id}
                </span>
              </div>
            </div>

            {/* Custom fields */}
            {ticket.custom_fields && ticket.custom_fields.length > 0 && (
              <div className="mb-3">
                <label className="block text-[11px] font-medium text-muted-foreground mb-1">
                  Custom fields
                </label>
                <div className="space-y-1.5">
                  {ticket.custom_fields.map((cf) => (
                    <div
                      key={cf.id}
                      className="flex justify-between items-center px-3 py-1.5 rounded-lg border border-border bg-background"
                    >
                      <span className="text-xs text-muted-foreground">
                        {cf.custom_field?.name || cf.custom_field_id}
                      </span>
                      <span className="text-xs text-foreground font-medium">
                        {cf.value}
                      </span>
                    </div>
                  ))}
                </div>
              </div>
            )}

            {/* Dates */}
            <div>
              <div className="space-y-1.5 text-xs">
                <div className="flex justify-between">
                  <span className="text-muted-foreground">Created</span>
                  <span className="text-foreground tabular-nums">
                    {formatDistanceToNow(new Date(ticket.created_at), {
                      addSuffix: true,
                    })}
                  </span>
                </div>
                <div className="flex justify-between">
                  <span className="text-muted-foreground">Updated</span>
                  <span className="text-foreground tabular-nums">
                    {formatDistanceToNow(new Date(ticket.updated_at), {
                      addSuffix: true,
                    })}
                  </span>
                </div>
                {ticket.resolved_at && (
                  <div className="flex justify-between">
                    <span className="text-muted-foreground">Resolved</span>
                    <span className="text-foreground tabular-nums">
                      {formatDistanceToNow(new Date(ticket.resolved_at), {
                        addSuffix: true,
                      })}
                    </span>
                  </div>
                )}
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}
