"use client"

import { cn } from "@mdxui/primitives/lib/utils"
import { Button } from "@mdxui/primitives/button"
import { Input } from "@mdxui/primitives/input"
import { Textarea } from "@mdxui/primitives/textarea"
import { Label } from "@mdxui/primitives/label"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@mdxui/primitives/select"
import { useState, useEffect } from "react"
import type { ContactData, ContactUser } from "./types"

const DEFAULT_TOPICS = ['Sales', 'Support', 'Partnership', 'Other']
const DEFAULT_COMPANY_SIZE_OPTIONS = ['1-10', '11-50', '51-200', '201-500', '500+']

interface ContactContentProps {
  showName?: boolean
  showEmail?: boolean
  showCompanyName?: boolean
  showCompanySize?: boolean
  showTopic?: boolean
  showMessage?: boolean
  showAdditionalInfo?: boolean
  requireName?: boolean
  requireEmail?: boolean
  requireCompanyName?: boolean
  requireCompanySize?: boolean
  requireTopic?: boolean
  requireMessage?: boolean
  requireAdditionalInfo?: boolean
  topics?: string[]
  companySizeOptions?: string[]
  rows?: string[][]
  user?: ContactUser
  context?: Record<string, unknown>
  captureMetadata?: boolean
  sessionId?: string
  correlationId?: string
  appVersion?: string
  environment?: string
  onSubmit?: (data: ContactData) => Promise<void> | void
  apiEndpoint?: string
  submitLabel?: string
  onSuccess: () => void
  onError: (error: string) => void
}

interface MetadataOptions {
  sessionId?: string
  correlationId?: string
  appVersion?: string
  environment?: string
}

// Track page load time for timeOnPage calculation
const pageLoadTime = typeof window !== 'undefined' ? Date.now() : 0

function captureCurrentMetadata(options: MetadataOptions = {}) {
  const timeOnPage = Date.now() - pageLoadTime

  return {
    // Page context
    url: window.location.href,
    timestamp: new Date().toISOString(),
    viewport: { width: window.innerWidth, height: window.innerHeight },
    userAgent: navigator.userAgent,

    // Navigation context
    referrer: document.referrer || undefined,
    pageTitle: document.title || undefined,
    timeOnPage,

    // Device details
    locale: navigator.language,
    timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
    screenResolution: { width: screen.width, height: screen.height },

    // Session tracking (from props)
    sessionId: options.sessionId,
    correlationId: options.correlationId,

    // App context (from props)
    appVersion: options.appVersion,
    environment: options.environment,
  }
}

function isValidEmail(email: string): boolean {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)
}

type FieldName = 'name' | 'email' | 'companyName' | 'companySize' | 'topic' | 'message' | 'additionalInfo'

export function ContactContent({
  showName = true,
  showEmail = true,
  showCompanyName = false,
  showCompanySize = false,
  showTopic = true,
  showMessage = true,
  showAdditionalInfo = false,
  requireName = true,
  requireEmail = true,
  requireCompanyName = false,
  requireCompanySize = false,
  requireTopic = false,
  requireMessage = true,
  requireAdditionalInfo = false,
  topics = DEFAULT_TOPICS,
  companySizeOptions = DEFAULT_COMPANY_SIZE_OPTIONS,
  rows,
  user,
  context,
  captureMetadata = true,
  sessionId,
  correlationId,
  appVersion,
  environment,
  onSubmit,
  apiEndpoint,
  submitLabel = "Send",
  onSuccess,
  onError,
}: ContactContentProps) {
  const [name, setName] = useState(user?.name || "")
  const [email, setEmail] = useState(user?.email || "")
  const [companyName, setCompanyName] = useState("")
  const [companySize, setCompanySize] = useState("")
  const [topic, setTopic] = useState("")
  const [message, setMessage] = useState("")
  const [additionalInfo, setAdditionalInfo] = useState("")
  const [isSubmitting, setIsSubmitting] = useState(false)
  const [errors, setErrors] = useState<Record<string, string>>({})

  // Update fields when user prop changes
  useEffect(() => {
    if (user?.name && !name) setName(user.name)
    if (user?.email && !email) setEmail(user.email)
  }, [user])

  const validate = (): boolean => {
    const newErrors: Record<string, string> = {}

    if (showName && requireName && name.trim().length < 2) {
      newErrors.name = "Name must be at least 2 characters"
    }
    if (showEmail && requireEmail && !isValidEmail(email)) {
      newErrors.email = "Please enter a valid email"
    }
    // Validate email format if provided, even when not required
    if (showEmail && !requireEmail && email.trim() && !isValidEmail(email)) {
      newErrors.email = "Please enter a valid email"
    }
    if (showCompanyName && requireCompanyName && companyName.trim().length < 2) {
      newErrors.companyName = "Company name must be at least 2 characters"
    }
    if (showCompanySize && requireCompanySize && !companySize) {
      newErrors.companySize = "Please select a company size"
    }
    if (showTopic && requireTopic && !topic) {
      newErrors.topic = "Please select a topic"
    }
    if (showMessage && requireMessage && message.trim().length < 10) {
      newErrors.message = "Message must be at least 10 characters"
    }
    if (showAdditionalInfo && requireAdditionalInfo && additionalInfo.trim().length < 10) {
      newErrors.additionalInfo = "Additional info must be at least 10 characters"
    }

    setErrors(newErrors)
    return Object.keys(newErrors).length === 0
  }

  const handleSubmit = async () => {
    if (!validate()) return

    setIsSubmitting(true)

    const data: ContactData = {
      name: showName ? name.trim() : undefined,
      email: showEmail ? email.trim() : undefined,
      companyName: showCompanyName ? companyName.trim() : undefined,
      companySize: showCompanySize ? companySize : undefined,
      topic: showTopic ? topic : undefined,
      message: message.trim(),
      additionalInfo: showAdditionalInfo ? additionalInfo.trim() : undefined,
      user,
      context,
      metadata: captureMetadata ? captureCurrentMetadata({ sessionId, correlationId, appVersion, environment }) : undefined,
    }

    try {
      if (onSubmit) {
        await onSubmit(data)
      } else if (apiEndpoint) {
        const response = await fetch(apiEndpoint, {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(data),
        })
        if (!response.ok) {
          throw new Error(`Failed to submit: ${response.statusText}`)
        }
      }
      onSuccess()
    } catch (err) {
      onError(err instanceof Error ? err.message : "Failed to submit")
    } finally {
      setIsSubmitting(false)
    }
  }

  const isValid =
    (!showName || !requireName || name.trim().length >= 2) &&
    (!showEmail || !requireEmail || isValidEmail(email)) &&
    (!showEmail || !email.trim() || isValidEmail(email)) && // Validate format if provided
    (!showCompanyName || !requireCompanyName || companyName.trim().length >= 2) &&
    (!showCompanySize || !requireCompanySize || companySize) &&
    (!showTopic || !requireTopic || topic) &&
    (!showMessage || !requireMessage || message.trim().length >= 10) &&
    (!showAdditionalInfo || !requireAdditionalInfo || additionalInfo.trim().length >= 10)

  // Field components
  const nameField = showName && (
    <div className="flex flex-col gap-1">
      <Label htmlFor="contact-name" className="text-sm text-foreground">
        Name
      </Label>
      <Input
        id="contact-name"
        value={name}
        onChange={(e) => setName(e.target.value)}
        placeholder="Your name"
        className={cn(errors.name && "border-destructive")}
      />
      {errors.name && (
        <p className="text-xs text-destructive">{errors.name}</p>
      )}
    </div>
  )

  const emailField = showEmail && (
    <div className="flex flex-col gap-1">
      <Label htmlFor="contact-email" className="text-sm text-foreground">
        Email
      </Label>
      <Input
        id="contact-email"
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        placeholder="your@email.com"
        className={cn(errors.email && "border-destructive")}
      />
      {errors.email && (
        <p className="text-xs text-destructive">{errors.email}</p>
      )}
    </div>
  )

  const companyNameField = showCompanyName && (
    <div className="flex flex-col gap-1">
      <Label htmlFor="contact-company-name" className="text-sm text-foreground">
        Company Name
      </Label>
      <Input
        id="contact-company-name"
        value={companyName}
        onChange={(e) => setCompanyName(e.target.value)}
        placeholder="Your company"
        className={cn(errors.companyName && "border-destructive")}
      />
      {errors.companyName && (
        <p className="text-xs text-destructive">{errors.companyName}</p>
      )}
    </div>
  )

  const companySizeField = showCompanySize && (
    <div className="flex flex-col gap-1">
      <Label htmlFor="contact-company-size" className="text-sm text-foreground">
        Company Size
      </Label>
      <Select value={companySize} onValueChange={setCompanySize}>
        <SelectTrigger className={cn("w-full", errors.companySize && "border-destructive")}>
          <SelectValue placeholder="Select company size" />
        </SelectTrigger>
        <SelectContent side="top">
          {companySizeOptions.map((size) => (
            <SelectItem key={size} value={size}>
              {size}
            </SelectItem>
          ))}
        </SelectContent>
      </Select>
      {errors.companySize && (
        <p className="text-xs text-destructive">{errors.companySize}</p>
      )}
    </div>
  )

  const topicField = showTopic && (
    <div className="flex flex-col gap-1">
      <Label htmlFor="contact-topic" className="text-sm text-foreground">
        Topic
      </Label>
      <Select value={topic} onValueChange={setTopic}>
        <SelectTrigger className={cn("w-full", errors.topic && "border-destructive")}>
          <SelectValue placeholder="Select a topic" />
        </SelectTrigger>
        <SelectContent side="top">
          {topics.map((t) => (
            <SelectItem key={t} value={t}>
              {t}
            </SelectItem>
          ))}
        </SelectContent>
      </Select>
      {errors.topic && (
        <p className="text-xs text-destructive">{errors.topic}</p>
      )}
    </div>
  )

  const messageField = showMessage && (
    <div className="flex flex-col gap-1">
      <Label htmlFor="contact-message" className="text-sm text-foreground">
        Message
      </Label>
      <Textarea
        id="contact-message"
        value={message}
        onChange={(e) => setMessage(e.target.value)}
        placeholder="How can we help?"
        rows={4}
        className={cn("resize-y min-h-24 max-h-48", errors.message && "border-destructive")}
      />
      {errors.message && (
        <p className="text-xs text-destructive">{errors.message}</p>
      )}
    </div>
  )

  const additionalInfoField = showAdditionalInfo && (
    <div className="flex flex-col gap-1">
      <Label htmlFor="contact-additional-info" className="text-sm text-foreground">
        Additional Info
      </Label>
      <Textarea
        id="contact-additional-info"
        value={additionalInfo}
        onChange={(e) => setAdditionalInfo(e.target.value)}
        placeholder="Any additional information..."
        rows={3}
        className={cn("resize-y min-h-20 max-h-40", errors.additionalInfo && "border-destructive")}
      />
      {errors.additionalInfo && (
        <p className="text-xs text-destructive">{errors.additionalInfo}</p>
      )}
    </div>
  )

  const submitButton = (
    <Button
      onClick={handleSubmit}
      disabled={!isValid || isSubmitting}
      className="w-full"
    >
      {isSubmitting ? "Sending..." : submitLabel}
    </Button>
  )

  // Map field names to components
  const fieldMap: Record<FieldName, React.ReactNode> = {
    name: nameField,
    email: emailField,
    companyName: companyNameField,
    companySize: companySizeField,
    topic: topicField,
    message: messageField,
    additionalInfo: additionalInfoField,
  }

  // Map field names to visibility
  const visibilityMap: Record<FieldName, boolean> = {
    name: showName,
    email: showEmail,
    companyName: showCompanyName,
    companySize: showCompanySize,
    topic: showTopic,
    message: showMessage,
    additionalInfo: showAdditionalInfo,
  }

  // Render with rows layout
  if (rows && rows.length > 0) {
    const usedFields = new Set<string>()

    // Track which fields are in rows
    rows.forEach(row => {
      row.forEach(fieldName => usedFields.add(fieldName))
    })

    // All possible field names in default order
    const allFieldNames: FieldName[] = ['name', 'email', 'companyName', 'companySize', 'topic', 'message', 'additionalInfo']

    // Fields not in any row that should still be shown
    const remainingFields = allFieldNames.filter(
      fieldName => visibilityMap[fieldName] && !usedFields.has(fieldName)
    )

    return (
      <div className="flex flex-col gap-4">
        {rows.map((row, rowIndex) => {
          // Filter to only visible fields in this row
          const visibleFieldsInRow = row.filter(
            fieldName => visibilityMap[fieldName as FieldName]
          )

          if (visibleFieldsInRow.length === 0) return null

          const gridCols = visibleFieldsInRow.length === 1
            ? 'grid-cols-1'
            : visibleFieldsInRow.length === 2
              ? 'grid-cols-2'
              : visibleFieldsInRow.length === 3
                ? 'grid-cols-3'
                : 'grid-cols-4'

          return (
            <div key={rowIndex} className={cn("grid gap-4", gridCols)}>
              {visibleFieldsInRow.map(fieldName => (
                <div key={fieldName}>
                  {fieldMap[fieldName as FieldName]}
                </div>
              ))}
            </div>
          )
        })}
        {/* Render remaining fields not in any row */}
        {remainingFields.map(fieldName => (
          <div key={fieldName}>
            {fieldMap[fieldName]}
          </div>
        ))}
        {submitButton}
      </div>
    )
  }

  // Default stacked layout
  return (
    <div className="flex flex-col gap-4">
      {nameField}
      {emailField}
      {companyNameField}
      {companySizeField}
      {topicField}
      {messageField}
      {additionalInfoField}
      {submitButton}
    </div>
  )
}
