"use client";

import { ChangeEvent, useCallback, useEffect, useMemo, useRef, useState } from "react";
import Image from "next/image";
import { ImageIcon, RefreshCcw, Send, UserRoundCheck } from "lucide-react";

import { NoPermissionState } from "@/components/auth/no-permission-state";
import { useSuperAdminSession } from "@/components/auth/session-context";
import { PageHeader } from "@/components/dashboard/page-header";
import { PaginationControls } from "@/components/dashboard/pagination-controls";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { EmptyState } from "@/components/ui/empty-state";
import { Input } from "@/components/ui/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Textarea } from "@/components/ui/textarea";
import { useToast } from "@/components/ui/toast";
import { getItems, getPagination } from "@/lib/api/core";
import {
  assignSupportTicket,
  getSupportTicket,
  listSupportTickets,
  replyToSupportTicket,
  updateSupportTicketStatus,
} from "@/lib/api/support";
import { formatDateTime } from "@/lib/format";
import { SUPERADMIN_PERMISSIONS, hasPermission } from "@/lib/permissions";
import type {
  ApiUser,
  SupportTicket,
  SupportTicketDetailResponse,
  SupportTicketStatus,
  SupportTicketsResponse,
} from "@/types/api";

const statuses: SupportTicketStatus[] = ["open", "pending", "in_progress", "resolved", "closed"];
const categories = ["account", "technical", "media", "payment", "collaboration", "other"];
const priorities = ["low", "normal", "high", "urgent"];

function userLabel(user?: ApiUser | null) {
  if (!user) return "-";
  return user.stageName || user.name || user.username || user.email || user._id;
}

function statusVariant(status: SupportTicketStatus): "success" | "muted" | "warning" | "danger" {
  if (status === "resolved" || status === "closed") return "success";
  if (status === "in_progress") return "warning";
  if (status === "pending") return "muted";
  return "danger";
}

export default function SupportPage() {
  const { permissions } = useSuperAdminSession();
  const canManageSupport = hasPermission(permissions, SUPERADMIN_PERMISSIONS.CASES_MANAGE);
  const { toast } = useToast();

  const [statusFilter, setStatusFilter] = useState("open");
  const [categoryFilter, setCategoryFilter] = useState("all");
  const [priorityFilter, setPriorityFilter] = useState("all");
  const [page, setPage] = useState(1);
  const [response, setResponse] = useState<SupportTicketsResponse | null>(null);
  const [selected, setSelected] = useState<SupportTicketDetailResponse | null>(null);
  const [reply, setReply] = useState("");
  const [replyImage, setReplyImage] = useState<File | null>(null);
  const [assignAdminId, setAssignAdminId] = useState("");
  const [loading, setLoading] = useState(true);
  const [updating, setUpdating] = useState(false);
  const filtersRef = useRef({ statusFilter, categoryFilter, priorityFilter });

  filtersRef.current = { statusFilter, categoryFilter, priorityFilter };

  const loadTickets = useCallback(async () => {
    if (!canManageSupport) {
      setLoading(false);
      return;
    }

    setLoading(true);
    try {
      const current = filtersRef.current;
      const tickets = await listSupportTickets({
        page,
        limit: 15,
        status: current.statusFilter === "all" ? undefined : current.statusFilter,
        category: current.categoryFilter === "all" ? undefined : current.categoryFilter,
        priority: current.priorityFilter === "all" ? undefined : current.priorityFilter,
        sortOrder: "desc",
      });
      setResponse(tickets);
      const items = getItems(tickets) as SupportTicket[];
      const currentSelectedId = selected?.ticket._id;
      const nextTicket = currentSelectedId
        ? items.find((item) => item._id === currentSelectedId) ?? items[0]
        : items[0];
      if (nextTicket) {
        const detail = await getSupportTicket(nextTicket._id);
        setSelected(detail);
        setAssignAdminId(detail.ticket.assignedAdminId ?? "");
      } else {
        setSelected(null);
        setAssignAdminId("");
      }
    } catch (error) {
      toast({ title: "Failed to load support tickets", description: String(error), variant: "danger" });
    } finally {
      setLoading(false);
    }
  }, [canManageSupport, page, selected?.ticket._id, toast]);

  useEffect(() => {
    void loadTickets();
  }, [loadTickets]);

  const tickets = getItems(response) as SupportTicket[];
  const summary = useMemo(
    () => ({
      open: tickets.filter((ticket) => ticket.status === "open").length,
      inProgress: tickets.filter((ticket) => ticket.status === "in_progress").length,
      resolved: tickets.filter((ticket) => ticket.status === "resolved").length,
      closed: tickets.filter((ticket) => ticket.status === "closed").length,
    }),
    [tickets],
  );

  const selectTicket = async (ticketId: string) => {
    setUpdating(true);
    try {
      const detail = await getSupportTicket(ticketId);
      setSelected(detail);
      setAssignAdminId(detail.ticket.assignedAdminId ?? "");
    } catch (error) {
      toast({ title: "Failed to load ticket", description: String(error), variant: "danger" });
    } finally {
      setUpdating(false);
    }
  };

  const applyFilters = () => {
    if (page === 1) {
      void loadTickets();
      return;
    }
    setPage(1);
  };

  const changeStatus = async (status: SupportTicketStatus) => {
    if (!selected) return;
    setUpdating(true);
    try {
      await updateSupportTicketStatus(selected.ticket._id, status);
      await selectTicket(selected.ticket._id);
      await loadTickets();
      toast({ title: "Ticket status updated", description: status, variant: "success" });
    } catch (error) {
      toast({ title: "Status update failed", description: String(error), variant: "danger" });
    } finally {
      setUpdating(false);
    }
  };

  const assignTicket = async () => {
    if (!selected) return;
    setUpdating(true);
    try {
      await assignSupportTicket(selected.ticket._id, assignAdminId.trim());
      await selectTicket(selected.ticket._id);
      toast({ title: "Assignment updated", variant: "success" });
    } catch (error) {
      toast({ title: "Assignment failed", description: String(error), variant: "danger" });
    } finally {
      setUpdating(false);
    }
  };

  const sendReply = async () => {
    if (!selected || (!reply.trim() && !replyImage)) return;
    setUpdating(true);
    try {
      await replyToSupportTicket(selected.ticket._id, reply.trim(), replyImage);
      setReply("");
      setReplyImage(null);
      await selectTicket(selected.ticket._id);
      await loadTickets();
      toast({ title: "Reply sent", variant: "success" });
    } catch (error) {
      toast({ title: "Reply failed", description: String(error), variant: "danger" });
    } finally {
      setUpdating(false);
    }
  };

  const onImageChange = (event: ChangeEvent<HTMLInputElement>) => {
    setReplyImage(event.target.files?.[0] ?? null);
  };

  if (!canManageSupport) {
    return (
      <div className="space-y-5 pb-8">
        <PageHeader title="Support" subtitle="Review user support tickets and reply from the dashboard." />
        <NoPermissionState description="This page needs the cases.manage permission." />
      </div>
    );
  }

  return (
    <div className="space-y-5 pb-8">
      <PageHeader
        title="Support tickets"
        subtitle="Handle user support requests separately from reports and moderation cases."
        actions={
          <Button variant="outline" onClick={() => void loadTickets()} disabled={loading}>
            <RefreshCcw className="h-4 w-4" />
            Refresh
          </Button>
        }
      />

      <section className="grid gap-4 md:grid-cols-4">
        <Card>
          <CardHeader>
            <CardTitle>Open</CardTitle>
          </CardHeader>
          <CardContent className="text-3xl font-bold text-foreground">{summary.open}</CardContent>
        </Card>
        <Card>
          <CardHeader>
            <CardTitle>In progress</CardTitle>
          </CardHeader>
          <CardContent className="text-3xl font-bold text-foreground">{summary.inProgress}</CardContent>
        </Card>
        <Card>
          <CardHeader>
            <CardTitle>Resolved</CardTitle>
          </CardHeader>
          <CardContent className="text-3xl font-bold text-foreground">{summary.resolved}</CardContent>
        </Card>
        <Card>
          <CardHeader>
            <CardTitle>Closed</CardTitle>
          </CardHeader>
          <CardContent className="text-3xl font-bold text-foreground">{summary.closed}</CardContent>
        </Card>
      </section>

      <Card>
        <CardHeader>
          <CardTitle>Filters</CardTitle>
        </CardHeader>
        <CardContent className="grid gap-3 md:grid-cols-4">
          <Select value={statusFilter} onValueChange={setStatusFilter}>
            <SelectTrigger>
              <SelectValue placeholder="Status" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">All statuses</SelectItem>
              {statuses.map((status) => (
                <SelectItem key={status} value={status}>
                  {status}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <Select value={categoryFilter} onValueChange={setCategoryFilter}>
            <SelectTrigger>
              <SelectValue placeholder="Category" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">All categories</SelectItem>
              {categories.map((category) => (
                <SelectItem key={category} value={category}>
                  {category}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <Select value={priorityFilter} onValueChange={setPriorityFilter}>
            <SelectTrigger>
              <SelectValue placeholder="Priority" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">All priorities</SelectItem>
              {priorities.map((priority) => (
                <SelectItem key={priority} value={priority}>
                  {priority}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <Button variant="outline" onClick={applyFilters} disabled={loading}>
            Apply
          </Button>
        </CardContent>
      </Card>

      <section className="grid gap-4 xl:grid-cols-12">
        <Card className="xl:col-span-7">
          <CardHeader>
            <CardTitle>Ticket queue</CardTitle>
          </CardHeader>
          <CardContent className="space-y-4">
            {!tickets.length && !loading ? (
              <EmptyState title="No support tickets" description="No tickets match the selected filters." />
            ) : (
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>User</TableHead>
                    <TableHead>Subject</TableHead>
                    <TableHead>Priority</TableHead>
                    <TableHead>Status</TableHead>
                    <TableHead>Last message</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {tickets.map((ticket) => (
                    <TableRow
                      key={ticket._id}
                      className={selected?.ticket._id === ticket._id ? "bg-primary/10" : undefined}
                      onClick={() => void selectTicket(ticket._id)}
                    >
                      <TableCell>
                        <div className="font-medium text-foreground">{userLabel(ticket.user)}</div>
                        <div className="text-xs text-muted-foreground">{ticket.user?.email ?? ticket.userId}</div>
                      </TableCell>
                      <TableCell>
                        <div className="max-w-[280px] truncate font-medium">{ticket.subject}</div>
                        <div className="text-xs text-muted-foreground">{ticket.category}</div>
                      </TableCell>
                      <TableCell>
                        <Badge variant={ticket.priority === "urgent" || ticket.priority === "high" ? "danger" : "muted"}>
                          {ticket.priority}
                        </Badge>
                      </TableCell>
                      <TableCell>
                        <Badge variant={statusVariant(ticket.status)}>{ticket.status}</Badge>
                      </TableCell>
                      <TableCell>{formatDateTime(ticket.lastMessageAt)}</TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            )}
            <PaginationControls pagination={getPagination(response)} loading={loading} onPageChange={setPage} />
          </CardContent>
        </Card>

        <Card className="xl:col-span-5">
          <CardHeader>
            <CardTitle>Ticket details</CardTitle>
          </CardHeader>
          <CardContent className="space-y-4">
            {!selected ? (
              <EmptyState title="Select a ticket" description="Choose a ticket to review user details and messages." />
            ) : (
              <>
                <div className="rounded-xl border border-border/70 bg-secondary/20 p-4">
                  <div className="flex items-start gap-3">
                    {selected.ticket.user?.avatar ? (
                      <Image
                        src={selected.ticket.user.avatar}
                        alt={userLabel(selected.ticket.user)}
                        width={48}
                        height={48}
                        unoptimized
                        className="h-12 w-12 rounded-full object-cover"
                      />
                    ) : (
                      <div className="flex h-12 w-12 items-center justify-center rounded-full bg-primary/10">
                        <UserRoundCheck className="h-5 w-5" />
                      </div>
                    )}
                    <div className="min-w-0 flex-1">
                      <div className="font-semibold text-foreground">{userLabel(selected.ticket.user)}</div>
                      <div className="text-sm text-muted-foreground">{selected.ticket.user?.username ?? "-"}</div>
                      <div className="break-all text-xs text-muted-foreground">{selected.ticket.user?.email ?? "-"}</div>
                    </div>
                    <Badge variant={selected.ticket.user?.isDisabled ? "danger" : "success"}>
                      {selected.ticket.user?.isDisabled ? "disabled" : "active"}
                    </Badge>
                  </div>
                  <div className="mt-4 space-y-1 text-sm">
                    <div className="font-semibold text-foreground">{selected.ticket.subject}</div>
                    <div className="text-muted-foreground">
                      {selected.ticket.category} / {selected.ticket.priority} / {formatDateTime(selected.ticket.createdAt)}
                    </div>
                  </div>
                </div>

                <div className="grid gap-2 md:grid-cols-2">
                  <Select value={selected.ticket.status} onValueChange={(value) => void changeStatus(value as SupportTicketStatus)}>
                    <SelectTrigger>
                      <SelectValue placeholder="Status" />
                    </SelectTrigger>
                    <SelectContent>
                      {statuses.map((status) => (
                        <SelectItem key={status} value={status}>
                          {status}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                  <div className="flex gap-2">
                    <Input
                      placeholder="Admin id"
                      value={assignAdminId}
                      onChange={(event) => setAssignAdminId(event.target.value)}
                    />
                    <Button variant="outline" onClick={() => void assignTicket()} disabled={updating}>
                      Assign
                    </Button>
                  </div>
                </div>

                <div className="max-h-[420px] space-y-3 overflow-y-auto rounded-xl border border-border/70 p-3">
                  {selected.messages.map((message) => (
                    <div
                      key={message._id}
                      className={`rounded-xl border border-border/70 p-3 ${
                        message.senderRole === "user" ? "bg-secondary/20" : "bg-primary/10"
                      }`}
                    >
                      <div className="flex items-center justify-between gap-3">
                        <Badge variant={message.senderRole === "user" ? "muted" : "warning"}>{message.senderRole}</Badge>
                        <span className="text-xs text-muted-foreground">{formatDateTime(message.createdAt)}</span>
                      </div>
                      {message.message ? <p className="mt-2 whitespace-pre-wrap text-sm">{message.message}</p> : null}
                      {message.attachmentUrl ? (
                        <a href={message.attachmentUrl} target="_blank" rel="noreferrer" className="mt-3 block">
                          <Image
                            src={message.attachmentUrl}
                            alt="Support attachment"
                            width={640}
                            height={260}
                            unoptimized
                            className="max-h-52 w-full rounded-lg object-cover"
                          />
                        </a>
                      ) : null}
                    </div>
                  ))}
                </div>

                <div className="space-y-3 rounded-xl border border-border/70 p-3">
                  <Textarea
                    placeholder="Write a reply"
                    value={reply}
                    onChange={(event) => setReply(event.target.value)}
                  />
                  <div className="flex flex-wrap items-center justify-between gap-2">
                    <label className="inline-flex cursor-pointer items-center gap-2 rounded-lg border border-border/70 px-3 py-2 text-sm">
                      <ImageIcon className="h-4 w-4" />
                      {replyImage ? replyImage.name : "Attach image"}
                      <input className="hidden" type="file" accept="image/*" onChange={onImageChange} />
                    </label>
                    <Button onClick={() => void sendReply()} disabled={updating || (!reply.trim() && !replyImage)}>
                      <Send className="h-4 w-4" />
                      Send reply
                    </Button>
                  </div>
                </div>
              </>
            )}
          </CardContent>
        </Card>
      </section>
    </div>
  );
}
