'use client'

import { useState } from 'react'
import { trpc } from '@/lib/trpc/client'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from '@/components/ui/card'
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select'
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
import { Badge } from '@/components/ui/badge'
import { Checkbox } from '@/components/ui/checkbox'
import { toast } from 'sonner'
import {
  CheckCircle,
  AlertCircle,
  Loader2,
  ArrowRight,
  ArrowLeft,
  Database,
} from 'lucide-react'

interface NotionImportFormProps {
  programId: string
  stageName?: string
  onSuccess?: () => void
}

type Step = 'connect' | 'map' | 'preview' | 'import' | 'complete'

export function NotionImportForm({
  programId,
  stageName,
  onSuccess,
}: NotionImportFormProps) {
  const [step, setStep] = useState<Step>('connect')
  const [apiKey, setApiKey] = useState('')
  const [databaseId, setDatabaseId] = useState('')
  const [isConnecting, setIsConnecting] = useState(false)
  const [connectionError, setConnectionError] = useState<string | null>(null)

  // Mapping state
  const [mappings, setMappings] = useState({
    title: '',
    teamName: '',
    description: '',
    tags: '',
  })
  const [includeUnmapped, setIncludeUnmapped] = useState(true)

  // Results
  const [importResults, setImportResults] = useState<{
    imported: number
    skipped: number
    errors: Array<{ recordId: string; error: string }>
  } | null>(null)

  const testConnection = trpc.notionImport.testConnection.useMutation()
  const { data: schema, refetch: refetchSchema } =
    trpc.notionImport.getDatabaseSchema.useQuery(
      { apiKey, databaseId },
      { enabled: false }
    )
  const { data: preview, refetch: refetchPreview } =
    trpc.notionImport.previewData.useQuery(
      { apiKey, databaseId, limit: 5 },
      { enabled: false }
    )
  const importMutation = trpc.notionImport.importProjects.useMutation()

  const handleConnect = async () => {
    if (!apiKey || !databaseId) {
      toast.error('Please enter both API key and database ID')
      return
    }

    setIsConnecting(true)
    setConnectionError(null)

    try {
      const result = await testConnection.mutateAsync({ apiKey })
      if (!result.success) {
        setConnectionError(result.error || 'Connection failed')
        return
      }

      // Fetch schema
      await refetchSchema()
      setStep('map')
    } catch (error) {
      setConnectionError(
        error instanceof Error ? error.message : 'Connection failed'
      )
    } finally {
      setIsConnecting(false)
    }
  }

  const handlePreview = async () => {
    if (!mappings.title) {
      toast.error('Please map the Title field')
      return
    }

    await refetchPreview()
    setStep('preview')
  }

  const handleImport = async () => {
    setStep('import')

    try {
      const result = await importMutation.mutateAsync({
        apiKey,
        databaseId,
        programId,
        mappings: {
          title: mappings.title,
          teamName: mappings.teamName || undefined,
          description: mappings.description || undefined,
          tags: mappings.tags || undefined,
        },
        includeUnmappedInMetadata: includeUnmapped,
      })

      setImportResults(result)
      setStep('complete')

      if (result.imported > 0) {
        toast.success(`Imported ${result.imported} projects`)
        onSuccess?.()
      }
    } catch (error) {
      toast.error(
        error instanceof Error ? error.message : 'Import failed'
      )
      setStep('preview')
    }
  }

  const properties = schema?.properties || []

  return (
    <div className="space-y-6">
      {/* Progress indicator */}
      <div className="flex items-center gap-2">
        {['connect', 'map', 'preview', 'import', 'complete'].map((s, i) => (
          <div key={s} className="flex items-center">
            {i > 0 && <div className="w-8 h-0.5 bg-muted mx-1" />}
            <div
              className={`w-8 h-8 rounded-full flex items-center justify-center text-sm font-medium ${
                step === s
                  ? 'bg-primary text-primary-foreground'
                  : ['connect', 'map', 'preview', 'import', 'complete'].indexOf(step) > i
                  ? 'bg-primary/20 text-primary'
                  : 'bg-muted text-muted-foreground'
              }`}
            >
              {i + 1}
            </div>
          </div>
        ))}
      </div>

      {/* Step 1: Connect */}
      {step === 'connect' && (
        <Card>
          <CardHeader>
            <CardTitle className="flex items-center gap-2">
              <Database className="h-5 w-5" />
              Connect to Notion
            </CardTitle>
            <CardDescription>
              Enter your Notion API key and database ID to connect
            </CardDescription>
          </CardHeader>
          <CardContent className="space-y-4">
            <div className="space-y-2">
              <Label htmlFor="apiKey">Notion API Key</Label>
              <Input
                id="apiKey"
                type="password"
                placeholder="secret_..."
                value={apiKey}
                onChange={(e) => setApiKey(e.target.value)}
              />
              <p className="text-xs text-muted-foreground">
                Create an integration at{' '}
                <a
                  href="https://www.notion.so/my-integrations"
                  target="_blank"
                  rel="noopener noreferrer"
                  className="text-primary hover:underline"
                >
                  notion.so/my-integrations
                </a>
              </p>
            </div>

            <div className="space-y-2">
              <Label htmlFor="databaseId">Database ID</Label>
              <Input
                id="databaseId"
                placeholder="abc123..."
                value={databaseId}
                onChange={(e) => setDatabaseId(e.target.value)}
              />
              <p className="text-xs text-muted-foreground">
                The ID from your Notion database URL
              </p>
            </div>

            {connectionError && (
              <Alert variant="destructive">
                <AlertCircle className="h-4 w-4" />
                <AlertTitle>Connection Failed</AlertTitle>
                <AlertDescription>{connectionError}</AlertDescription>
              </Alert>
            )}

            <Button
              onClick={handleConnect}
              disabled={isConnecting || !apiKey || !databaseId}
            >
              {isConnecting && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
              Connect
              <ArrowRight className="ml-2 h-4 w-4" />
            </Button>
          </CardContent>
        </Card>
      )}

      {/* Step 2: Map columns */}
      {step === 'map' && (
        <Card>
          <CardHeader>
            <CardTitle>Map Columns</CardTitle>
            <CardDescription>
              Map Notion properties to project fields. Database: {schema?.title}
            </CardDescription>
          </CardHeader>
          <CardContent className="space-y-4">
            <div className="grid gap-4 md:grid-cols-2">
              <div className="space-y-2">
                <Label>
                  Title <span className="text-destructive">*</span>
                </Label>
                <Select
                  value={mappings.title}
                  onValueChange={(v) => setMappings((m) => ({ ...m, title: v }))}
                >
                  <SelectTrigger>
                    <SelectValue placeholder="Select property" />
                  </SelectTrigger>
                  <SelectContent>
                    {properties.map((p) => (
                      <SelectItem key={p.id} value={p.name}>
                        {p.name}{' '}
                        <span className="text-muted-foreground">({p.type})</span>
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>

              <div className="space-y-2">
                <Label>Team Name</Label>
                <Select
                  value={mappings.teamName}
                  onValueChange={(v) =>
                    setMappings((m) => ({ ...m, teamName: v }))
                  }
                >
                  <SelectTrigger>
                    <SelectValue placeholder="Select property (optional)" />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="">None</SelectItem>
                    {properties.map((p) => (
                      <SelectItem key={p.id} value={p.name}>
                        {p.name}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>

              <div className="space-y-2">
                <Label>Description</Label>
                <Select
                  value={mappings.description}
                  onValueChange={(v) =>
                    setMappings((m) => ({ ...m, description: v }))
                  }
                >
                  <SelectTrigger>
                    <SelectValue placeholder="Select property (optional)" />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="">None</SelectItem>
                    {properties.map((p) => (
                      <SelectItem key={p.id} value={p.name}>
                        {p.name}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>

              <div className="space-y-2">
                <Label>Tags</Label>
                <Select
                  value={mappings.tags}
                  onValueChange={(v) => setMappings((m) => ({ ...m, tags: v }))}
                >
                  <SelectTrigger>
                    <SelectValue placeholder="Select property (optional)" />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="">None</SelectItem>
                    {properties
                      .filter((p) => p.type === 'multi_select' || p.type === 'select')
                      .map((p) => (
                        <SelectItem key={p.id} value={p.name}>
                          {p.name}
                        </SelectItem>
                      ))}
                  </SelectContent>
                </Select>
              </div>
            </div>

            <div className="flex items-center space-x-2">
              <Checkbox
                id="includeUnmapped"
                checked={includeUnmapped}
                onCheckedChange={(c) => setIncludeUnmapped(!!c)}
              />
              <Label htmlFor="includeUnmapped" className="font-normal">
                Store unmapped columns in metadata
              </Label>
            </div>

            <div className="flex gap-2">
              <Button variant="outline" onClick={() => setStep('connect')}>
                <ArrowLeft className="mr-2 h-4 w-4" />
                Back
              </Button>
              <Button onClick={handlePreview} disabled={!mappings.title}>
                Preview
                <ArrowRight className="ml-2 h-4 w-4" />
              </Button>
            </div>
          </CardContent>
        </Card>
      )}

      {/* Step 3: Preview */}
      {step === 'preview' && (
        <Card>
          <CardHeader>
            <CardTitle>Preview Import</CardTitle>
            <CardDescription>
              Review the first {preview?.count || 0} records before importing
            </CardDescription>
          </CardHeader>
          <CardContent className="space-y-4">
            <div className="border rounded-lg overflow-hidden">
              <table className="w-full text-sm">
                <thead className="bg-muted">
                  <tr>
                    <th className="px-4 py-2 text-left font-medium">Title</th>
                    <th className="px-4 py-2 text-left font-medium">Team</th>
                    <th className="px-4 py-2 text-left font-medium">Tags</th>
                  </tr>
                </thead>
                <tbody>
                  {preview?.records.map((record, i) => (
                    <tr key={i} className="border-t">
                      <td className="px-4 py-2">
                        {String(record.properties[mappings.title] || '-')}
                      </td>
                      <td className="px-4 py-2">
                        {mappings.teamName
                          ? String(record.properties[mappings.teamName] || '-')
                          : '-'}
                      </td>
                      <td className="px-4 py-2">
                        {mappings.tags && record.properties[mappings.tags]
                          ? (
                              record.properties[mappings.tags] as string[]
                            ).map((tag, j) => (
                              <Badge key={j} variant="secondary" className="mr-1">
                                {tag}
                              </Badge>
                            ))
                          : '-'}
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>

            <Alert>
              <AlertCircle className="h-4 w-4" />
              <AlertTitle>Ready to import</AlertTitle>
              <AlertDescription>
                This will import all records from the Notion database into{' '}
                <strong>{stageName}</strong>.
              </AlertDescription>
            </Alert>

            <div className="flex gap-2">
              <Button variant="outline" onClick={() => setStep('map')}>
                <ArrowLeft className="mr-2 h-4 w-4" />
                Back
              </Button>
              <Button onClick={handleImport}>
                Import All Records
                <ArrowRight className="ml-2 h-4 w-4" />
              </Button>
            </div>
          </CardContent>
        </Card>
      )}

      {/* Step 4: Importing */}
      {step === 'import' && (
        <Card>
          <CardContent className="flex flex-col items-center justify-center py-12">
            <Loader2 className="h-12 w-12 animate-spin text-primary mb-4" />
            <p className="text-lg font-medium">Importing projects...</p>
            <p className="text-sm text-muted-foreground">
              Please wait while we import your data from Notion
            </p>
          </CardContent>
        </Card>
      )}

      {/* Step 5: Complete */}
      {step === 'complete' && importResults && (
        <Card>
          <CardContent className="flex flex-col items-center justify-center py-12">
            <CheckCircle className="h-12 w-12 text-green-500 mb-4" />
            <p className="text-lg font-medium">Import Complete</p>
            <div className="mt-4 text-center">
              <p className="text-2xl font-bold text-green-600">
                {importResults.imported}
              </p>
              <p className="text-sm text-muted-foreground">projects imported</p>
            </div>
            {importResults.skipped > 0 && (
              <p className="mt-2 text-sm text-muted-foreground">
                {importResults.skipped} records skipped
              </p>
            )}
            {importResults.errors.length > 0 && (
              <div className="mt-4 w-full max-w-md">
                <p className="text-sm font-medium text-destructive mb-2">
                  Errors ({importResults.errors.length}):
                </p>
                <div className="max-h-32 overflow-y-auto text-xs text-muted-foreground">
                  {importResults.errors.slice(0, 5).map((e, i) => (
                    <p key={i}>
                      {e.recordId}: {e.error}
                    </p>
                  ))}
                </div>
              </div>
            )}
          </CardContent>
        </Card>
      )}
    </div>
  )
}
