import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { apiClient } from '../lib/api';
import type {
  ClientCreateRequest,
  InvitationCreate,
  MembershipCreate,
  MembershipUpdate,
  OrganizationCreateRequest,
  OrganizationUpdateRequest,
  ProjectCreateRequest,
  TeamCreateRequest,
} from '../types/api';

// ── Clients ──────────────────────────────────────────────────────────────────

export function useClients() {
  return useQuery({
    queryKey: ['clients'],
    queryFn: () => apiClient.listClients(),
  });
}

export function useClient(clientId: string) {
  return useQuery({
    queryKey: ['clients', clientId],
    queryFn: () => apiClient.getClient(clientId),
    enabled: !!clientId && clientId !== 'undefined',
  });
}

export function useCreateClient() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (data: ClientCreateRequest) => apiClient.createClient(data),
    onSuccess: () => qc.invalidateQueries({ queryKey: ['clients'] }),
  });
}

export function useUpdateClient(clientId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (data: Partial<ClientCreateRequest & { is_active: boolean }>) =>
      apiClient.updateClient(clientId, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['clients'] });
      qc.invalidateQueries({ queryKey: ['clients', clientId] });
    },
  });
}

export function useTeamsForClient(clientId: string | null) {
  return useQuery({
    queryKey: ['clients', clientId, 'teams'],
    queryFn: () => apiClient.listTeams(clientId!),
    enabled: !!clientId,
  });
}

export function useAssignPMAny() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ clientId, userId }: { clientId: string; userId: string }) =>
      apiClient.assignPM(clientId, userId),
    onSuccess: (_, { clientId, userId }) => {
      qc.invalidateQueries({ queryKey: ['clients', clientId, 'pm'] });
      qc.invalidateQueries({ queryKey: ['users', userId] });
      qc.invalidateQueries({ queryKey: ['users'] });
    },
  });
}

export function useRemovePMAny() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ clientId, userId }: { clientId: string; userId: string }) =>
      apiClient.removePM(clientId, userId),
    onSuccess: (_, { clientId, userId }) => {
      qc.invalidateQueries({ queryKey: ['clients', clientId, 'pm'] });
      qc.invalidateQueries({ queryKey: ['users', userId] });
      qc.invalidateQueries({ queryKey: ['users'] });
    },
  });
}

export function useAddTeamMemberAny() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ clientId, teamId, userId }: { clientId: string; teamId: string; userId: string }) =>
      apiClient.addTeamMember(clientId, teamId, userId),
    onSuccess: (_, { clientId }) => qc.invalidateQueries({ queryKey: ['clients', clientId, 'teams'] }),
  });
}

export function useRemoveTeamMemberAny() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ clientId, teamId, userId }: { clientId: string; teamId: string; userId: string }) =>
      apiClient.removeTeamMember(clientId, teamId, userId),
    onSuccess: (_, { clientId }) => qc.invalidateQueries({ queryKey: ['clients', clientId, 'teams'] }),
  });
}

// ── PMs ──────────────────────────────────────────────────────────────────────

export function usePMs(clientId: string) {
  return useQuery({
    queryKey: ['clients', clientId, 'pm'],
    queryFn: () => apiClient.listPMs(clientId),
    enabled: !!clientId && clientId !== 'undefined',
  });
}

export function useAssignPM(clientId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (userId: string) => apiClient.assignPM(clientId, userId),
    onSuccess: () => qc.invalidateQueries({ queryKey: ['clients', clientId, 'pm'] }),
  });
}

export function useRemovePM(clientId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (userId: string) => apiClient.removePM(clientId, userId),
    onSuccess: () => qc.invalidateQueries({ queryKey: ['clients', clientId, 'pm'] }),
  });
}

// ── Teams ─────────────────────────────────────────────────────────────────────

export function useTeams(clientId: string) {
  return useQuery({
    queryKey: ['clients', clientId, 'teams'],
    queryFn: () => apiClient.listTeams(clientId),
    enabled: !!clientId && clientId !== 'undefined',
  });
}

export function useCreateTeam(clientId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (data: TeamCreateRequest) => apiClient.createTeam(clientId, data),
    onSuccess: () => qc.invalidateQueries({ queryKey: ['clients', clientId, 'teams'] }),
  });
}

export function useUpdateTeam(clientId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ teamId, name }: { teamId: string; name: string }) =>
      apiClient.updateTeam(clientId, teamId, name),
    onSuccess: () => qc.invalidateQueries({ queryKey: ['clients', clientId, 'teams'] }),
  });
}

export function useDeleteTeam(clientId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (teamId: string) => apiClient.deleteTeam(clientId, teamId),
    onSuccess: () => qc.invalidateQueries({ queryKey: ['clients', clientId, 'teams'] }),
  });
}

export function useAddTeamMember(clientId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ teamId, userId }: { teamId: string; userId: string }) =>
      apiClient.addTeamMember(clientId, teamId, userId),
    onSuccess: () => qc.invalidateQueries({ queryKey: ['clients', clientId, 'teams'] }),
  });
}

export function useRemoveTeamMember(clientId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ teamId, userId }: { teamId: string; userId: string }) =>
      apiClient.removeTeamMember(clientId, teamId, userId),
    onSuccess: () => qc.invalidateQueries({ queryKey: ['clients', clientId, 'teams'] }),
  });
}

// ── Projects ──────────────────────────────────────────────────────────────────

export function useProjects(clientId: string) {
  return useQuery({
    queryKey: ['clients', clientId, 'projects'],
    queryFn: () => apiClient.listProjects(clientId),
    enabled: !!clientId && clientId !== 'undefined',
  });
}

export function useAllProjects() {
  return useQuery({
    queryKey: ['all-projects'],
    queryFn: () => apiClient.listAllProjects(),
  });
}

export function useCreateProject(clientId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (data: ProjectCreateRequest) => apiClient.createProject(clientId, data),
    onSuccess: () => qc.invalidateQueries({ queryKey: ['clients', clientId, 'projects'] }),
  });
}

export function useUpdateProject(clientId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ projectId, data }: { projectId: string; data: Partial<{ name: string; is_active: boolean }> }) =>
      apiClient.updateProject(clientId, projectId, data),
    onSuccess: () => qc.invalidateQueries({ queryKey: ['clients', clientId, 'projects'] }),
  });
}

export function useArchiveProject(clientId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (projectId: string) => apiClient.archiveProject(clientId, projectId),
    onSuccess: () => qc.invalidateQueries({ queryKey: ['clients', clientId, 'projects'] }),
  });
}

// ── Organizations (SaaS) ──────────────────────────────────────────────────────

export function useOrganizations(options?: { enabled?: boolean }) {
  return useQuery({
    queryKey: ['organizations'],
    queryFn: () => apiClient.listOrganizations(),
    enabled: options?.enabled !== false,
  });
}

export function useOrganization(orgId: string) {
  return useQuery({
    queryKey: ['organizations', orgId],
    queryFn: () => apiClient.getOrganization(orgId),
    enabled: !!orgId && orgId !== 'undefined',
  });
}

export function useCreateOrganization() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (data: OrganizationCreateRequest) => apiClient.createOrganization(data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['organizations'] });
      qc.invalidateQueries({ queryKey: ['clients'] });
    },
  });
}

export function useUpdateOrganization(orgId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (data: OrganizationUpdateRequest) => apiClient.updateOrganization(orgId, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['organizations'] });
      qc.invalidateQueries({ queryKey: ['organizations', orgId] });
      qc.invalidateQueries({ queryKey: ['clients'] });
    },
  });
}

export function useOrgMembers(orgId: string) {
  return useQuery({
    queryKey: ['organizations', orgId, 'members'],
    queryFn: () => apiClient.listOrgMembers(orgId),
    enabled: !!orgId && orgId !== 'undefined',
  });
}

export function useAddOrgMember(orgId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (data: MembershipCreate) => apiClient.addOrgMember(orgId, data),
    onSuccess: () => qc.invalidateQueries({ queryKey: ['organizations', orgId, 'members'] }),
  });
}

export function useUpdateOrgMember(orgId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ userId, data }: { userId: string; data: MembershipUpdate }) =>
      apiClient.updateOrgMember(orgId, userId, data),
    onSuccess: () => qc.invalidateQueries({ queryKey: ['organizations', orgId, 'members'] }),
  });
}

export function useRemoveOrgMember(orgId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (userId: string) => apiClient.removeOrgMember(orgId, userId),
    onSuccess: () => qc.invalidateQueries({ queryKey: ['organizations', orgId, 'members'] }),
  });
}

export function useMyMemberships() {
  return useQuery({
    queryKey: ['my-memberships'],
    queryFn: () => apiClient.getMyMemberships(),
  });
}

export function useBriefAssignees() {
  return useQuery({
    queryKey: ['brief-assignees'],
    queryFn: () => apiClient.listBriefAssignees(),
  });
}

// ── Invitations ───────────────────────────────────────────────────────────────

export function useInvitations(orgId: string) {
  return useQuery({
    queryKey: ['organizations', orgId, 'invitations'],
    queryFn: () => apiClient.listInvitations(orgId),
    enabled: !!orgId && orgId !== 'undefined',
  });
}

export function useCreateInvitation(orgId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (data: InvitationCreate) => apiClient.createInvitation(orgId, data),
    onSuccess: () => qc.invalidateQueries({ queryKey: ['organizations', orgId, 'invitations'] }),
  });
}

export function useRevokeInvitation(orgId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (invitationId: string) => apiClient.revokeInvitation(orgId, invitationId),
    onSuccess: () => qc.invalidateQueries({ queryKey: ['organizations', orgId, 'invitations'] }),
  });
}
