'use client'

import React, { startTransition, useState } from 'react'
import { FormProvider } from 'react-hook-form'
import { Progress, Card, Button, Stepper, Box, Flex, Text, Paper, Container, Portal } from "@pikku/mantine/core"
import { BasicInfo } from "@/components/jobs/form/BasicInfo"
import { TrainingCertificates } from "@/components/jobs/form/TrainingCertificates"
import { License } from "@/components/jobs/form/License"
import { GermanLanguage } from "@/components/jobs/form/GermanLanguage"
import { ProfessionalExperience } from "@/components/jobs/form/ProfessionalExperience"
import { ApplicationCandidateData } from '@heygermany/sdk'
import { useCandidateForm } from '@/hooks/candidate/useCandidateForm'
import { useGetCandidate } from '@/hooks/candidate/useGetCandidate'
import { pikku } from '@/pikku/http'
import { useQueryClient } from '@tanstack/react-query'
import { Done } from '@/components/jobs/form/Done'
import { Invalid } from '@/components/jobs/form/Invalid'
import { useI18n } from '@/context/i18n-provider'
import { ApplicantStatuses } from '@heygermany/sdk'
import { CandidateResult } from '@/components/jobs/CandidateResult'
import { useGetCandidateResults } from '@/hooks/useGetCandidateResult'
import { IconCheck } from '@tabler/icons-react'
import { HelpAffix } from '@/components/jobs/form/HelpAffix'
import { useSearchParams } from '@/framework/navigation'
import { asI18n } from '@pikku/react'

const Form: React.FunctionComponent<{ candidate: ApplicationCandidateData }> = ({ candidate }) => {
  const t = useI18n()

  const steps = [
    { title: t('jobs.apply.steps.basicinfo'), component: BasicInfo },
    { title: t('jobs.apply.steps.educationdocuments' as any), component: TrainingCertificates },
    { title: t('jobs.apply.steps.license'), component: License },
    { title: t('jobs.apply.steps.germanlanguage'), component: GermanLanguage },
    { title: t('jobs.apply.steps.professionalexperience'), component: ProfessionalExperience },
  ]

  const [currentStep, setCurrentStep] = useState(0)

  // Single form instance for the entire application
  const form = useCandidateForm(candidate)

  const progressPercentage = (currentStep / steps.length) * 100

  const queryClient = useQueryClient()

  // Return a Date (not an ISO string): the pikku fetch client serializes Date
  // values over the wire, and the /candidate input type expects Date fields.
  const serializeDate = (value: Date | string | null | undefined) => {
    if (!value) return null
    const date = value instanceof Date ? value : new Date(value)
    return Number.isNaN(date.getTime()) ? null : date
  }

  const handleNext = async () => {
    // Validate current form state before proceeding
    const isValid = await form.trigger()

    if (isValid) {
      // Perform partial update - save current form data
      const { education, licenses, languageCertificates, workExperience, ...formData } = form.getValues()
      const currentData = {
        ...formData,
        candidateId: candidate.candidateId,
        dateOfBirth: serializeDate(formData.dateOfBirth),
      }

      if (currentStep < steps.length - 1) {
        startTransition(() => {
          setCurrentStep((step) => step + 1)
        })
        void pikku().patch('/candidate/:candidateId', currentData).catch((error: unknown) => {
          console.error('Error saving application data:', error)
        })
        return
      }

      try {
        // Final submission
        ;(window as any).fbq?.('track', 'Lead', {
          content_name: 'HeyGermany application',
          content_category: 'Application'
        })
        await pikku().patch('/candidate/:candidateId', {
          ...currentData,
          submittedAt: new Date(),
        })
      } catch (error) {
        console.error('Error saving application data:', error)
      }

      queryClient.invalidateQueries({ queryKey: ['candidate'] })
    }
  }

  const handleBack = () => {
    if (currentStep > 0) {
      setCurrentStep(currentStep - 1)
    }
  }

  const renderStepContent = () => {
    const currentStepConfig = steps[currentStep]
    if (!currentStepConfig) return null
    const StepComponent = currentStepConfig.component
    return <StepComponent candidate={candidate} />
  }

  return (
    <FormProvider {...form}>
      {/* Mobile Progress Bar */}
      <Box px="md" py="xs" w="100%" bg="white" pos="sticky" top="4rem" display={{ base: 'block', lg: 'none' }} style={{ borderBottom: '1px solid var(--mantine-color-gray-3)' }}>
        <Flex align="center" gap="xs" mb="xs">
          <Text size="sm" fw={500}>{t('jobs.apply.stepprogress', { current: currentStep + 1, total: steps.length })}</Text>
        </Flex>
        <Progress value={progressPercentage} h="0.5rem" />
      </Box>

      <Container size='xl' display={{ base: 'none', lg: 'block' }}>
        {/* Desktop Stepper */}
        <Box my="xl">
          <Stepper
            active={currentStep}
            onStepClick={setCurrentStep}
            allowNextStepsSelect={false}

            wrap={false}
          >
            {steps.map((step, index) => <Stepper.Step key={index} label={step.title} completedIcon={<IconCheck color='#eab308' size={18} />} />)}
          </Stepper>
        </Box>
      </Container>

      <Container size='lg' maw='4xl' w='100%'>
        <Flex w="100%" direction="column" align="center" justify="center" p="lg">
          {/* Render the current step once to avoid duplicate form controls across breakpoints */}
          <Paper w="100%" shadow='xl' withBorder p={{ base: 'md', md: 'xl' }}>
            {renderStepContent()}
          </Paper>

          {/* Navigation Buttons */}
          <Flex justify="center" gap="md" mt="lg">
            <Button
              variant="outline"
              onClick={handleBack}
              disabled={form.formState.isSubmitting}
            >
              {t('jobs.apply.buttons.back')}
            </Button>
            <Button
              onClick={handleNext}
              disabled={form.formState.isSubmitting}
            >
              {currentStep === steps.length - 1 ? t('jobs.apply.buttons.submit') : t('jobs.apply.buttons.next')}
            </Button>
          </Flex>
        </Flex>
      </Container>

      <HelpAffix />
    </FormProvider >
  )
}

const Result: React.FunctionComponent<{ candidateId: string }> = ({ candidateId }) => {
  const { data: candidateResults, isLoading: resultLoading, error } = useGetCandidateResults(candidateId)

  if (resultLoading) {
    return null
  }

  if (error) {
    return (
      <Container size="lg" py="xl">
        <Card shadow="sm" p="lg" radius="md" withBorder>
          <Text size="xl" fw={700} mb="md" c="red">
            {asI18n('Error Loading Qualification Results')}
          </Text>
          <Text size="md" c="dimmed">
            {asI18n('We encountered an error while checking your qualifications. Please try again later or contact support if the issue persists.')}
          </Text>
        </Card>
      </Container>
    )
  }

  if (!candidateResults) {
    return null
  }

  return <CandidateResult candidateResults={candidateResults} />
}

const ApplicationPage: React.FunctionComponent = () => {
  const searchParams = useSearchParams()
  const candidateIdFromParams = searchParams.get('candidateId')
  const { data: candidate, isLoading: candidateLoading } = useGetCandidate(candidateIdFromParams || undefined)

  if (candidateLoading || !candidate) {
    return null
  }

  if (candidate.status === ApplicantStatuses.PENDING) {
    return <Done name={candidate.name} />
  }

  if (candidate.status === ApplicantStatuses.INVALID) {
    return <Invalid name={candidate.name} candidateId={candidate.candidateId} />
  }

  if (candidate.status === ApplicantStatuses.COMPLETE) {
    return <Result candidateId={candidate.candidateId} />
  }

  return <div style={{ position: 'relative' }}>
    <Form candidate={candidate} />
  </div>
}

export default ApplicationPage
