import { logApiError } from "@/lib/api/security";
import { NextResponse } from "next/server";
import { canAccessWorkspace } from "@/lib/developers/auth";
import {
  createGitHubIssue,
  decryptGitHubToken,
  parseGitHubConfig,
} from "@/lib/integrations/github";
import { createAdminClient } from "@/lib/supabase/admin";
import { createRouteClient } from "@/lib/supabase/route";

function buildIssueBody(input: {
  title: string;
  description: string | null;
  priority: string;
  status: string;
  deadline: string | null;
}) {
  const sections = [
    "Created from Mindavio task.",
    "",
    `- Priority: ${input.priority}`,
    `- Status: ${input.status}`,
    `- Deadline: ${input.deadline ? new Date(input.deadline).toLocaleString() : "None"}`,
    "",
    "Task details:",
    input.description?.trim() || "No additional description.",
  ];

  return sections.join("\n");
}

async function loadTaskForGitHub(taskId: string) {
  const supabase = await createRouteClient();
  const {
    data: { user },
  } = await supabase.auth.getUser();

  if (!user) {
    return {
      supabase,
      user: null,
      task: null,
      error: NextResponse.json({ error: "Unauthorized" }, { status: 401 }),
    };
  }

  const { data: task } = await supabase
    .from("tasks")
    .select("id, user_id, team_id, title, description, priority, status, deadline")
    .eq("id", taskId)
    .maybeSingle();

  if (!task) {
    return {
      supabase,
      user,
      task: null,
      error: NextResponse.json({ error: "Task not found" }, { status: 404 }),
    };
  }

  const hasAccess =
    task.user_id === user.id &&
    !task.team_id
      ? true
      : await canAccessWorkspace(user.id, task.team_id || null);

  if (!hasAccess) {
    return {
      supabase,
      user,
      task: null,
      error: NextResponse.json({ error: "Forbidden" }, { status: 403 }),
    };
  }

  return {
    supabase,
    user,
    task,
    error: null,
  };
}

export async function GET(
  _req: Request,
  context: { params: Promise<{ id: string }> }
) {
  try {
    const { id } = await context.params;
    const loaded = await loadTaskForGitHub(id);
    if (loaded.error) return loaded.error;

    const { supabase } = loaded;
    const { data, error } = await supabase
      .from("github_issue_links")
      .select("*")
      .eq("task_id", id)
      .order("created_at", { ascending: false });

    if (error) {
      return NextResponse.json({ error: error.message }, { status: 400 });
    }

    return NextResponse.json({ links: data || [] });
  } catch (error) {
    logApiError("Task GitHub links GET error:", error);
    return NextResponse.json({ error: "Failed to load GitHub links" }, { status: 500 });
  }
}

export async function POST(
  _req: Request,
  context: { params: Promise<{ id: string }> }
) {
  try {
    const admin = createAdminClient();
    const { id } = await context.params;
    const loaded = await loadTaskForGitHub(id);
    if (loaded.error || !loaded.user || !loaded.task) return loaded.error!;

    const { supabase, user, task } = loaded;
    const body = await _req.json();
    const connectionId = typeof body.connectionId === "string" ? body.connectionId : "";

    if (!connectionId) {
      return NextResponse.json({ error: "GitHub connection is required" }, { status: 400 });
    }

    const { data: connection } = await admin
      .from("integration_connections")
      .select("id, user_id, team_id, provider, config, secret_encrypted, is_active")
      .eq("id", connectionId)
      .eq("provider", "github")
      .maybeSingle();

    if (!connection) {
      return NextResponse.json({ error: "GitHub connection not found" }, { status: 404 });
    }

    if ((connection.team_id || null) !== (task.team_id || null)) {
      return NextResponse.json(
        { error: "GitHub connection must belong to the same workspace as the task" },
        { status: 400 }
      );
    }

    if (!connection.is_active) {
      return NextResponse.json({ error: "GitHub connection is paused" }, { status: 400 });
    }

    const config = parseGitHubConfig(connection.config || {});
    if (!config.repoOwner || !config.repoName) {
      return NextResponse.json(
        { error: "Select a target GitHub repository in Integrations first" },
        { status: 400 }
      );
    }

    const issue = await createGitHubIssue({
      token: decryptGitHubToken(connection.secret_encrypted),
      owner: config.repoOwner,
      repo: config.repoName,
      title: task.title,
      body:
        typeof body.body === "string" && body.body.trim()
          ? body.body.trim()
          : buildIssueBody(task),
    });

    const { data, error } = await supabase
      .from("github_issue_links")
      .insert({
        connection_id: connection.id,
        task_id: task.id,
        user_id: user.id,
        team_id: task.team_id,
        repo_owner: config.repoOwner,
        repo_name: config.repoName,
        issue_number: issue.number,
        issue_title: issue.title,
        issue_url: issue.html_url,
        issue_state: issue.state,
      })
      .select("*")
      .single();

    if (error) {
      return NextResponse.json({ error: error.message }, { status: 400 });
    }

    return NextResponse.json({ link: data });
  } catch (error) {
    logApiError("Task GitHub links POST error:", error);
    const message = error instanceof Error ? error.message : "Failed to create GitHub issue";
    return NextResponse.json({ error: message }, { status: 500 });
  }
}
