"use server"

import { ActionResponse, createErrorResponse, createSuccessResponse } from "@/lib/action-response"
import { GitHubUserSearchResult, Member, UserRole } from "@/lib/types"
import {
  deleteOrganizationMemberApiKeys,
  getUserById,
  organizationMemberRepository,
  prisma,
} from "@codeflash-ai/common"

/**
 * Get organization members
 */
export async function getOrganizationMembers(
  currentUserId: string,
  organizationId: string,
): Promise<ActionResponse<Member[]>> {
  try {
    const org = await prisma.organizations.findFirst({
      where: { id: organizationId },
      include: {
        organization_members: {
          include: {
            user: true,
          },
          orderBy: {
            added_at: "asc",
          },
        },
      },
    })

    if (!org) {
      return createErrorResponse("Organization not found")
    }

    // Check if user has access
    const hasAccess = org.organization_members.some(m => m.user_id === currentUserId)

    if (!hasAccess) {
      return createErrorResponse("You don't have access to this organization")
    }

    const members: Member[] = org.organization_members.map(member => ({
      id: member.id,
      user_id: member.user_id,
      username: member.user.github_username,
      name: member.user.name,
      email: member.user.email,
      role: member.role,
      added_at: member.added_at,
      avatarUrl: `https://github.com/${member.user.github_username}.png`,
    }))

    return createSuccessResponse(members)
  } catch (error) {
    console.error("Failed to get organization members:", error)
    return createErrorResponse(error instanceof Error ? error.message : "Failed to get members")
  }
}

/**
 * Add a member to organization
 */
export async function addOrganizationMember(
  currentUserId: string,
  invitedUser: GitHubUserSearchResult,
  role: UserRole,
  organizationId: string,
): Promise<ActionResponse<Member>> {
  try {
    const org = await prisma.organizations.findFirst({
      where: { id: organizationId },
      include: {
        organization_members: true,
      },
    })
    const invitedUserId = `github|${invitedUser.githubUserId.toString()}`

    if (!org) {
      return createErrorResponse("Organization not found")
    }

    const currentUserMember = org.organization_members.find(m => m.user_id === currentUserId)

    // Check if user has permission to add members
    const isAdmin = currentUserMember?.role === "admin" || currentUserMember?.role === "owner"

    if (!isAdmin) {
      return createErrorResponse("You don't have permission to add members")
    }

    // Check if member already exists by username
    const existingMember = org.organization_members.find(m => m.user_id === invitedUserId)

    if (existingMember) {
      return createErrorResponse("User is already a member of this organization")
    }

    // Check if user exists in our database
    let user = await getUserById(invitedUserId)

    // If user doesn't exist, create them
    if (!user) {
      user = await prisma.users.create({
        data: {
          user_id: invitedUserId,
          github_username: invitedUser.username,
          onboarding_completed: false,
        },
      })
    }

    // Add user to organization members
    const newMember = await prisma.organization_members.create({
      data: {
        organization_id: organizationId,
        user_id: user.user_id,
        role,
        added_by: currentUserId,
      },
    })
    return createSuccessResponse({
      id: newMember.id,
      user_id: newMember.user_id,
      username: invitedUser.username,
      name: user.name,
      email: user.email,
      role: newMember.role,
      added_at: newMember.added_at,
      avatarUrl: invitedUser.avatarUrl,
    })
  } catch (error) {
    console.error("Failed to add organization member:", error)
    return createErrorResponse(error instanceof Error ? error.message : "Failed to add member")
  }
}

/**
 * Update organization member role
 */
export async function updateOrganizationMemberRole(
  currentUserId: string,
  organizationId: string,
  memberId: string,
  newRole: "admin" | "member" | "owner",
): Promise<ActionResponse<Boolean>> {
  try {
    const org = await prisma.organizations.findFirst({
      where: { id: organizationId },
      include: {
        organization_members: true,
      },
    })

    if (!org) {
      return createErrorResponse("Organization not found")
    }

    const currentUserMember = org.organization_members.find(m => m.user_id === currentUserId)

    // Only admins and owners can change roles
    if (currentUserMember?.role !== "admin" && currentUserMember?.role !== "owner") {
      return createErrorResponse("Only admins can change member roles")
    }

    // Don't allow changing owner role
    const targetMember = org.organization_members.find(m => m.id === memberId)
    if (targetMember?.role === "owner") {
      return createErrorResponse("Cannot change owner role")
    }

    // Don't allow changing own role if you're the only admin
    const adminCount = org.organization_members.filter(
      m => m.role === "admin" || m.role === "owner",
    ).length

    if (targetMember?.user_id === currentUserId) {
      return createErrorResponse("Cannot change your own role as the only admin")
    }

    await prisma.organization_members.update({
      where: { id: memberId },
      data: { role: newRole },
    })

    return createSuccessResponse(true)
  } catch (error) {
    console.error("Failed to update member role:", error)
    return createErrorResponse("Failed to update role")
  }
}

/**
 * Remove organization member
 */
export async function removeOrganizationMember(
  currentUserId: string,
  organizationId: string,
  memberId: string,
): Promise<ActionResponse<Boolean>> {
  try {
    const org = await prisma.organizations.findFirst({
      where: { id: organizationId },
      include: {
        organization_members: true,
      },
    })

    if (!org) {
      return createErrorResponse("Organization not found")
    }

    const currentUserMember = org.organization_members.find(m => m.user_id === currentUserId)
    const targetMember = org.organization_members.find(m => m.id === memberId)

    if (!targetMember) {
      return createErrorResponse("Member not found")
    }

    // Cannot remove owner
    if (targetMember.role === "owner") {
      return createErrorResponse("Cannot remove organization owner")
    }

    // Check permissions
    const isAdmin = currentUserMember?.role === "admin" || currentUserMember?.role === "owner"
    const isSelf = targetMember.user_id === currentUserId

    if (!isAdmin && !isSelf) {
      return createErrorResponse("You don't have permission to remove this member")
    }

    if (isSelf) {
      return createErrorResponse("Cannot remove yourself as the only admin")
    }

    // Delete all organization API keys created by this user before removing them
    await deleteOrganizationMemberApiKeys(targetMember.user_id, organizationId)

    await organizationMemberRepository.delete(memberId)

    return createSuccessResponse(true)
  } catch (error) {
    console.error("Failed to remove organization member:", error)
    return createErrorResponse("Failed to remove member")
  }
}

/**
 * Get current user's role in organization
 */
export async function getCurrentUserRole(
  userId: string,
  organizationId: string,
): Promise<ActionResponse<{ role: UserRole }>> {
  try {
    const member = await prisma.organization_members.findFirst({
      where: {
        organization_id: organizationId,
        user_id: userId,
      },
    })

    if (!member) {
      return createErrorResponse("Member not found")
    }

    return createSuccessResponse({ role: member.role as UserRole })
  } catch (error) {
    console.error("Failed to get user role:", error)
    return createErrorResponse(error instanceof Error ? error.message : "Failed to get user role")
  }
}
