"use client";

import React, { useMemo, useState } from "react";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import {
  Dialog,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Textarea } from "@/components/ui/textarea";
import type { ComplaintStatus, WorkspaceComplaint } from "@/lib/complaints-storage";
import {
  createWorkspaceComplaint,
  deleteWorkspaceComplaint,
  patchWorkspaceComplaint,
  postComplaintReply,
} from "@/lib/complaints-api";
import { useComplaintsNotify } from "@/context/complaints-notify-context";
import { workspacePersonaFromMe } from "@/lib/workspace-persona";
import { toast } from "sonner";
import { Pencil, Plus, Trash2 } from "lucide-react";
import ClientWorkspaceLayout, { type ClientWorkspaceChildCtx } from "./client-workspace-layout";
import { getApiErrorMessage } from "@/lib/api-error";

function displayName(ctx: ClientWorkspaceChildCtx): string {
  const u = ctx.me as {
    firstName?: string;
    lastName?: string;
    email?: string;
    username?: string;
  };
  const n = [u.firstName, u.lastName].filter(Boolean).join(" ").trim();
  return n || u.email || u.username || "User";
}

export default function ClientComplaintsFeature() {
  return (
    <ClientWorkspaceLayout
      title="Complaints"
      barDescription="Raise issues for your unit or property. Updates sync in real time for your organization."
    >
      {(ctx) => <ClientComplaintsBody ctx={ctx} />}
    </ClientWorkspaceLayout>
  );
}

function ClientComplaintsBody({ ctx }: { ctx: ClientWorkspaceChildCtx }) {
  const { complaints: rows, complaintsReady, markComplaintSeen, refreshComplaints } = useComplaintsNotify();
  const scope = ctx.effectiveClientKey;
  const tenantApiKey = ctx.tenantApiKey;
  const persona = workspacePersonaFromMe(ctx.me);
  const uid = ctx.me._id ? String(ctx.me._id) : "";
  const canModerate = persona === "super_admin" || persona === "client_owner" || persona === "management_staff";
  const isOccupant = persona === "occupant_tenant";
  const canCreateComplaint =
    persona === "occupant_tenant" || persona === "client_owner" || persona === "super_admin";

  const [createOpen, setCreateOpen] = useState(false);
  const [editOpen, setEditOpen] = useState(false);
  const [editId, setEditId] = useState<string | null>(null);
  const [title, setTitle] = useState("");
  const [description, setDescription] = useState("");
  const [replyText, setReplyText] = useState("");
  const [replyForId, setReplyForId] = useState<string | null>(null);

  const visibleRows = useMemo(() => {
    if (!isOccupant) return rows;
    return rows.filter((r) => r.createdBy === uid);
  }, [rows, isOccupant, uid]);

  const resetForm = () => {
    setTitle("");
    setDescription("");
    setEditId(null);
  };

  const openCreate = () => {
    resetForm();
    setCreateOpen(true);
  };

  const openEdit = (c: WorkspaceComplaint) => {
    if (c.createdBy !== uid) return;
    setEditId(c.id);
    setTitle(c.title);
    setDescription(c.description);
    setEditOpen(true);
  };

  const submitCreate = async () => {
    if (!tenantApiKey) {
      toast.error("Workspace not ready.");
      return;
    }
    if (!title.trim() || !description.trim()) {
      toast.error("Title and description are required.");
      return;
    }
    try {
      const created = await createWorkspaceComplaint(tenantApiKey, {
        title: title.trim(),
        description: description.trim(),
      });
      markComplaintSeen(created.id, created.updatedAt);
      await refreshComplaints();
      toast.success("Complaint submitted");
      resetForm();
      setCreateOpen(false);
    } catch (e: unknown) {
      toast.error(getApiErrorMessage(e, "Could not create complaint"));
    }
  };

  const submitEdit = async () => {
    if (!tenantApiKey || !editId) return;
    if (!title.trim() || !description.trim()) {
      toast.error("Title and description are required.");
      return;
    }
    try {
      const updated = await patchWorkspaceComplaint(tenantApiKey, editId, {
        title: title.trim(),
        description: description.trim(),
      });
      markComplaintSeen(updated.id, updated.updatedAt);
      await refreshComplaints();
      toast.success("Complaint updated");
      resetForm();
      setEditOpen(false);
    } catch (e: unknown) {
      toast.error(getApiErrorMessage(e, "Could not update complaint"));
    }
  };

  const removeOwn = async (c: WorkspaceComplaint) => {
    if (!tenantApiKey || c.createdBy !== uid) return;
    try {
      await deleteWorkspaceComplaint(tenantApiKey, c.id);
      await refreshComplaints();
      toast.success("Complaint deleted");
    } catch (e: unknown) {
      toast.error(getApiErrorMessage(e, "Could not delete complaint"));
    }
  };

  const setStatus = async (id: string, status: ComplaintStatus) => {
    if (!tenantApiKey || !canModerate) return;
    try {
      const updated = await patchWorkspaceComplaint(tenantApiKey, id, { status });
      markComplaintSeen(updated.id, updated.updatedAt);
      await refreshComplaints();
    } catch (e: unknown) {
      toast.error(getApiErrorMessage(e, "Could not update status"));
    }
  };

  const submitReply = async (complaintId: string) => {
    if (!tenantApiKey || !canModerate) return;
    const text = replyText.trim();
    if (!text) {
      toast.error("Write a message first.");
      return;
    }
    try {
      const updated = await postComplaintReply(tenantApiKey, complaintId, text);
      markComplaintSeen(updated.id, updated.updatedAt);
      await refreshComplaints();
      await reload();
      setReplyText("");
      setReplyForId(null);
      toast.success("Reply added");
    } catch (e: unknown) {
      toast.error(getApiErrorMessage(e, "Could not add reply"));
    }
  };

  if (!ctx.tenantReady || !scope) {
    return <p className="text-sm text-muted-foreground">Select a client workspace to manage complaints.</p>;
  }

  if (!complaintsReady) {
    return (
      <div className="rounded-md border bg-white p-8 text-center text-sm text-muted-foreground">Loading complaints…</div>
    );
  }

  return (
    <div className="space-y-4">
      <div className="flex flex-wrap items-center justify-between gap-2">
        <p className="text-sm text-muted-foreground max-w-xl">
          {persona === "management_staff"
            ? "Review and reply to complaints. Tenants see only their own tickets."
            : isOccupant
              ? "Add and track your complaints. Management and the property owner can see them and reply here."
              : "All complaints for this client. Tenants see only their own entries."}
        </p>
        {canCreateComplaint ? (
          <Button type="button" size="sm" onClick={openCreate}>
            <Plus className="size-4" />
            New complaint
          </Button>
        ) : null}
      </div>

      <div className="grid gap-4 md:grid-cols-2">
        {visibleRows.length === 0 ? (
          <Card className="md:col-span-2 border-dashed">
            <CardHeader>
              <CardTitle className="text-base">No complaints yet</CardTitle>
              <CardDescription>
                {isOccupant ? "Tap “New complaint” to add one." : "Nothing submitted for this workspace."}
              </CardDescription>
            </CardHeader>
          </Card>
        ) : (
          visibleRows.map((c) => (
            <Card key={c.id} className="min-w-0">
              <CardHeader className="space-y-1 pb-2">
                <div className="flex flex-wrap items-start justify-between gap-2">
                  <CardTitle className="text-base leading-snug">{c.title}</CardTitle>
                  <div className="flex items-center gap-1">
                    {c.createdBy === uid ? (
                      <>
                        <Button type="button" variant="ghost" size="icon" aria-label="Edit" onClick={() => openEdit(c)}>
                          <Pencil className="size-4" />
                        </Button>
                        <Button
                          type="button"
                          variant="ghost"
                          size="icon"
                          className="text-destructive"
                          aria-label="Delete"
                          onClick={() => void removeOwn(c)}
                        >
                          <Trash2 className="size-4" />
                        </Button>
                      </>
                    ) : null}
                  </div>
                </div>
                <CardDescription className="text-xs">
                  From {c.createdByName} · {new Date(c.createdAt).toLocaleString()}
                  {!isOccupant && c.createdBy !== uid ? ` · author …${c.createdBy.slice(-6)}` : null}
                </CardDescription>
              </CardHeader>
              <CardContent className="space-y-3 text-sm">
                <p className="whitespace-pre-wrap text-gray-800">{c.description}</p>
                {canModerate ? (
                  <div className="flex flex-wrap items-center gap-2">
                    <span className="text-xs text-muted-foreground">Status</span>
                    <Select value={c.status} onValueChange={(v) => void setStatus(c.id, v as ComplaintStatus)}>
                      <SelectTrigger className="h-8 w-[160px] text-xs">
                        <SelectValue />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectItem value="open">Open</SelectItem>
                        <SelectItem value="in_progress">In progress</SelectItem>
                        <SelectItem value="resolved">Resolved</SelectItem>
                      </SelectContent>
                    </Select>
                  </div>
                ) : (
                  <p className="text-xs capitalize text-muted-foreground">Status: {c.status.replace("_", " ")}</p>
                )}

                {c.replies.length > 0 ? (
                  <div className="rounded-md border bg-muted/40 p-3 space-y-2">
                    <p className="text-xs font-medium text-muted-foreground">Discussion</p>
                    <ul className="space-y-2">
                      {c.replies.map((r) => (
                        <li key={r.id} className="text-xs">
                          <span className="font-medium text-gray-900">{r.userName}</span>
                          <span className="text-muted-foreground">
                            {" "}
                            · {new Date(r.at).toLocaleString()}
                          </span>
                          <p className="mt-0.5 whitespace-pre-wrap text-gray-800">{r.text}</p>
                        </li>
                      ))}
                    </ul>
                  </div>
                ) : null}

                {canModerate ? (
                  <div className="space-y-2 border-t pt-3">
                    {replyForId === c.id ? (
                      <>
                        <Label className="text-xs">Reply as {displayName(ctx)}</Label>
                        <Textarea
                          rows={3}
                          value={replyText}
                          onChange={(e) => setReplyText(e.target.value)}
                          placeholder="Message to the tenant…"
                        />
                        <div className="flex gap-2">
                          <Button type="button" size="sm" onClick={() => void submitReply(c.id)}>
                            Send reply
                          </Button>
                          <Button type="button" size="sm" variant="outline" onClick={() => setReplyForId(null)}>
                            Cancel
                          </Button>
                        </div>
                      </>
                    ) : (
                      <Button type="button" size="sm" variant="secondary" onClick={() => setReplyForId(c.id)}>
                        Reply
                      </Button>
                    )}
                  </div>
                ) : null}
              </CardContent>
            </Card>
          ))
        )}
      </div>

      <Dialog open={createOpen} onOpenChange={setCreateOpen}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>New complaint</DialogTitle>
          </DialogHeader>
          <div className="space-y-3">
            <div className="space-y-1">
              <Label>Title</Label>
              <Input value={title} onChange={(e) => setTitle(e.target.value)} placeholder="Short summary" />
            </div>
            <div className="space-y-1">
              <Label>Details</Label>
              <Textarea rows={5} value={description} onChange={(e) => setDescription(e.target.value)} />
            </div>
          </div>
          <DialogFooter>
            <Button type="button" variant="outline" onClick={() => setCreateOpen(false)}>
              Cancel
            </Button>
            <Button type="button" onClick={() => void submitCreate()}>
              Submit
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <Dialog open={editOpen} onOpenChange={setEditOpen}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>Edit complaint</DialogTitle>
          </DialogHeader>
          <div className="space-y-3">
            <div className="space-y-1">
              <Label>Title</Label>
              <Input value={title} onChange={(e) => setTitle(e.target.value)} />
            </div>
            <div className="space-y-1">
              <Label>Details</Label>
              <Textarea rows={5} value={description} onChange={(e) => setDescription(e.target.value)} />
            </div>
          </div>
          <DialogFooter>
            <Button type="button" variant="outline" onClick={() => setEditOpen(false)}>
              Cancel
            </Button>
            <Button type="button" onClick={() => void submitEdit()}>
              Save
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
