"use client";

import { useEffect, useMemo, useState } from "react";
import { Modal } from "@/components/ui/modal";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Textarea } from "@/components/ui/textarea";
import { SubtaskList } from "./subtask-list";
import {
  AlertTriangle,
  Pencil,
  Trash2,
  Calendar,
  ExternalLink,
  FolderKanban,
  GitBranch,
  Target,
  User2,
  X,
  Repeat,
  CheckCheck,
  GitPullRequestArrow,
} from "lucide-react";
import { cn, formatRelativeDate, isTaskDeadlineOverdue } from "@/lib/utils";
import type { TaskWithRelations } from "@/hooks/use-tasks";
import type { Project } from "@/types";
import { CommentsPanel } from "@/components/comments/comments-panel";
import { useTeamPermissions } from "@/hooks/use-team-permissions";
import { useTeams } from "@/hooks/use-teams";
import { recurrenceLabel } from "@/lib/task-recurrence";
import { AttachmentsPanel } from "@/components/attachments/attachments-panel";
import { RemindMeButton } from "@/components/reminders/remind-me-button";
import { useTaskGitHubLinks } from "@/hooks/use-task-github-links";

const PRIORITY_COLORS: Record<string, string> = {
  urgent: "bg-red-100 text-red-700",
  high: "bg-orange-100 text-orange-700",
  medium: "bg-yellow-100 text-yellow-700",
  low: "bg-blue-100 text-blue-700",
};

const STATUS_LABELS: Record<string, string> = {
  todo: "To do",
  in_progress: "In progress",
  done: "Done",
  cancelled: "Cancelled",
};

const REVIEW_STATUS_META = {
  not_required: {
    label: "No review",
    className: "border-border bg-muted/50 text-muted-foreground",
  },
  pending_review: {
    label: "Needs review",
    className: "border-amber-500/20 bg-amber-500/10 text-amber-700",
  },
  changes_requested: {
    label: "Changes requested",
    className: "border-red-500/20 bg-red-500/10 text-red-700",
  },
  approved: {
    label: "Approved",
    className: "border-emerald-500/20 bg-emerald-500/10 text-emerald-700",
  },
} satisfies Record<
  TaskWithRelations["review_status"],
  { label: string; className: string }
>;

interface TaskDetailProps {
  open: boolean;
  onClose: () => void;
  task: TaskWithRelations;
  project?: Project | null;
  goalTitle?: string | null;
  onEdit: () => void;
  onDelete: () => void;
  onAddSubtask: (title: string) => Promise<void>;
  onToggleSubtask: (id: string, currentStatus: string) => Promise<void>;
  onDeleteSubtask: (id: string) => Promise<void>;
  onUpdateReview?: (
    status: TaskWithRelations["review_status"],
    reviewNotes?: string
  ) => Promise<void>;
  editableOverride?: boolean;
  allowCommentsOverride?: boolean;
}

export function TaskDetail({
  open,
  onClose,
  task,
  project,
  goalTitle,
  onEdit,
  onDelete,
  onAddSubtask,
  onToggleSubtask,
  onDeleteSubtask,
  onUpdateReview,
  editableOverride,
  allowCommentsOverride,
}: TaskDetailProps) {
  const isDone = task.status === "done";
  const isOverdue =
    task.deadline && !isDone && isTaskDeadlineOverdue(task.deadline);
  const { can } = useTeamPermissions(task.team_id);
  const { userId } = useTeams();
  const canEditTask = editableOverride ?? (!task.team_id || can("tasks", "edit"));
  const canCommentOnTask =
    allowCommentsOverride ?? (!task.team_id || can("comments", "comment"));
  const commentsPlaceholder =
    task.team_id || task.project_id
      ? "Write an update, decision, or unblock request..."
      : "Add a private comment...";
  const canRequestReview = canEditTask && !!task.reviewer_id;
  const canRespondToReview =
    !!task.reviewer_id && userId === task.reviewer_id && task.review_status === "pending_review";
  const needsAssigneeAction =
    task.review_status === "changes_requested" && !!userId && userId === task.assignee_id;
  const [reviewNotes, setReviewNotes] = useState(task.review_notes || "");
  const [reviewSubmitting, setReviewSubmitting] = useState(false);
  const {
    connections: githubConnections,
    links: githubLinks,
    loading: githubLoading,
    createIssue,
    deleteLink,
    refetch,
  } = useTaskGitHubLinks(task.id, task.team_id);
  const [selectedGitHubConnectionId, setSelectedGitHubConnectionId] = useState("");
  const [githubIssueBody, setGitHubIssueBody] = useState("");
  const [githubSubmitting, setGitHubSubmitting] = useState(false);
  const [githubFeedback, setGitHubFeedback] = useState<string | null>(null);
  const [githubSyncing, setGitHubSyncing] = useState(false);

  const activeGitHubConnections = useMemo(
    () => githubConnections.filter((connection) => connection.is_active),
    [githubConnections]
  );

  useEffect(() => {
    setReviewNotes(task.review_notes || "");
  }, [task.id, task.review_notes]);

  useEffect(() => {
    setGitHubFeedback(null);
    setGitHubIssueBody("");
    setSelectedGitHubConnectionId((current) => {
      if (current && activeGitHubConnections.some((connection) => connection.id === current)) {
        return current;
      }
      return activeGitHubConnections[0]?.id || "";
    });
  }, [activeGitHubConnections, task.id]);

  async function handleReview(status: TaskWithRelations["review_status"]) {
    if (!onUpdateReview) return;
    setReviewSubmitting(true);
    try {
      await onUpdateReview(status, reviewNotes.trim());
    } finally {
      setReviewSubmitting(false);
    }
  }

  async function handleCreateGitHubIssue() {
    if (!selectedGitHubConnectionId || githubSubmitting) return;

    setGitHubSubmitting(true);
    setGitHubFeedback(null);
    try {
      await createIssue({
        connectionId: selectedGitHubConnectionId,
        body: githubIssueBody.trim() || undefined,
      });
      setGitHubIssueBody("");
      setGitHubFeedback("GitHub issue created and linked to this task.");
    } catch (error) {
      setGitHubFeedback(error instanceof Error ? error.message : "GitHub issue could not be created.");
    } finally {
      setGitHubSubmitting(false);
    }
  }

  async function handleDeleteGitHubLink(linkId: string) {
    try {
      await deleteLink(linkId);
      setGitHubFeedback("GitHub issue link removed.");
    } catch (error) {
      setGitHubFeedback(error instanceof Error ? error.message : "GitHub issue link could not be removed.");
    }
  }

  async function handleSyncGitHub(direction: "pull" | "push") {
    setGitHubSyncing(true);
    setGitHubFeedback(null);
    try {
      const res = await fetch(`/api/tasks/${task.id}/github-sync`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ direction }),
      });
      const json = await res.json();
      if (!res.ok) {
        throw new Error(json.error || "GitHub sync failed.");
      }
      setGitHubFeedback(
        direction === "pull"
          ? `Pulled ${json.synced} issue state update${json.synced === 1 ? "" : "s"} from GitHub.`
          : `Pushed task status to ${json.synced} linked issue${json.synced === 1 ? "" : "s"}.`
      );
      await refetch();
    } catch (error) {
      setGitHubFeedback(error instanceof Error ? error.message : "GitHub sync failed.");
    } finally {
      setGitHubSyncing(false);
    }
  }

  return (
    <Modal open={open} onClose={onClose} className="max-w-2xl">
      <div className="space-y-5">
        {/* Header */}
        <div>
          <div className="flex items-start justify-between gap-3">
            <h2
              className={cn(
                "text-lg font-semibold",
                isDone && "line-through text-muted-foreground"
              )}
            >
              {task.title}
            </h2>
            <div className="flex items-center gap-1 shrink-0">
              <RemindMeButton
                body={task.description}
                label="Reminder für diese Aufgabe"
                sourceId={task.id}
                sourceTitle={task.title}
                sourceType="task"
                sourceUrl={`/tasks?task=${task.id}`}
                variant="icon"
              />
              <Button variant="ghost" size="icon" onClick={onEdit} disabled={!canEditTask}>
                <Pencil className="h-4 w-4" />
              </Button>
              <Button variant="ghost" size="icon" onClick={onDelete} disabled={!canEditTask}>
                <Trash2 className="h-4 w-4 text-destructive" />
              </Button>
              <button
                onClick={onClose}
                className="rounded-md p-1.5 hover:bg-accent transition-colors cursor-pointer ml-1"
                title="Schließen"
              >
                <X className="h-5 w-5 text-red-500" />
              </button>
            </div>
          </div>

        </div>

        {/* Description */}
        <div className="space-y-1.5">
          <div className="text-[11px] uppercase tracking-[0.16em] text-muted-foreground">
            Description
          </div>
          {task.description ? (
            <p className="text-sm text-foreground whitespace-pre-wrap">
              {task.description}
            </p>
          ) : (
            <p className="text-sm italic text-muted-foreground">No description</p>
          )}
        </div>

        {/* Meta */}
        <div className="flex flex-wrap gap-2">
          <Badge variant="secondary" className="text-xs">
            {STATUS_LABELS[task.status] || task.status}
          </Badge>

          {task.priority !== "none" && (
            <Badge
              className={cn(
                "text-xs border-0",
                PRIORITY_COLORS[task.priority]
              )}
            >
              {task.priority.charAt(0).toUpperCase() + task.priority.slice(1)}
            </Badge>
          )}

          {task.deadline && (
            <Badge
              variant="outline"
              className={cn("text-xs gap-1", isOverdue && "border-destructive text-destructive")}
            >
              <Calendar className="h-3 w-3" />
              {formatRelativeDate(task.deadline)}
            </Badge>
          )}

          {project && (
            <Badge variant="outline" className="text-xs gap-1">
              <FolderKanban className="h-3 w-3" />
              {project.icon} {project.name}
            </Badge>
          )}

          {goalTitle && (
            <Badge variant="outline" className="text-xs gap-1">
              <Target className="h-3 w-3" />
              {goalTitle}
            </Badge>
          )}

          {task.assignee && (
            <Badge variant="outline" className="text-xs gap-1">
              <User2 className="h-3 w-3" />
              {task.assignee.full_name || task.assignee.email}
            </Badge>
          )}

          {task.recurrence_pattern !== "none" && (
            <Badge variant="outline" className="text-xs gap-1">
              <Repeat className="h-3 w-3" />
              {recurrenceLabel(task.recurrence_pattern, task.recurrence_interval)}
            </Badge>
          )}

          {task.review_status !== "not_required" && (
            <Badge variant="outline" className={cn("text-xs", REVIEW_STATUS_META[task.review_status].className)}>
              {REVIEW_STATUS_META[task.review_status].label}
            </Badge>
          )}
        </div>

        {/* Tags */}
        {task.tags.length > 0 && (
          <div className="flex flex-wrap gap-1.5">
            {task.tags.map((tag) => (
              <span
                key={tag.id}
                className="inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-xs font-medium text-white"
                style={{ backgroundColor: tag.color }}
              >
                {tag.name}
              </span>
            ))}
          </div>
        )}

        {/* Divider */}
        <div className="border-t border-border" />

        {/* Subtasks */}
        <SubtaskList
          subtasks={task.subtasks}
          onAdd={onAddSubtask}
          onToggle={onToggleSubtask}
          onDelete={onDeleteSubtask}
          editable={canEditTask}
        />

        <div className="border-t border-border" />

        <AttachmentsPanel
          entityType="task"
          entityId={task.id}
          projectId={task.project_id}
          teamId={task.team_id}
          editable={canEditTask}
        />

        {(canEditTask || githubLinks.length > 0) && (
          <>
            <div className="border-t border-border" />
            <div className="space-y-3 rounded-2xl border border-border/60 bg-card p-4">
              <div className="flex items-center justify-between gap-3">
                <div>
                  <h3 className="text-sm font-semibold">GitHub</h3>
                  <p className="text-xs text-muted-foreground">
                    Turn this task into an issue in your connected repo and keep the link visible here.
                  </p>
                </div>
                <Badge variant="outline">
                  {githubLoading ? "Loading..." : `${githubLinks.length} linked`}
                </Badge>
              </div>

              {githubFeedback ? (
                <div className="rounded-xl border border-border/60 bg-background/70 px-3 py-2 text-xs text-muted-foreground">
                  {githubFeedback}
                </div>
              ) : null}

              {githubLinks.length > 0 ? (
                <div className="space-y-2">
                  {githubLinks.map((link) => (
                    <div
                      key={link.id}
                      className="flex flex-wrap items-center justify-between gap-3 rounded-xl border border-border/60 bg-background/60 p-3"
                    >
                      <div className="space-y-1">
                        <div className="flex items-center gap-2">
                          <Badge variant="outline">
                            {link.repo_owner}/{link.repo_name}#{link.issue_number}
                          </Badge>
                          <Badge variant="outline">{link.issue_state}</Badge>
                        </div>
                        <p className="text-sm font-medium">{link.issue_title}</p>
                      </div>
                      <div className="flex flex-wrap gap-2">
                        <Button
                          size="sm"
                          variant="outline"
                          onClick={() => window.open(link.issue_url, "_blank", "noopener,noreferrer")}
                        >
                          <ExternalLink className="h-4 w-4" />
                          Open issue
                        </Button>
                        {canEditTask ? (
                          <Button
                            size="sm"
                            variant="ghost"
                            onClick={() => void handleDeleteGitHubLink(link.id)}
                          >
                            <Trash2 className="h-4 w-4 text-destructive" />
                          </Button>
                        ) : null}
                      </div>
                    </div>
                  ))}
                </div>
              ) : null}

              {canEditTask ? (
                activeGitHubConnections.length === 0 ? (
                  <div className="rounded-xl border border-dashed border-border p-4 text-sm text-muted-foreground">
                    Connect GitHub in Integrations and select a target repo to create issues from tasks.
                  </div>
                ) : (
                  <div className="space-y-3">
                    <div className="flex flex-wrap justify-end gap-2">
                      <Button
                        size="sm"
                        variant="outline"
                        onClick={() => void handleSyncGitHub("pull")}
                        disabled={githubSyncing || githubLinks.length === 0}
                      >
                        {githubSyncing ? "Syncing..." : "Pull issue state"}
                      </Button>
                      <Button
                        size="sm"
                        variant="outline"
                        onClick={() => void handleSyncGitHub("push")}
                        disabled={githubSyncing || githubLinks.length === 0}
                      >
                        Push task status
                      </Button>
                    </div>
                    <select
                      value={selectedGitHubConnectionId}
                      onChange={(event) => setSelectedGitHubConnectionId(event.target.value)}
                      className="flex h-10 w-full rounded-md border border-border bg-background px-3 py-2 text-sm"
                    >
                      <option value="">Select GitHub repo...</option>
                      {activeGitHubConnections.map((connection) => {
                        const repoFullName =
                          typeof connection.config.repoFullName === "string"
                            ? connection.config.repoFullName
                            : null;

                        return (
                          <option key={connection.id} value={connection.id}>
                            {connection.name}
                            {repoFullName ? ` · ${repoFullName}` : " · repo not selected"}
                          </option>
                        );
                      })}
                    </select>
                    <Textarea
                      value={githubIssueBody}
                      onChange={(event) => setGitHubIssueBody(event.target.value)}
                      placeholder="Optional GitHub issue body. Leave empty to use a generated summary from the task."
                      className="min-h-[96px]"
                      disabled={githubSubmitting}
                    />
                    <div className="flex justify-end">
                      <Button
                        size="sm"
                        onClick={() => void handleCreateGitHubIssue()}
                        disabled={!selectedGitHubConnectionId || githubSubmitting}
                      >
                        <GitBranch className="h-4 w-4" />
                        {githubSubmitting ? "Creating..." : "Create GitHub issue"}
                      </Button>
                    </div>
                  </div>
                )
              ) : null}
            </div>
          </>
        )}

        {(task.team_id || task.reviewer_id) && (
          <>
            <div className="border-t border-border" />
            <div className="space-y-3 rounded-2xl border border-border/60 bg-card p-4">
              <div className="flex items-center justify-between gap-3">
                <div>
                  <h3 className="text-sm font-semibold">Review Flow</h3>
                  <p className="text-xs text-muted-foreground">
                    Route work through a clear review step before it is considered finished.
                  </p>
                </div>
                <Badge variant="outline" className={REVIEW_STATUS_META[task.review_status].className}>
                  {REVIEW_STATUS_META[task.review_status].label}
                </Badge>
              </div>

              {(canRespondToReview || needsAssigneeAction) && (
                <div className="flex items-center gap-2 rounded-xl border border-amber-500/30 bg-amber-500/10 px-3 py-2.5 text-sm font-medium text-amber-700 dark:text-amber-400">
                  <GitPullRequestArrow className="h-4 w-4 shrink-0" />
                  {canRespondToReview
                    ? "It's your turn — take the lead on this review."
                    : "Changes were requested — take the lead and update this task."}
                </div>
              )}

              <div className="grid gap-3 sm:grid-cols-2">
                <div className="rounded-xl border border-border/60 bg-background/60 p-3">
                  <div className="text-[11px] uppercase tracking-[0.16em] text-muted-foreground">
                    Reviewer
                  </div>
                  <div className="mt-2 text-sm font-medium">
                    {task.reviewer
                      ? task.reviewer.full_name || task.reviewer.email
                      : "No reviewer assigned"}
                  </div>
                </div>
                <div className="rounded-xl border border-border/60 bg-background/60 p-3">
                  <div className="text-[11px] uppercase tracking-[0.16em] text-muted-foreground">
                    Timeline
                  </div>
                  <div className="mt-2 text-sm text-muted-foreground">
                    {task.review_requested_at
                      ? `Requested ${formatRelativeDate(task.review_requested_at)}`
                      : "No review requested yet"}
                    {task.reviewed_at
                      ? `, last updated ${formatRelativeDate(task.reviewed_at)}`
                      : ""}
                  </div>
                </div>
              </div>

              <div className="space-y-1.5">
                <div className="text-[11px] uppercase tracking-[0.16em] text-muted-foreground">
                  Review notes
                </div>
                <Textarea
                  value={reviewNotes}
                  onChange={(event) => setReviewNotes(event.target.value)}
                  placeholder="Capture what should be checked, what changed, or what still needs attention..."
                  className="min-h-[96px]"
                  disabled={(!canRequestReview && !canRespondToReview) || reviewSubmitting}
                />
              </div>

              <div className="flex flex-wrap justify-end gap-2">
                {canRequestReview && (
                  <Button
                    size="sm"
                    variant="outline"
                    onClick={() => void handleReview("pending_review")}
                    disabled={reviewSubmitting || task.review_status === "pending_review"}
                  >
                    <GitPullRequestArrow className="h-4 w-4" />
                    {reviewSubmitting && task.review_status !== "pending_review"
                      ? "Updating..."
                      : "Request review"}
                  </Button>
                )}
                {canRespondToReview && (
                  <>
                    <Button
                      size="sm"
                      variant="outline"
                      onClick={() => void handleReview("changes_requested")}
                      disabled={reviewSubmitting}
                    >
                      <AlertTriangle className="h-4 w-4" />
                      Request changes
                    </Button>
                    <Button
                      size="sm"
                      onClick={() => void handleReview("approved")}
                      disabled={reviewSubmitting}
                    >
                      <CheckCheck className="h-4 w-4" />
                      Approve
                    </Button>
                  </>
                )}
              </div>
            </div>
          </>
        )}

        {(task.team_id || task.project_id) && (
          <>
            <div className="border-t border-border" />
            <CommentsPanel
              entityType="task"
              entityId={task.id}
              teamId={task.team_id}
              title="Discussion"
              allowCommentOverride={canCommentOnTask}
              placeholderOverride={commentsPlaceholder}
            />
          </>
        )}
      </div>
    </Modal>
  );
}
