import { GraphQLError } from 'graphql'

import { prisma } from '../../../lib/prisma'
import { Context } from '../../context'
import { DomainResolvers } from '../shared/types'

// Cart Domain Resolvers - изолированная логика корзины и избранного
export const cartResolvers: DomainResolvers = {
  Query: {
    // Получение корзины текущего пользователя
    myCart: async (_: unknown, __: unknown, context: Context) => {
      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('У пользователя нет организации')
      }

      // Найти или создать корзину для организации
      let cart = await prisma.cart.findUnique({
        where: { organizationId: currentUser.organization.id },
        include: {
          items: {
            include: {
              product: {
                include: {
                  category: true,
                  organization: {
                    include: {
                      users: true,
                    },
                  },
                },
              },
            },
            orderBy: {
              createdAt: 'desc',
            },
          },
          organization: {
            include: {
              users: true,
            },
          },
        },
      })

      if (!cart) {
        cart = await prisma.cart.create({
          data: {
            organizationId: currentUser.organization.id,
            items: {
              create: [],
            },
          },
          include: {
            items: {
              include: {
                product: {
                  include: {
                    category: true,
                    organization: {
                      include: {
                        users: true,
                      },
                    },
                  },
                },
              },
            },
            organization: {
              include: {
                users: true,
              },
            },
          },
        })
      }

      return cart
    },

    // Получение избранных товаров текущего пользователя
    myFavorites: async (_: unknown, __: unknown, context: Context) => {
      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('У пользователя нет организации')
      }

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

      return favorites.map((fav) => fav.product)
    },
  },

  Mutation: {
    // Добавление товара в корзину
    addToCart: async (_: unknown, args: { productId: string; quantity: number }, context: Context) => {
      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('У пользователя нет организации')
      }

      // Проверяем, что товар существует и активен
      const product = await prisma.product.findFirst({
        where: {
          id: args.productId,
          isActive: true,
        },
        include: {
          organization: true,
        },
      })

      if (!product) {
        return {
          success: false,
          message: 'Товар не найден или неактивен',
        }
      }

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

      // Найти или создать корзину
      let cart = await prisma.cart.findUnique({
        where: { organizationId: currentUser.organization.id },
      })

      if (!cart) {
        cart = await prisma.cart.create({
          data: {
            organizationId: currentUser.organization.id,
          },
        })
      }

      try {
        // Проверяем, есть ли уже этот товар в корзине
        const existingItem = await prisma.cartItem.findFirst({
          where: {
            cartId: cart.id,
            productId: args.productId,
          },
        })

        if (existingItem) {
          // Обновляем количество
          await prisma.cartItem.update({
            where: {
              id: existingItem.id,
            },
            data: {
              quantity: existingItem.quantity + args.quantity,
            },
          })
        } else {
          // Создаем новый элемент корзины
          await prisma.cartItem.create({
            data: {
              cartId: cart.id,
              productId: args.productId,
              quantity: args.quantity,
            },
          })
        }

        // Возвращаем обновленную корзину
        const updatedCart = await prisma.cart.findUnique({
          where: { id: cart.id },
          include: {
            items: {
              include: {
                product: {
                  include: {
                    category: true,
                    organization: {
                      include: {
                        users: true,
                      },
                    },
                  },
                },
              },
              orderBy: {
                createdAt: 'desc',
              },
            },
            organization: {
              include: {
                users: true,
              },
            },
          },
        })

        return {
          success: true,
          message: 'Товар добавлен в корзину',
          cart: updatedCart,
        }
      } catch (error) {
        console.error('Ошибка при добавлении в корзину:', error)
        return {
          success: false,
          message: 'Ошибка при добавлении товара в корзину',
        }
      }
    },

    // Удаление товара из корзины
    removeFromCart: async (_: unknown, args: { productId: string }, context: Context) => {
      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('У пользователя нет организации')
      }

      const cart = await prisma.cart.findUnique({
        where: { organizationId: currentUser.organization.id },
      })

      if (!cart) {
        return {
          success: false,
          message: 'Корзина не найдена',
        }
      }

      try {
        await prisma.cartItem.delete({
          where: {
            cartId_productId: {
              cartId: cart.id,
              productId: args.productId,
            },
          },
        })

        // Возвращаем обновленную корзину
        const updatedCart = await prisma.cart.findUnique({
          where: { id: cart.id },
          include: {
            items: {
              include: {
                product: {
                  include: {
                    category: true,
                    organization: {
                      include: {
                        users: true,
                      },
                    },
                  },
                },
              },
              orderBy: {
                createdAt: 'desc',
              },
            },
            organization: {
              include: {
                users: true,
              },
            },
          },
        })

        return {
          success: true,
          message: 'Товар удален из корзины',
          cart: updatedCart,
        }
      } catch (error) {
        console.error('Ошибка при удалении из корзины:', error)
        return {
          success: false,
          message: 'Товар не найден в корзине',
        }
      }
    },

    // Очистка корзины
    clearCart: async (_: unknown, __: unknown, context: Context) => {
      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('У пользователя нет организации')
      }

      const cart = await prisma.cart.findUnique({
        where: { organizationId: currentUser.organization.id },
      })

      if (!cart) {
        return false
      }

      try {
        await prisma.cartItem.deleteMany({
          where: { cartId: cart.id },
        })

        return true
      } catch (error) {
        console.error('Ошибка при очистке корзины:', error)
        return false
      }
    },

    // Добавление товара в избранное
    addToFavorites: async (_: unknown, args: { productId: string }, context: Context) => {
      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('У пользователя нет организации')
      }

      // Проверяем, что товар существует и активен
      const product = await prisma.product.findFirst({
        where: {
          id: args.productId,
          isActive: true,
        },
        include: {
          organization: true,
        },
      })

      if (!product) {
        return {
          success: false,
          message: 'Товар не найден или неактивен',
        }
      }

      // Проверяем, что пользователь не пытается добавить свой собственный товар
      if (product.organizationId === currentUser.organization.id) {
        return {
          success: false,
          message: 'Нельзя добавлять собственные товары в избранное',
        }
      }

      try {
        // Проверяем, есть ли уже этот товар в избранном
        const existing = await prisma.favorites.findFirst({
          where: {
            organizationId: currentUser.organization.id,
            productId: args.productId,
          },
        })

        if (existing) {
          return {
            success: false,
            message: 'Товар уже в избранном',
          }
        }

        // Добавляем в избранное
        await prisma.favorites.create({
          data: {
            organizationId: currentUser.organization.id,
            productId: args.productId,
          },
        })

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

        return {
          success: true,
          message: 'Товар добавлен в избранное',
          favorites: favorites.map((fav) => fav.product),
        }
      } catch (error) {
        console.error('Ошибка при добавлении в избранное:', error)
        return {
          success: false,
          message: 'Ошибка при добавлении товара в избранное',
        }
      }
    },

    // Удаление товара из избранного
    removeFromFavorites: async (_: unknown, args: { productId: string }, context: Context) => {
      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 {
        // Удаляем товар из избранного
        await prisma.favorites.deleteMany({
          where: {
            organizationId: currentUser.organization.id,
            productId: args.productId,
          },
        })

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

        return {
          success: true,
          message: 'Товар удален из избранного',
          favorites: favorites.map((fav) => fav.product),
        }
      } catch (error) {
        console.error('Ошибка при удалении из избранного:', error)
        return {
          success: false,
          message: 'Ошибка при удалении товара из избранного',
        }
      }
    },
  },

  // Type resolvers для Cart и CartItem
  Cart: {
    totalPrice: (parent: { items: Array<{ product: { price: number }; quantity: number }> }) => {
      return parent.items.reduce((total, item) => {
        return total + Number(item.product.price) * item.quantity
      }, 0)
    },
    totalItems: (parent: { items: Array<{ quantity: number }> }) => {
      return parent.items.reduce((total, item) => total + item.quantity, 0)
    },
  },

  CartItem: {
    totalPrice: (parent: { product: { price: number }; quantity: number }) => {
      return Number(parent.product.price) * parent.quantity
    },
    isAvailable: (parent: { product: { quantity: number; isActive: boolean }; quantity: number }) => {
      return parent.product.isActive && parent.product.quantity >= parent.quantity
    },
    availableQuantity: (parent: { product: { quantity: number } }) => {
      return parent.product.quantity
    },
  },
}