import { useEffect, useMemo, useState } from "react";
import { formatDistanceToNow } from "date-fns";
import { AlertCircle, Loader2, MessageSquare, Plus, Send, Ticket } from "lucide-react";
import { supabase } from "@/integrations/supabase/client";
import { useAuth } from "@/contexts/AuthContext";
import { useHomeowner } from "@/contexts/HomeownerContext";
import { useToast } from "@/hooks/use-toast";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, 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";

type TicketRow = {
  id: string;
  title: string;
  description: string | null;
  category: string | null;
  priority: string | null;
  status: string;
  created_at: string;
};

type CommentRow = {
  id: string;
  comment: string;
  created_at: string;
  user_id: string;
  profile?: { full_name: string | null; email: string | null } | null;
};

const emptyForm = {
  title: "",
  category: "general",
  priority: "medium",
  location: "",
  best_contact: "email",
  phone: "",
  availability: "",
  permission_to_enter: "no",
  impact: "",
  steps_taken: "",
  description: "",
};

const statusStyles: Record<string, string> = {
  open: "bg-primary/10 text-primary border-primary/20",
  "in-progress": "bg-warning/10 text-warning border-warning/20",
  resolved: "bg-success/10 text-success border-success/20",
  closed: "bg-muted text-muted-foreground border-border",
};

const detailFieldLabels = new Set([
  "Property",
  "Category",
  "Priority",
  "Best Contact Method",
  "Phone",
  "Specific Location",
  "Availability",
  "Permission to Enter",
  "Impact/Urgency",
  "Steps Already Taken",
]);

function parseTicketDescription(description: string | null) {
  const lines = (description || "").split("\n").map((line) => line.trim()).filter(Boolean);
  const issueLines: string[] = [];
  const fields: Array<{ label: string; value: string }> = [];
  let readingIssue = false;

  lines.forEach((line) => {
    if (line === "Issue Description:") {
      readingIssue = true;
      return;
    }

    const match = line.match(/^([^:]+):\s*(.*)$/);
    if (match && detailFieldLabels.has(match[1])) {
      fields.push({ label: match[1], value: match[2] || "Not provided" });
      readingIssue = false;
      return;
    }

    if (readingIssue || !fields.length) issueLines.push(line);
  });

  return { issue: issueLines.join("\n") || "No description provided", fields };
}

function TicketDescriptionView({ description }: { description: string | null }) {
  const { issue, fields } = parseTicketDescription(description);

  if (!fields.length) {
    return <div className="rounded-md border bg-muted/30 p-3 text-sm whitespace-pre-wrap">{issue}</div>;
  }

  return (
    <div className="space-y-3">
      <div className="rounded-md border bg-muted/30 p-4">
        <p className="mb-1 text-xs font-medium uppercase tracking-wide text-muted-foreground">Issue description</p>
        <p className="whitespace-pre-wrap text-sm text-foreground">{issue}</p>
      </div>
      <div className="grid gap-2 sm:grid-cols-2">
        {fields.map((field) => (
          <div key={field.label} className="rounded-md border bg-card p-3">
            <p className="text-xs font-medium text-muted-foreground">{field.label}</p>
            <p className="mt-1 whitespace-pre-wrap text-sm text-foreground">{field.value}</p>
          </div>
        ))}
      </div>
    </div>
  );
}

async function sendTicketEmailToStaff(senderName: string, title: string, message: string) {
  const { data: staff } = await (supabase as any).rpc("get_message_staff_profiles", { _current_user_id: null });
  const recipientIds = [...new Set(((staff || []) as Array<{ user_id: string }>).map((p) => p.user_id).filter(Boolean))];
  if (!recipientIds.length) return;
  await supabase.functions.invoke("send-smtp-email", {
    body: {
      action: "send_direct_message_notification",
      recipient_ids: recipientIds,
      sender_name: senderName,
      message: `${title}\n\n${message}`,
    },
  });
}

export default function HomeownerTicketsPage() {
  const { user } = useAuth();
  const { currentOwner, association, unit, loading: homeownerLoading } = useHomeowner();
  const { toast } = useToast();
  const [tickets, setTickets] = useState<TicketRow[]>([]);
  const [selectedTicket, setSelectedTicket] = useState<TicketRow | null>(null);
  const [comments, setComments] = useState<CommentRow[]>([]);
  const [newComment, setNewComment] = useState("");
  const [dialogOpen, setDialogOpen] = useState(false);
  const [form, setForm] = useState(emptyForm);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);

  const propertyAddress = useMemo(
    () => unit?.address || currentOwner?.property_address || currentOwner?.street_address || "",
    [currentOwner, unit]
  );

  const getTicketSummary = (description: string | null) => parseTicketDescription(description).issue;

  const fetchTickets = async () => {
    if (!currentOwner) return;
    setLoading(true);
    const { data, error } = await supabase
      .from("homeowner_requests")
      .select("id, title, description, category, priority, status, created_at")
      .eq("owner_id", currentOwner.id)
      .order("created_at", { ascending: false });

    if (error) toast({ variant: "destructive", title: "Could not load tickets", description: error.message });
    else setTickets((data || []) as TicketRow[]);
    setLoading(false);
  };

  const fetchComments = async (ticketId: string) => {
    const { data, error } = await supabase
      .from("entity_comments")
      .select("id, comment, created_at, user_id")
      .eq("entity_type", "homeowner_request")
      .eq("entity_id", ticketId)
      .order("created_at", { ascending: true });

    if (error) {
      setComments([]);
      return;
    }

    const userIds = [...new Set((data || []).map((comment) => comment.user_id).filter(Boolean))];
    const { data: profiles } = userIds.length
      ? await supabase.from("profiles").select("user_id, full_name, email").in("user_id", userIds)
      : { data: [] };
    const profileMap = new Map((profiles || []).map((profile) => [profile.user_id, profile]));
    setComments((data || []).map((comment) => ({ ...comment, profile: profileMap.get(comment.user_id) || null })) as CommentRow[]);
  };

  useEffect(() => {
    if (!homeownerLoading) void fetchTickets();
  }, [homeownerLoading, currentOwner?.id]);

  useEffect(() => {
    if (!selectedTicket) return;
    void fetchComments(selectedTicket.id);

    const channel = supabase
      .channel(`homeowner-ticket-${selectedTicket.id}`)
      .on("postgres_changes", { event: "*", schema: "public", table: "entity_comments", filter: `entity_id=eq.${selectedTicket.id}` }, () => {
        void fetchComments(selectedTicket.id);
      })
      .subscribe();

    return () => { void supabase.removeChannel(channel); };
  }, [selectedTicket?.id]);

  const submitTicket = async () => {
    if (!currentOwner || !association) return;
    if (!form.title.trim() || !form.description.trim()) {
      toast({ variant: "destructive", title: "Title and description are required" });
      return;
    }

    const detail = [
      `Issue Description:\n${form.description.trim()}`,
      `\nProperty: ${propertyAddress || "Not provided"}`,
      `Category: ${form.category}`,
      `Priority: ${form.priority}`,
      `Best Contact Method: ${form.best_contact}`,
      form.phone ? `Phone: ${form.phone}` : null,
      form.location ? `Specific Location: ${form.location}` : null,
      form.availability ? `Availability: ${form.availability}` : null,
      `Permission to Enter: ${form.permission_to_enter}`,
      form.impact ? `Impact/Urgency: ${form.impact}` : null,
      form.steps_taken ? `Steps Already Taken: ${form.steps_taken}` : null,
    ].filter(Boolean).join("\n");

    setSaving(true);
    const { data: inserted, error } = await supabase.from("homeowner_requests").insert({
      association_id: association.id,
      owner_id: currentOwner.id,
      title: form.title.trim(),
      category: form.category,
      priority: form.priority,
      status: "open",
      description: detail,
    }).select("id").single();
    setSaving(false);

    if (error) {
      toast({ variant: "destructive", title: "Ticket not submitted", description: error.message });
      return;
    }

    toast({ title: "Ticket submitted", description: "Admin and staff have been notified." });
    void sendTicketEmailToStaff(
      `${currentOwner.first_name || ""} ${currentOwner.last_name || ""}`.trim() || "A homeowner",
      `New homeowner ticket: ${form.title.trim()}`,
      detail
    );
    setForm(emptyForm);
    setDialogOpen(false);
    void fetchTickets();
  };

  const sendComment = async () => {
    if (!user || !selectedTicket || !newComment.trim()) return;
    const { error } = await supabase.from("entity_comments").insert({
      entity_type: "homeowner_request",
      entity_id: selectedTicket.id,
      user_id: user.id,
      comment: newComment.trim(),
    });
    if (error) toast({ variant: "destructive", title: "Reply not sent", description: error.message });
    else {
      void sendTicketEmailToStaff(
        `${currentOwner.first_name || ""} ${currentOwner.last_name || ""}`.trim() || "A homeowner",
        `New reply on ticket: ${selectedTicket.title}`,
        newComment.trim()
      );
      setNewComment("");
    }
  };

  if (homeownerLoading || loading) {
    return <div className="flex justify-center py-16"><Loader2 className="h-6 w-6 animate-spin text-primary" /></div>;
  }

  if (!currentOwner) {
    return <div className="py-16 text-center text-muted-foreground">No linked property found.</div>;
  }

  return (
    <div className="space-y-5">
      <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
        <div>
          <h1 className="flex items-center gap-2 text-xl font-semibold text-foreground"><Ticket className="h-5 w-5 text-primary" /> Submit Ticket</h1>
          <p className="text-sm text-muted-foreground">Create and track detailed requests for {association?.name || "your association"}.</p>
        </div>
        <Button onClick={() => setDialogOpen(true)} className="gap-2"><Plus className="h-4 w-4" /> New Ticket</Button>
      </div>

      {tickets.length === 0 ? (
        <Card><CardContent className="py-12 text-center"><AlertCircle className="mx-auto mb-2 h-7 w-7 text-muted-foreground/40" /><p className="text-sm text-muted-foreground">No tickets submitted yet.</p></CardContent></Card>
      ) : (
        <div className="grid gap-3">
          {tickets.map((ticket) => (
            <Card key={ticket.id} className="cursor-pointer transition-colors hover:bg-muted/40" onClick={() => setSelectedTicket(ticket)}>
              <CardContent className="flex items-start justify-between gap-4 p-4">
                <div className="min-w-0 space-y-1">
                  <p className="font-medium text-foreground">{ticket.title}</p>
                  <p className="line-clamp-2 text-sm text-muted-foreground">{getTicketSummary(ticket.description)}</p>
                  <p className="text-xs text-muted-foreground">Submitted {formatDistanceToNow(new Date(ticket.created_at), { addSuffix: true })}</p>
                </div>
                <div className="flex shrink-0 flex-col items-end gap-2">
                  <Badge variant="outline" className={statusStyles[ticket.status] || statusStyles.open}>{ticket.status}</Badge>
                  <span className="text-xs capitalize text-muted-foreground">{ticket.priority || "medium"}</span>
                </div>
              </CardContent>
            </Card>
          ))}
        </div>
      )}

      <Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
        <DialogContent className="max-h-[90vh] max-w-2xl overflow-y-auto">
          <DialogHeader><DialogTitle>Submit Ticket</DialogTitle></DialogHeader>
          <div className="grid gap-4">
            <div><Label>Subject *</Label><Input value={form.title} onChange={(e) => setForm({ ...form, title: e.target.value })} maxLength={160} placeholder="Briefly summarize the issue" /></div>
            <div className="grid gap-4 sm:grid-cols-2">
              <div><Label>Category</Label><Select value={form.category} onValueChange={(category) => setForm({ ...form, category })}><SelectTrigger><SelectValue /></SelectTrigger><SelectContent><SelectItem value="maintenance">Maintenance</SelectItem><SelectItem value="billing">Billing</SelectItem><SelectItem value="violation">Violation question</SelectItem><SelectItem value="documents">Documents</SelectItem><SelectItem value="amenity">Amenity</SelectItem><SelectItem value="general">General</SelectItem></SelectContent></Select></div>
              <div><Label>Priority</Label><Select value={form.priority} onValueChange={(priority) => setForm({ ...form, priority })}><SelectTrigger><SelectValue /></SelectTrigger><SelectContent><SelectItem value="low">Low</SelectItem><SelectItem value="medium">Medium</SelectItem><SelectItem value="high">High</SelectItem><SelectItem value="urgent">Urgent</SelectItem></SelectContent></Select></div>
            </div>
            <div><Label>Detailed Description *</Label><Textarea value={form.description} onChange={(e) => setForm({ ...form, description: e.target.value })} rows={6} maxLength={3000} placeholder="Describe what happened, when it started, and what outcome you need." /></div>
            <div className="grid gap-4 sm:grid-cols-2">
              <div><Label>Specific Location</Label><Input value={form.location} onChange={(e) => setForm({ ...form, location: e.target.value })} maxLength={180} placeholder={propertyAddress || "Building, unit, room, common area"} /></div>
              <div><Label>Best Contact Method</Label><Select value={form.best_contact} onValueChange={(best_contact) => setForm({ ...form, best_contact })}><SelectTrigger><SelectValue /></SelectTrigger><SelectContent><SelectItem value="email">Email</SelectItem><SelectItem value="phone">Phone</SelectItem><SelectItem value="portal">Portal reply</SelectItem></SelectContent></Select></div>
              <div><Label>Phone</Label><Input value={form.phone} onChange={(e) => setForm({ ...form, phone: e.target.value })} maxLength={40} /></div>
              <div><Label>Availability</Label><Input value={form.availability} onChange={(e) => setForm({ ...form, availability: e.target.value })} maxLength={180} placeholder="Preferred days/times" /></div>
            </div>
            <div><Label>Permission to Enter</Label><Select value={form.permission_to_enter} onValueChange={(permission_to_enter) => setForm({ ...form, permission_to_enter })}><SelectTrigger><SelectValue /></SelectTrigger><SelectContent><SelectItem value="no">No</SelectItem><SelectItem value="yes-with-notice">Yes, with notice</SelectItem><SelectItem value="yes-anytime">Yes, anytime</SelectItem></SelectContent></Select></div>
            <div><Label>Impact / Urgency</Label><Textarea value={form.impact} onChange={(e) => setForm({ ...form, impact: e.target.value })} rows={3} maxLength={1000} placeholder="Explain safety, access, billing, or community impact." /></div>
            <div><Label>Steps Already Taken</Label><Textarea value={form.steps_taken} onChange={(e) => setForm({ ...form, steps_taken: e.target.value })} rows={3} maxLength={1000} placeholder="List troubleshooting, prior calls, photos sent, or related details." /></div>
          </div>
          <DialogFooter><Button variant="outline" onClick={() => setDialogOpen(false)}>Cancel</Button><Button onClick={submitTicket} disabled={saving}>{saving && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}Submit Ticket</Button></DialogFooter>
        </DialogContent>
      </Dialog>

      <Dialog open={!!selectedTicket} onOpenChange={(open) => !open && setSelectedTicket(null)}>
        <DialogContent className="max-h-[90vh] max-w-2xl overflow-y-auto">
          {selectedTicket && <>
            <DialogHeader><DialogTitle className="flex items-center gap-2"><Ticket className="h-5 w-5 text-primary" /> {selectedTicket.title}</DialogTitle></DialogHeader>
            <div className="space-y-4">
              <div className="flex flex-wrap gap-2"><Badge variant="outline" className={statusStyles[selectedTicket.status] || statusStyles.open}>{selectedTicket.status}</Badge><Badge variant="secondary" className="capitalize">{selectedTicket.category || "general"}</Badge></div>
              <TicketDescriptionView description={selectedTicket.description} />
              <div className="border-t pt-4">
                <h3 className="mb-3 flex items-center gap-2 text-sm font-semibold"><MessageSquare className="h-4 w-4" /> Responses</h3>
                <div className="mb-3 max-h-64 space-y-3 overflow-y-auto">
                  {comments.length === 0 && <p className="text-sm text-muted-foreground">No responses yet.</p>}
                  {comments.map((comment) => <div key={comment.id} className="rounded-md border bg-card p-3"><div className="mb-1 flex justify-between gap-3 text-xs text-muted-foreground"><span>{comment.profile?.full_name || comment.profile?.email || "User"}</span><span>{formatDistanceToNow(new Date(comment.created_at), { addSuffix: true })}</span></div><p className="text-sm whitespace-pre-wrap">{comment.comment}</p></div>)}
                </div>
                <div className="flex gap-2"><Textarea value={newComment} onChange={(e) => setNewComment(e.target.value)} placeholder="Reply to staff..." className="min-h-[64px]" maxLength={1500} /><Button onClick={sendComment} disabled={!newComment.trim()} className="self-end"><Send className="h-4 w-4" /></Button></div>
              </div>
            </div>
          </>}
        </DialogContent>
      </Dialog>
    </div>
  );
}