"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 { fetchBankApis } from "@/components/xml-apis/bank-api/api/bank-api.api"
import { createUploadXml } 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 {
  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 buildCreateTabHref(tab: UploadXmlCreateTab) {
  return tab === "standard" ? createHref : `${createHref}?tab=${tab}`
}

export function UploadXmlCreateForm() {
  const router = useRouter()
  const searchParams = useSearchParams()
  const activeTab = parseCreateTab(searchParams.get("tab"))

  const [fileNames, setFileNames] = React.useState<string[]>([])
  const [selectedFiles, setSelectedFiles] = React.useState<File[]>([])
  const [fileError, setFileError] = React.useState<string | null>(null)
  const [bankApiOptions, setBankApiOptions] = React.useState<SettingsSelectOption[]>([
    { value: "please-select", label: "Please Select" },
  ])

  React.useEffect(() => {
    void fetchBankApis()
      .then((result) => {
        setBankApiOptions([
          { value: "please-select", label: "Please Select" },
          ...result.items.map((bankApi) => ({
            value: bankApi.id,
            label: bankApi.corporateAccount
              ? `${bankApi.bankName} (${bankApi.corporateAccount})`
              : bankApi.bankName,
          })),
        ])
      })
      .catch(() => {
        toast.error("Failed to load bank APIs")
      })
  }, [])

  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)
      setFileNames([])
      setSelectedFiles([])
      setValue("fileCount", 0, { shouldValidate: true })
      return
    }

    setFileError(null)
    setSelectedFiles(files)
    setFileNames(files.map((file) => file.name))
    setValue("fileCount", files.length, { shouldValidate: true })
  }

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

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

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

  return (
    <div className="pb-4">
      <FormPageHeader
        backHref={listHref}
        breadcrumb={[
          { label: "XML API" },
          { label: "Upload XML", href: listHref },
          { label: "Create new" },
        ]}
        titleIcon={<Upload className="size-5 text-primary" />}
        title="Create new upload XML"
        description="Select a bank API and upload transaction or position XML files."
      />

      <Tabs value={activeTab} onValueChange={handleTabChange} className="mt-4 gap-4">
        <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="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">
                    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="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={() => {}}
                  />
                  {fileNames.length > 0 ? (
                    <ul className="text-sm text-muted-foreground">
                      {fileNames.map((name) => (
                        <li key={name}>{name}</li>
                      ))}
                    </ul>
                  ) : null}
                  <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 })
                setFileNames([])
                setSelectedFiles([])
                setFileError(null)
              }}
            />
          </form>
        </TabsContent>

        <TabsContent value="cub-folder">
          <CubFolderUploadPanel />
        </TabsContent>
      </Tabs>
    </div>
  )
}
