'use client'

import { useState, useEffect, useCallback } from 'react'
import { Button } from '@/components/ui/button'
import { Label } from '@/components/ui/label'
import { Checkbox } from '@/components/ui/checkbox'
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog'
import { Download, Loader2 } from 'lucide-react'
import { csvCell } from '@/lib/csv'

/**
 * Converts a camelCase or snake_case column name to Title Case.
 * e.g. "projectTitle" -> "Project Title", "ai_meetsCriteria" -> "Ai Meets Criteria"
 */
function formatColumnName(col: string): string {
  // Replace underscores with spaces
  let result = col.replace(/_/g, ' ')
  // Insert space before uppercase letters (camelCase -> spaced)
  result = result.replace(/([a-z])([A-Z])/g, '$1 $2')
  // Capitalize first letter of each word
  return result
    .split(' ')
    .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
    .join(' ')
}

type ExportData = {
  data: Record<string, unknown>[]
  columns: string[]
}

type CsvExportDialogProps = {
  open: boolean
  onOpenChange: (open: boolean) => void
  exportData: ExportData | undefined
  isLoading: boolean
  filename: string
  onRequestData: () => Promise<ExportData | undefined>
}

export function CsvExportDialog({
  open,
  onOpenChange,
  exportData,
  isLoading,
  filename,
  onRequestData,
}: CsvExportDialogProps) {
  const [selectedColumns, setSelectedColumns] = useState<Set<string>>(new Set())
  const [dataLoaded, setDataLoaded] = useState(false)

  // When dialog opens, fetch data if not already loaded
  useEffect(() => {
    if (open && !dataLoaded) {
      onRequestData().then((result) => {
        if (result?.columns) {
          setSelectedColumns(new Set(result.columns))
        }
        setDataLoaded(true)
      })
    }
  }, [open, dataLoaded, onRequestData])

  // Sync selected columns when export data changes
  useEffect(() => {
    if (exportData?.columns) {
      setSelectedColumns(new Set(exportData.columns))
    }
  }, [exportData])

  // Reset state when dialog closes
  useEffect(() => {
    if (!open) {
      setDataLoaded(false)
    }
  }, [open])

  const toggleColumn = (col: string, checked: boolean) => {
    const next = new Set(selectedColumns)
    if (checked) {
      next.add(col)
    } else {
      next.delete(col)
    }
    setSelectedColumns(next)
  }

  const toggleAll = () => {
    if (!exportData) return
    if (selectedColumns.size === exportData.columns.length) {
      setSelectedColumns(new Set())
    } else {
      setSelectedColumns(new Set(exportData.columns))
    }
  }

  const handleDownload = () => {
    if (!exportData) return

    const columnsArray = exportData.columns.filter((col) => selectedColumns.has(col))

    // Build CSV header with formatted names. Use csvCell so formula-character
    // headers (unlikely in practice) are still defanged.
    const csvHeader = columnsArray.map((col) => csvCell(formatColumnName(col)))

    const csvContent = [
      csvHeader.join(','),
      ...exportData.data.map((row) =>
        columnsArray.map((col) => csvCell(row[col])).join(',')
      ),
    ].join('\n')

    const blob = new Blob(['\ufeff' + csvContent], { type: 'text/csv;charset=utf-8;' })
    const url = URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = `${filename}-${new Date().toISOString().split('T')[0]}.csv`
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    // Delay revoking to ensure download starts before URL is invalidated
    setTimeout(() => URL.revokeObjectURL(url), 1000)
    onOpenChange(false)
  }

  const allSelected = exportData ? selectedColumns.size === exportData.columns.length : false
  const noneSelected = selectedColumns.size === 0

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-md">
        <DialogHeader>
          <DialogTitle>Export CSV</DialogTitle>
          <DialogDescription>
            Select which columns to include in the export
          </DialogDescription>
        </DialogHeader>

        {isLoading ? (
          <div className="flex items-center justify-center py-8">
            <Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
            <span className="ml-2 text-sm text-muted-foreground">Loading data...</span>
          </div>
        ) : exportData ? (
          <div className="space-y-3">
            <div className="flex items-center justify-between">
              <Label className="text-sm font-medium">
                {selectedColumns.size} of {exportData.columns.length} columns selected
              </Label>
              <Button variant="ghost" size="sm" onClick={toggleAll}>
                {allSelected ? 'Deselect all' : 'Select all'}
              </Button>
            </div>
            <div className="space-y-1.5 max-h-60 overflow-y-auto rounded-lg border p-3">
              {exportData.columns.map((col) => (
                <div key={col} className="flex items-center gap-2">
                  <Checkbox
                    id={`col-${col}`}
                    checked={selectedColumns.has(col)}
                    onCheckedChange={(checked) => toggleColumn(col, !!checked)}
                  />
                  <Label htmlFor={`col-${col}`} className="text-sm cursor-pointer font-normal">
                    {formatColumnName(col)}
                  </Label>
                </div>
              ))}
            </div>
            <p className="text-xs text-muted-foreground">
              {exportData.data.length} row{exportData.data.length !== 1 ? 's' : ''} will be exported
            </p>
          </div>
        ) : (
          <p className="text-sm text-muted-foreground py-4 text-center">
            No data available for export.
          </p>
        )}

        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)}>
            Cancel
          </Button>
          <Button
            onClick={handleDownload}
            disabled={isLoading || !exportData || noneSelected}
          >
            <Download className="mr-2 h-4 w-4" />
            Download CSV
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}
