"use client";
import { Location, Product } from "prisma/generated/client";
import AsyncSelect from "react-select/async"
import styles from "./stock-opname.module.css"
import { Button, Card, CardBody, Input, Modal, ModalBody, ModalContent, ModalHeader, Spacer, Spinner } from "@nextui-org/react";
import { SelectOption } from "@/common/types/select";
import { useStockOpnameStore } from "@/common/stores/useStockOpnameStore";
import { ActionMeta, SingleValue } from "react-select";
import { useMutation } from "@tanstack/react-query";
import { useEffect, useState } from "react";
import toast from "@/common/libs/toast";
import Scanner from "@/common/components/Scanner";
import { AlertCircleIcon, ScanLineIcon } from "lucide-react";
import Link from "next/link";

type ActiveScanner = "product" | "location" | null
type ScannerOption = { value: number, label: string }

const StockOpname = () => {
  const {
    form, updateForm,
    oldOpname, setOldOpname,
    resetForm
  } = useStockOpnameStore()

  useEffect(() => {
    const productId = form.product?.value
    const locationId = form.location?.value

    if (
      typeof productId === 'number' &&
      typeof locationId === 'number'
    ) {
      loadOldQuantity(productId, locationId)
        .then((data) => setOldOpname(data))
    }

  }, [form.product, form.location, setOldOpname])

  // Auto-populate location when a product with assigned location is selected
  useEffect(() => {
    const loadProductAndSetLocation = async () => {
      if (form.product?.value) {
        try {
          const response = await fetch(`/api/product?search=`)
          const data: { products: Product[] } = await response.json()
          const selectedProduct = data?.products.find(p => p.id === form.product?.value)
          
          if (selectedProduct && (selectedProduct as any).location && !form.location?.value) {
            const location = (selectedProduct as any).location
            updateForm('location', {
              value: location.id,
              label: location.name
            })
          }
        } catch (error) {
          console.error('Error loading product location:', error)
        }
      }
    }

    loadProductAndSetLocation()
  }, [form.product?.value, form.location?.value, updateForm])

  const handleSelectChange = (val: SingleValue<SelectOption>, action: ActionMeta<SelectOption>) => {
    updateForm(action.name as keyof typeof form, val)
  }

  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    updateForm(e.target.name as keyof typeof form, e.target.value)
  }

  const saveMutation = useMutation({
    mutationKey: ['stock-opname'],
    mutationFn: async (data: typeof form) => await fetch("/api/stock-opname", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        location: data.location?.value,
        product: data.product?.value,
        quantity: parseInt(data.quantity),
      }),
    }),
    onSuccess(data) {
      if (data.status === 200) {
        toast('Data berhasil disimpan')
        resetForm()
      }
    },
  })

  const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault()
    saveMutation.mutate(form)
  }

  const [activeScanner, setActiveScanner] = useState<ActiveScanner>(null)
  const [scannerVal, setScannerVal] = useState('')
  const [scannerOptions, setScannerOptions] = useState<ScannerOption[]>()
  const [scannerOptionLoading, setScannerOptionLoading] = useState<boolean>(false)

  const handleOnScan = async (data: string) => {
    if (!activeScanner) return
    setScannerVal(data)
    const loadFunc = activeScanner === 'product' ? loadProduct : loadLocation
    setScannerOptionLoading(true)
    const response = await loadFunc(data)
    setScannerOptionLoading(false)
    setScannerOptions(response)
  }

  const handleScannerOptionPress = (option: ScannerOption) => {
    toast(`${activeScanner} berhasil diubah`)
    updateForm(activeScanner as keyof typeof form, option)
    closeModal()
  }

  const closeModal = () => {
    setActiveScanner(null)
    setScannerOptions(undefined)
  }

  return (
    <>
      <div className="font-semibold text-xl">
        Stock Opname
      </div>

      <Spacer y={4} />

      <form className={styles.form} onSubmit={handleSubmit}>
        <div>
          <label htmlFor="location" className={styles.label}>Lokasi Rak</label>
          <div className={styles.inputGroup}>
            <AsyncSelect
              cacheOptions
              defaultOptions
              loadOptions={loadLocation}
              classNamePrefix="react-select"
              id="location"
              name="location"
              placeholder="Pilih lokasi..."
              value={form.location}
              onChange={handleSelectChange}
              className="flex-1"
            />
            <Button type="button" className={styles.scanButton} variant="flat" onPress={() => setActiveScanner('location')}>
              <ScanLineIcon size={20} />
            </Button>
          </div>
        </div>

        <div>
          <label htmlFor="product" className={styles.label}>Produk</label>
          <div className={styles.inputGroup}>
            <AsyncSelect
              cacheOptions
              defaultOptions
              loadOptions={loadProduct}
              classNamePrefix="react-select"
              id="product"
              name="product"
              placeholder="Pilih barang..."
              value={form.product}
              onChange={handleSelectChange}
              className="flex-1"
            />
            <Button type="button" className={styles.scanButton} variant="flat" onPress={() => setActiveScanner('product')}>
              <ScanLineIcon size={20} />
            </Button>
          </div>
        </div>

        <div>
          <label htmlFor="quantity" className={styles.label}>Jumlah</label>
          <Input
            type="number"
            id="quantity"
            name="quantity"
            value={form.quantity}
            onChange={handleInputChange}
            placeholder="Masukan jumlah barang..."
          />
          {oldOpname && (
            <div className="text-sm mt-2 text-neutral-600">
              Jumlah terakhir adalah {' '}
              <span className="font-medium">{oldOpname.quantity}</span>
              {' '} diisi oleh {' '}
              <span className="font-medium">{oldOpname.user.name}</span>.
              {' '}
              <button
                type="button"
                className="text-primary-500 underline"
                onClick={() => updateForm('quantity', oldOpname.quantity.toString())}
              >
                Gunakan
              </button>
            </div>
          )}
        </div>

        <Button
          className="mt-4"
          color="primary"
          type="submit"
          isDisabled={!form.quantity || !form.location || !form.product || saveMutation.isPending}
        >
          {saveMutation.isPending ? <Spinner color="white" size="sm" /> : 'Simpan'}
        </Button>

        <Button as={Link} href="/result" variant="flat">Lihat hasil</Button>
      </form>

      <Modal isOpen={!!activeScanner} onOpenChange={closeModal}>
        <ModalContent className="fixed top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
          <ModalHeader>Scan {activeScanner}</ModalHeader>
          <ModalBody className="pb-6">
            {!scannerOptions && !scannerOptionLoading && (
              <Scanner paused={!activeScanner} onScan={handleOnScan} />
            )}

            {!scannerOptions && scannerOptionLoading && <Spinner />}

            {!!scannerOptions && (
              <>
                <div className="max-h-[60vh] overflow-auto grid grid-cols-1 gap-y-4">
                  {scannerOptions.map((option) => (
                    <Card key={option.value} isPressable shadow="none" className="bg-default-50 border border-default-300" onPress={() => handleScannerOptionPress(option)}>
                      <CardBody>{option.label}</CardBody>
                    </Card>
                  ))}
                </div>
                {scannerOptions.length === 0 && (
                  <div className="flex flex-col justify-center items-center gap-y-4 text-default-700 text-center">
                    <AlertCircleIcon size={36} />
                    <span>
                      Tidak ada opsi untuk ditampilkan dari <span className="font-medium">{scannerVal}</span>
                    </span>
                  </div>
                )}
                <Spacer y={2} />
                <Button variant="flat" onPress={() => setScannerOptions(undefined)}>
                  Scan Ulang
                </Button>
              </>
            )}
          </ModalBody>
        </ModalContent>
      </Modal>

    </>
  )
}

const loadOldQuantity = async (productId: number, locationId: number) => {
  const queryParams = new URLSearchParams({
    productId: productId.toString(),
    locationId: locationId.toString()
  })

  const response = await fetch(`/api/stock-opname/quantity?${queryParams}`)
  const data = await response.json()

  return data
}

const loadLocation = async (inputValue: string) => {
  const response = await fetch(`/api/location?search=${inputValue}`)
  const data: Location[] = await response.json() || []

  return data.map((location) => ({
    value: location.id,
    label: location.name
  }))
}

const loadProduct = async (inputValue: string) => {
  const response = await fetch(`/api/product?search=${inputValue}`)
  const data: { products: Product[] } = await response.json() || []

  return data?.products.map((product: any) => ({
    value: product.id,
    label: `${product.itemCode ? `[${product.itemCode}]` : ''} ${product.name} ${product.barcode ? ` [${product.barcode}]` : ''} ${product.location ? `(Lokasi: ${product.location.name})` : ''}`
  }
  ))
}

export default StockOpname