"use server"

import { revalidatePath } from "next/cache"

import {
  createAssignment,
  updateAssignment,
} from "@/lib/actions/assignament.actions"
import {
  CreateAssetFormType,
  createAssetSchema,
  UpdateAssetFormType,
  updateAssetSchema,
} from "@/lib/schemas/asset.schemas"
import { AssetService } from "@/services/asset.service"
import { AssignmentService } from "@/services/assignment.service"
import { ItemService } from "@/services/item.service"
import { MovementService } from "@/services/movement.service"

export async function createAssetAction(formData: CreateAssetFormType) {
  try {
    const validatedFields = createAssetSchema.safeParse(formData)

    if (!validatedFields.success) {
      return {
        errors: validatedFields.error.flatten().fieldErrors,
      }
    }

    const { itemId, serialNumber, deliveryNote, status, notes, recipientId } =
      validatedFields.data

    const item = await ItemService.findByIdWithCategory(itemId)

    if (!item) {
      return {
        success: false,
        errors: { itemId: ["Item not found"] },
      }
    }

    const existentAsset = await AssetService.findBySerialNumber(serialNumber)

    if (existentAsset) {
      return {
        success: false,
        errors: {
          serialNumber: ["This serial number already exists"],
        },
      }
    }

    const newAsset = await AssetService.create({
      item: { connect: { id: itemId } },
      serialNumber,
      deliveryNote,
      status,
      notes,
    })

    await MovementService.create({
      itemId,
      assetId: newAsset?.id,
      quantity: 1,
      type: status === "ASSIGNED" ? "ASSIGNMENT" : "IN",
    })

    if (status === "AVAILABLE") {
      await ItemService.update(itemId, {
        stock: item.stock + 1,
        name: item.name,
        category: { connect: { id: item.category?.id } },
      })
    }

    if (status === "ASSIGNED" && recipientId) {
      await AssignmentService.create({
        notes: "",
        itemId,
        assetId: newAsset?.id,
        quantity: 1,
        recipientId,
        assignmentDate: new Date(),
      })
    }

    revalidatePath("/inventory/assets")

    return {
      success: true,
      message: "Asset created successfully",
    }
  } catch (error) {
    console.error("Database error:", error)
    return {
      success: false,
      message: "Error creating asset",
    }
  }
}

export async function updateAssetAction(formData: UpdateAssetFormType) {
  const validatedFields = updateAssetSchema.safeParse(formData)

  if (!validatedFields.success) {
    return {
      errors: validatedFields.error.flatten().fieldErrors,
    }
  }

  const { id, itemId, serialNumber, deliveryNote, status, notes, recipientId } =
    validatedFields.data

  try {
    const item = await ItemService.findByIdWithCategory(itemId)

    if (!item) {
      return {
        success: false,
        errors: { itemId: ["Item not found"] },
      }
    }

    const existentAsset = await AssetService.findBySerialNumber(serialNumber)

    if (
      existentAsset &&
      id !== existentAsset.id &&
      existentAsset.serialNumber === serialNumber
    ) {
      return {
        success: false,
        errors: {
          serialNumber: ["This serial number already exists"],
        },
      }
    }

    await AssetService.update(id, {
      item: { connect: { id: itemId } },
      serialNumber,
      deliveryNote,
      status,
      notes,
    })

    await MovementService.create({
      itemId,
      assetId: id,
      quantity: 1,
      type: status === "ASSIGNED" ? "ASSIGNMENT" : "IN",
    })

    if (status === "AVAILABLE") {
      await ItemService.update(itemId, {
        stock: item.stock + 1,
        name: item.name,
        category: { connect: { id: item.category?.id } },
      })
    }

    if (status === "ASSIGNED" && recipientId) {
      if (!recipientId) {
        return {
          success: false,
          errors: { recipientId: ["Recipient is required for assignment"] },
        }
      }

      if (existentAsset?.assignment) {
        await updateAssignment({
          id: existentAsset.assignment.id,
          recipientId,
          quantity: 1,
        })
      } else {
        await createAssignment({
          itemId,
          assetId: id,
          quantity: 1,
          recipientId,
          assignmentDate: new Date(),
        })
      }
    }

    return {
      success: true,
      message: "Asset updated successfully",
    }
  } catch (error) {
    console.error("Database error:", error)
    return {
      success: false,
      message: "Error updating asset",
    }
  }
}
