"use client"

import { toastApiError } from "@/lib/toast-api-error";
import { useRouter, useSearchParams } from "next/navigation"
import { zodResolver } from "@hookform/resolvers/zod"
import { Upload } from "lucide-react"
import * as React from "react"
import { Controller, useForm } from "react-hook-form"
import { toast } from "sonner"

import {
  FormPageHeader,
  FormPanel,
  FormSaveBar,
} from "@/app/dashboard/_components/form"
import { Field, FieldError, FieldLabel } from "@/components/ui/field"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { CubFolderUploadPanel } from "@/components/xml-apis/upload-xml/create/cub-folder-upload-panel"
import {
  createUploadXml,
  fetchOcrNewBanks,
  fetchStandardUploadBanks,
} from "@/components/xml-apis/upload-xml/api/upload-xml.api"
import {
  uploadXmlCreateSchema,
  type UploadXmlCreateFormValues,
} from "@/components/xml-apis/upload-xml/create/schema"
import { XmlFileDropzone } from "@/components/xml-apis/shared/xml-file-dropzone"
import {
  percentsForFiles,
  XmlSelectedFileProgressList,
} from "@/components/xml-apis/upload-xml/create/xml-selected-file-progress-list"
import {
  validateXmlFiles,
  XML_UPLOAD_MAX_FILES,
} from "@/components/xml-apis/shared/xml-upload-validation"
import type { SettingsSelectOption } from "@/components/settings/types"
import { SettingsSelect } from "@/components/settings/ui/settings-select"

const listHref = "/dashboard/xml-apis/upload-xml"
const createHref = "/dashboard/xml-apis/upload-xml/create"

export type UploadXmlCreateTab = "standard" | "cub-folder"

function parseCreateTab(value: string | null): UploadXmlCreateTab {
  return value === "cub-folder" ? "cub-folder" : "standard"
}

function isOcrNewCategoryMode(value: string | null): boolean {
  return value === "ocr-new" || value === "12"
}

function buildCreateTabHref(tab: UploadXmlCreateTab, ocrNewCategory: boolean) {
  const params = new URLSearchParams()
  if (ocrNewCategory) params.set("category", "ocr-new")
  if (tab === "cub-folder") params.set("tab", tab)
  const query = params.toString()
  return query ? `${createHref}?${query}` : createHref
}

const PLEASE_SELECT: SettingsSelectOption = { value: "please-select", label: "Please Select" }

export function UploadXmlCreateForm() {
  const router = useRouter()
  const searchParams = useSearchParams()
  const ocrNewCategory = isOcrNewCategoryMode(searchParams.get("category"))
  const activeTab = ocrNewCategory ? "standard" : parseCreateTab(searchParams.get("tab"))

  const [selectedFiles, setSelectedFiles] = React.useState<File[]>([])
  const [fileError, setFileError] = React.useState<string | null>(null)
  const [uploadPercent, setUploadPercent] = React.useState<number | null>(null)
  const [bankApiOptions, setBankApiOptions] = React.useState<SettingsSelectOption[]>([
    PLEASE_SELECT,
  ])

  React.useEffect(() => {
    const controller = new AbortController()

    if (ocrNewCategory) {
      void fetchOcrNewBanks({ signal: controller.signal })
        .then((bankOptions) => {
          setBankApiOptions([PLEASE_SELECT, ...bankOptions])
        })
        .catch((error) => {
          if (controller.signal.aborted || (error instanceof DOMException && error.name === "AbortError")) {
            return
          }
          toast.error("Failed to load OCR New banks")
        })
      return () => controller.abort()
    }

    void fetchStandardUploadBanks({ signal: controller.signal })
      .then((bankOptions) => {
        setBankApiOptions([PLEASE_SELECT, ...bankOptions])
      })
      .catch((error) => {
        if (controller.signal.aborted || (error instanceof DOMException && error.name === "AbortError")) {
          return
        }
        toast.error("Failed to load bank APIs")
      })
    return () => controller.abort()
  }, [ocrNewCategory])

  const form = useForm<UploadXmlCreateFormValues>({
    resolver: zodResolver(uploadXmlCreateSchema),
    defaultValues: { bankApiId: "please-select", image: "1", fileCount: 0 },
    mode: "onBlur",
  })

  const {
    control,
    handleSubmit,
    setValue,
    formState: { errors, isSubmitting },
  } = form

  const applyFiles = (files: File[]) => {
    const validationError = validateXmlFiles(files, { maxFileSizeMb: null })
    if (validationError) {
      setFileError(validationError)
      setSelectedFiles([])
      setUploadPercent(null)
      setValue("fileCount", 0, { shouldValidate: true })
      return
    }

    setFileError(null)
    setUploadPercent(null)
    setSelectedFiles(files)
    setValue("fileCount", files.length, { shouldValidate: true })
  }

  const onSubmit = handleSubmit(async (values) => {
    if (!selectedFiles.length) {
      toast.error("Upload at least one XML file")
      return
    }

    try {
      setUploadPercent(0)
      await createUploadXml({
        bankApiId: values.bankApiId,
        image: values.image,
        files: selectedFiles,
        onUploadProgress: setUploadPercent,
      })
      setUploadPercent(100)
      toast.success("Upload XML created")
      router.push(listHref)
    } catch (error) {
      setUploadPercent(null)
      toastApiError(error, "Failed to save")
    }
  })

  const handleTabChange = (nextTab: string) => {
    const tab = parseCreateTab(nextTab)
    router.replace(buildCreateTabHref(tab, ocrNewCategory), { scroll: false })
  }

  return (
    <div className="pb-4">
      <FormPageHeader
        backHref={listHref}
        breadcrumb={[
          { label: "XML API" },
          { label: "Upload XML", href: listHref },
          { label: ocrNewCategory ? "Upload OCR XML" : "Create new" },
        ]}
        titleIcon={<Upload className="size-5 text-primary" />}
        title={ocrNewCategory ? "Upload OCR XML" : "Create new upload XML"}
        description={
          ocrNewCategory
            ? "Select an OCR New bank API and upload XML files. This is independent of the legacy OCR category."
            : "Select a bank API and upload transaction or position XML files."
        }
      />

      <Tabs value={activeTab} onValueChange={handleTabChange} className="mt-4 gap-4">
        {ocrNewCategory ? null : (
          <TabsList>
            <TabsTrigger value="standard">Standard upload</TabsTrigger>
            <TabsTrigger value="cub-folder">CUB folder upload</TabsTrigger>
          </TabsList>
        )}

        <TabsContent value="standard">
          <form onSubmit={(e) => void onSubmit(e)}>
            <FormPanel title={ocrNewCategory ? "OCR New upload details" : "Upload details"}>
              <div className="space-y-6">
                <Field data-invalid={!!errors.bankApiId} className="max-w-md gap-1.5">
                  <FieldLabel className="text-sm font-medium">
                    {ocrNewCategory ? "OCR New Bank API" : "Bank API"}{" "}
                    <span className="text-destructive">*</span>
                  </FieldLabel>
                  <Controller
                    name="bankApiId"
                    control={control}
                    render={({ field }) => (
                      <SettingsSelect
                        value={field.value}
                        onValueChange={field.onChange}
                        options={bankApiOptions}
                        placeholder={ocrNewCategory ? "Please select OCR New bank" : "Please select"}
                      />
                    )}
                  />
                  <FieldError
                    errors={
                      errors.bankApiId?.message
                        ? [{ message: String(errors.bankApiId.message) }]
                        : undefined
                    }
                  />
                </Field>

                <Field
                  data-invalid={!!errors.fileCount || !!fileError}
                  className="gap-1.5"
                >
                  <XmlFileDropzone
                    onFilesChosen={applyFiles}
                    onFilesSelected={() => {}}
                    disabled={isSubmitting}
                  />
                  <XmlSelectedFileProgressList
                    files={selectedFiles}
                    percents={
                      uploadPercent == null
                        ? null
                        : percentsForFiles(selectedFiles, uploadPercent)
                    }
                  />
                  <p className="text-xs text-muted-foreground">
                    XML only · max {XML_UPLOAD_MAX_FILES} files
                  </p>
                  <FieldError
                    errors={
                      fileError || errors.fileCount?.message
                        ? [
                            {
                              message: String(fileError ?? errors.fileCount?.message),
                            },
                          ]
                        : undefined
                    }
                  />
                </Field>
              </div>
            </FormPanel>

            <FormSaveBar
              cancelHref={listHref}
              isSaving={isSubmitting}
              saveLabel="Save changes"
              onReset={() => {
                form.reset({ bankApiId: "please-select", image: "1", fileCount: 0 })
                setSelectedFiles([])
                setFileError(null)
                setUploadPercent(null)
              }}
            />
          </form>
        </TabsContent>

        {ocrNewCategory ? null : (
          <TabsContent value="cub-folder">
            <CubFolderUploadPanel />
          </TabsContent>
        )}
      </Tabs>
    </div>
  )
}
