import { GraphQLError } from 'graphql'

import { prisma } from '../../../lib/prisma'
import { Context } from '../../context'
import { getCurrentUser } from '../shared/auth-utils'
import { DomainResolvers } from '../shared/types'

// Counterparty Management Domain Resolvers - управление партнерами и заявками
export const counterpartyManagementResolvers: DomainResolvers = {
  Query: {
    // Мои контрагенты (партнеры)
    myCounterparties: async (_: unknown, __: unknown, context: Context) => {
      const currentUser = await getCurrentUser(context)

      const counterparties = await prisma.counterparty.findMany({
        where: {
          organizationId: currentUser.organization.id,
        },
        include: {
          counterparty: {
            include: {
              users: true,
              apiKeys: true,
            },
          },
        },
        orderBy: {
          createdAt: 'desc',
        },
        take: 100, // Добавляем пагинацию для производительности
      })

      console.warn('🤝 MY_COUNTERPARTIES:', {
        userId: currentUser.id,
        organizationId: currentUser.organization.id,
        organizationType: currentUser.organization.type,
        counterpartiesCount: counterparties.length,
      })

      return counterparties.map((cp) => cp.counterparty)
    },

    // Входящие заявки на партнерство
    incomingRequests: async (_: unknown, __: unknown, context: Context) => {
      const currentUser = await getCurrentUser(context)

      const incomingRequests = await prisma.counterpartyRequest.findMany({
        where: {
          receiverId: currentUser.organization.id,
          status: 'PENDING',
        },
        include: {
          sender: {
            include: {
              users: true,
              apiKeys: true,
            },
          },
          receiver: {
            include: {
              users: true,
              apiKeys: true,
            },
          },
        },
        orderBy: {
          createdAt: 'desc',
        },
        take: 50, // Добавляем пагинацию для производительности
      })

      console.warn('📥 INCOMING_REQUESTS ДИАГНОСТИКА:', {
        userId: currentUser.id,
        organizationId: currentUser.organization.id,
        organizationType: currentUser.organization.type,
        requestsCount: incomingRequests.length,
        timestamp: new Date().toISOString(),
        requests: incomingRequests.map((r) => ({
          id: r.id,
          senderId: r.senderId,
          senderType: r.sender.type,
          status: r.status,
          createdAt: r.createdAt,
        })),
      })

      return incomingRequests
    },

    // Исходящие заявки на партнерство
    outgoingRequests: async (_: unknown, __: unknown, context: Context) => {
      const currentUser = await getCurrentUser(context)

      const outgoingRequests = await prisma.counterpartyRequest.findMany({
        where: {
          senderId: currentUser.organization.id,
          status: 'PENDING',
        },
        include: {
          sender: {
            include: {
              users: true,
              apiKeys: true,
            },
          },
          receiver: {
            include: {
              users: true,
              apiKeys: true,
            },
          },
        },
        orderBy: {
          createdAt: 'desc',
        },
        take: 50, // Добавляем пагинацию для производительности
      })

      console.warn('📤 OUTGOING_REQUESTS:', {
        userId: currentUser.id,
        organizationId: currentUser.organization.id,
        requestsCount: outgoingRequests.length,
      })

      return outgoingRequests
    },

    // V1 Legacy: Услуги контрагентов
    counterpartyServices: async (_: unknown, __: unknown, context: Context) => {
      console.warn('🔗 COUNTERPARTY_SERVICES (V1) - LEGACY RESOLVER')

      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      // TODO: Реализовать логику получения услуг от контрагентов
      // Это V1 legacy резолвер - может потребоваться миграция на V2
      return []
    },

    // V1 Legacy: Поставки контрагентов
    counterpartySupplies: async (_: unknown, __: unknown, context: Context) => {
      console.warn('📦 COUNTERPARTY_SUPPLIES (V1) - LEGACY RESOLVER')

      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      // TODO: Реализовать логику получения поставок от контрагентов
      // Это V1 legacy резолвер - может потребоваться миграция на V2
      return []
    },
  },

  Mutation: {
    // Отправить заявку на партнерство
    sendCounterpartyRequest: async (
      _: unknown,
      args: {
        input: {
          receiverId: string
          message?: string
          requestType?: string
        }
      },
      context: Context,
    ) => {
      console.warn('📩 SEND_COUNTERPARTY_REQUEST - ВЫЗВАН:', {
        receiverId: args.input.receiverId,
        requestType: args.input.requestType,
        hasMessage: !!args.input.message,
        timestamp: new Date().toISOString(),
      })

      const currentUser = await getCurrentUser(context)

      // Проверяем, что получатель существует
      const receiverOrganization = await prisma.organization.findUnique({
        where: { id: args.input.receiverId },
      })

      if (!receiverOrganization) {
        return {
          success: false,
          message: 'Организация-получатель не найдена',
        }
      }

      // Проверяем, что не отправляем заявку самим себе
      if (currentUser.organization.id === args.input.receiverId) {
        return {
          success: false,
          message: 'Нельзя отправить заявку самому себе',
        }
      }

      try {
        // Проверяем, нет ли уже активной заявки
        const existingRequest = await prisma.counterpartyRequest.findFirst({
          where: {
            senderId: currentUser.organization.id,
            receiverId: args.input.receiverId,
            status: 'PENDING',
          },
        })

        if (existingRequest) {
          return {
            success: false,
            message: 'Заявка уже отправлена и ожидает рассмотрения',
          }
        }

        // Проверяем, нет ли уже партнерства
        const existingPartnership = await prisma.counterparty.findFirst({
          where: {
            organizationId: currentUser.organization.id,
            counterpartyId: args.input.receiverId,
          },
        })

        if (existingPartnership) {
          return {
            success: false,
            message: 'Партнерство уже установлено',
          }
        }

        // Создаем заявку
        const request = await prisma.counterpartyRequest.create({
          data: {
            senderId: currentUser.organization.id,
            receiverId: args.input.receiverId,
            message: args.input.message,
            // TODO: добавить requestType когда будет в модели
            // requestType: args.input.requestType || 'PARTNERSHIP',
            status: 'PENDING',
          },
          include: {
            sender: {
              include: {
                users: true,
                apiKeys: true,
              },
            },
            receiver: {
              include: {
                users: true,
                apiKeys: true,
              },
            },
          },
        })

        console.warn('✅ ЗАЯВКА НА ПАРТНЕРСТВО ОТПРАВЛЕНА:', {
          requestId: request.id,
          senderId: currentUser.organization.id,
          senderType: currentUser.organization.type,
          receiverId: args.input.receiverId,
          receiverType: receiverOrganization.type,
          // requestType: request.requestType, // TODO: когда поле будет в модели
        })

        return {
          success: true,
          message: 'Заявка на партнерство отправлена',
          request,
        }
      } catch (error) {
        console.error('Error sending counterparty request:', error)
        return {
          success: false,
          message: 'Ошибка при отправке заявки',
        }
      }
    },

    // Ответить на заявку партнерства (принять или отклонить)
    respondToCounterpartyRequest: async (
      _: unknown,
      args: {
        input: {
          requestId: string
          action: 'APPROVE' | 'REJECT'
          responseMessage?: string
        }
      },
      context: Context,
    ) => {
      console.warn('✉️ RESPOND_TO_COUNTERPARTY_REQUEST - ВЫЗВАН:', {
        requestId: args.input.requestId,
        action: args.input.action,
        hasResponseMessage: !!args.input.responseMessage,
        timestamp: new Date().toISOString(),
      })

      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      try {
        // Находим заявку
        const request = await prisma.counterpartyRequest.findFirst({
          where: {
            id: args.input.requestId,
            receiverId: currentUser.organization.id, // Только получатель может отвечать
            status: 'PENDING',
          },
          include: {
            sender: true,
            receiver: true,
          },
        })

        if (!request) {
          return {
            success: false,
            message: 'Заявка не найдена или уже обработана',
          }
        }

        if (args.input.action === 'APPROVE') {
          // Одобряем заявку - создаем партнерство

          // Создаем двустороннее партнерство
          await prisma.counterparty.createMany({
            data: [
              {
                organizationId: request.senderId,
                counterpartyId: request.receiverId,
              },
              {
                organizationId: request.receiverId,
                counterpartyId: request.senderId,
              },
            ],
            skipDuplicates: true,
          })

          // Обновляем статус заявки
          const updatedRequest = await prisma.counterpartyRequest.update({
            where: { id: args.input.requestId },
            data: {
              status: 'ACCEPTED',
              // TODO: добавить поля когда будут в модели
              // responseMessage: args.input.responseMessage,
              // respondedAt: new Date(),
            },
            include: {
              sender: {
                include: {
                  users: true,
                  apiKeys: true,
                },
              },
              receiver: {
                include: {
                  users: true,
                  apiKeys: true,
                },
              },
            },
          })

          console.warn('🎉 ЗАЯВКА ОДОБРЕНА И ПАРТНЕРСТВО СОЗДАНО:', {
            requestId: args.input.requestId,
            senderId: request.senderId,
            receiverId: request.receiverId,
            senderType: request.sender.type,
            receiverType: request.receiver.type,
          })

          return {
            success: true,
            message: 'Заявка одобрена. Партнерство установлено!',
            request: updatedRequest,
          }
        } else {
          // Отклоняем заявку
          const updatedRequest = await prisma.counterpartyRequest.update({
            where: { id: args.input.requestId },
            data: {
              status: 'REJECTED',
              // TODO: добавить поля когда будут в модели
              // responseMessage: args.input.responseMessage,
              // respondedAt: new Date(),
            },
            include: {
              sender: {
                include: {
                  users: true,
                  apiKeys: true,
                },
              },
              receiver: {
                include: {
                  users: true,
                  apiKeys: true,
                },
              },
            },
          })

          console.warn('❌ ЗАЯВКА ОТКЛОНЕНА:', {
            requestId: args.input.requestId,
            senderId: request.senderId,
            receiverId: request.receiverId,
            responseMessage: args.input.responseMessage,
          })

          return {
            success: true,
            message: 'Заявка отклонена',
            request: updatedRequest,
          }
        }
      } catch (error) {
        console.error('Error responding to counterparty request:', error)
        return {
          success: false,
          message: 'Ошибка при обработке заявки',
        }
      }
    },

    // Отменить отправленную заявку
    cancelCounterpartyRequest: async (_: unknown, args: { requestId: string }, context: Context) => {
      console.warn('🚫 CANCEL_COUNTERPARTY_REQUEST - ВЫЗВАН:', {
        requestId: args.requestId,
        timestamp: new Date().toISOString(),
      })

      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      try {
        // Находим заявку, которую отправили мы
        const request = await prisma.counterpartyRequest.findFirst({
          where: {
            id: args.requestId,
            senderId: currentUser.organization.id, // Только отправитель может отменить
            status: 'PENDING',
          },
        })

        if (!request) {
          return {
            success: false,
            message: 'Заявка не найдена или уже обработана',
          }
        }

        // Обновляем статус на отмененный
        await prisma.counterpartyRequest.update({
          where: { id: args.requestId },
          data: {
            status: 'CANCELLED',
            // TODO: добавить поле когда будет в модели
            // respondedAt: new Date(),
          },
        })

        console.warn('🗑️ ЗАЯВКА ОТМЕНЕНА:', {
          requestId: args.requestId,
          senderId: currentUser.organization.id,
          receiverId: request.receiverId,
        })

        return {
          success: true,
          message: 'Заявка отменена',
        }
      } catch (error) {
        console.error('Error cancelling counterparty request:', error)
        return {
          success: false,
          message: 'Ошибка при отмене заявки',
        }
      }
    },

    // Удалить партнера (разорвать партнерство)
    removeCounterparty: async (_: unknown, args: { organizationId: string }, context: Context) => {
      console.warn('💔 REMOVE_COUNTERPARTY - ВЫЗВАН:', {
        organizationId: args.organizationId,
        timestamp: new Date().toISOString(),
      })

      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      try {
        // Проверяем, что партнерство существует
        const partnership = await prisma.counterparty.findFirst({
          where: {
            organizationId: currentUser.organization.id,
            counterpartyId: args.organizationId,
          },
        })

        if (!partnership) {
          return {
            success: false,
            message: 'Партнерство не найдено',
          }
        }

        // Удаляем двустороннее партнерство
        await prisma.counterparty.deleteMany({
          where: {
            OR: [
              {
                organizationId: currentUser.organization.id,
                counterpartyId: args.organizationId,
              },
              {
                organizationId: args.organizationId,
                counterpartyId: currentUser.organization.id,
              },
            ],
          },
        })

        console.warn('💥 ПАРТНЕРСТВО РАЗОРВАНО:', {
          organization1: currentUser.organization.id,
          organization2: args.organizationId,
        })

        return {
          success: true,
          message: 'Партнерство разорвано',
        }
      } catch (error) {
        console.error('Error removing counterparty:', error)
        return {
          success: false,
          message: 'Ошибка при разрыве партнерства',
        }
      }
    },

    // Автоматическое создание записи для склада (утилита для фулфилмент центров)
    autoCreateWarehouseEntry: async (_: unknown, args: { partnerId: string }, context: Context) => {
      console.warn('🏭 AUTO_CREATE_WAREHOUSE_ENTRY - ВЫЗВАН:', {
        partnerId: args.partnerId,
        timestamp: new Date().toISOString(),
      })

      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Проверяем, что это фулфилмент центр
      if (currentUser.organization.type !== 'FULFILLMENT') {
        throw new GraphQLError('Функция доступна только для фулфилмент центров')
      }

      try {
        // Проверяем, что партнер существует и это селлер
        const partner = await prisma.organization.findFirst({
          where: {
            id: args.partnerId,
            type: 'SELLER',
          },
        })

        if (!partner) {
          return {
            success: false,
            message: 'Партнер не найден или не является селлером',
          }
        }

        // Проверяем, что есть партнерство
        const partnership = await prisma.counterparty.findFirst({
          where: {
            organizationId: currentUser.organization.id,
            counterpartyId: args.partnerId,
          },
        })

        if (!partnership) {
          return {
            success: false,
            message: 'Партнерство с данной организацией не установлено',
          }
        }

        // TODO: Здесь может быть логика создания складских записей
        // Например, создание дефолтных категорий, настройка процессов и т.д.

        console.warn('✅ СКЛАДСКАЯ ЗАПИСЬ СОЗДАНА:', {
          fulfillmentId: currentUser.organization.id,
          sellerId: args.partnerId,
          sellerName: partner.name || partner.fullName,
        })

        return {
          success: true,
          message: 'Складская запись для партнера создана',
        }
      } catch (error) {
        console.error('Error creating warehouse entry:', error)
        return {
          success: false,
          message: 'Ошибка при создании складской записи',
        }
      }
    },
  },
}
