'use client';

import { useState, useEffect } from 'react';
import {
  Ticket,
  Plus,
  Copy,
  MoreHorizontal,
  CheckCircle2,
  XCircle,
  Clock,
  Upload,
  FileSpreadsheet,
} from 'lucide-react';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import {
  apiListInvitations,
  apiCreateInvitation,
  apiUpdateInvitation,
  apiDeleteInvitation,
  apiBulkCreateInvitations,
  type ApiInvitation,
  type BulkInviteResult,
} from '@/lib/api';

const statusConfig: Record<string, { label: string; color: string; icon: typeof CheckCircle2 }> = {
  active: { label: 'Active', color: 'bg-emerald-50 text-emerald-700', icon: CheckCircle2 },
  expired: { label: 'Expired', color: 'bg-amber-50 text-amber-700', icon: Clock },
  disabled: { label: 'Disabled', color: 'bg-red-50 text-red-700', icon: XCircle },
};

function formatDate(iso: string) {
  return new Date(iso).toLocaleDateString('en-US', {
    month: 'short',
    day: 'numeric',
    year: 'numeric',
  });
}

export default function InvitationsPage() {
  const [codes, setCodes] = useState<ApiInvitation[]>([]);
  const [total, setTotal] = useState(0);
  const [loading, setLoading] = useState(true);
  const [showCreate, setShowCreate] = useState(false);
  const [copied, setCopied] = useState<string | null>(null);

  // Create form state
  const [newCode, setNewCode] = useState('');
  const [newDescription, setNewDescription] = useState('');
  const [newPlan, setNewPlan] = useState('pro');
  const [newTrialDays, setNewTrialDays] = useState('0');
  const [newBonusTokens, setNewBonusTokens] = useState('0');
  const [newMaxUses, setNewMaxUses] = useState('100');
  const [creating, setCreating] = useState(false);

  // Bulk upload state
  const [showBulk, setShowBulk] = useState(false);
  const [csvRows, setCsvRows] = useState<Record<string, string>[]>([]);
  const [bulkUploading, setBulkUploading] = useState(false);
  const [bulkResult, setBulkResult] = useState<BulkInviteResult | null>(null);

  async function loadCodes() {
    setLoading(true);
    const { data } = await apiListInvitations();
    if (data) {
      setCodes(data.codes);
      setTotal(data.total);
    }
    setLoading(false);
  }

  useEffect(() => {
    void loadCodes();
  }, []);

  async function handleCreate() {
    setCreating(true);
    const { data, error } = await apiCreateInvitation({
      code: newCode || undefined,
      description: newDescription,
      grantPlan: newPlan,
      grantTrialDays: parseInt(newTrialDays) || 0,
      bonusTokens: parseInt(newBonusTokens) || 0,
      maxUses: parseInt(newMaxUses) || 100,
    });
    setCreating(false);
    if (data) {
      setShowCreate(false);
      setNewCode('');
      setNewDescription('');
      setNewPlan('pro');
      setNewTrialDays('0');
      setNewBonusTokens('0');
      setNewMaxUses('100');
      loadCodes();
    } else {
      alert(error || 'Failed to create invitation');
    }
  }

  async function handleToggle(inv: ApiInvitation) {
    const newStatus = inv.status === 'active' ? 'disabled' : 'active';
    await apiUpdateInvitation(inv.id, { status: newStatus });
    loadCodes();
  }

  async function handleDelete(id: string) {
    if (!confirm('Delete this invitation code?')) return;
    await apiDeleteInvitation(id);
    loadCodes();
  }

  function parseCsvLine(line: string): string[] {
    const fields: string[] = [];
    let current = '';
    let inQuotes = false;
    for (let i = 0; i < line.length; i++) {
      const ch = line[i];
      if (inQuotes) {
        if (ch === '"' && line[i + 1] === '"') {
          current += '"';
          i++; // skip escaped quote
        } else if (ch === '"') {
          inQuotes = false;
        } else {
          current += ch;
        }
      } else {
        if (ch === '"') {
          inQuotes = true;
        } else if (ch === ',') {
          fields.push(current.trim());
          current = '';
        } else {
          current += ch;
        }
      }
    }
    fields.push(current.trim());
    return fields;
  }

  function handleCsvFile(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0];
    if (!file) return;
    const reader = new FileReader();
    reader.onload = ev => {
      const text = ev.target?.result as string;
      const lines = text.split(/\r?\n/).filter(l => l.trim());
      if (lines.length < 2) return;
      const headers = parseCsvLine(lines[0]).map(h => h.toLowerCase());
      const rows = lines.slice(1).map(line => {
        const vals = parseCsvLine(line);
        const row: Record<string, string> = {};
        headers.forEach((h, i) => (row[h] = vals[i] || ''));
        return row;
      });
      setCsvRows(rows);
      setBulkResult(null);
    };
    reader.readAsText(file);
  }

  async function handleBulkUpload() {
    if (csvRows.length === 0) return;
    setBulkUploading(true);
    const invitations = csvRows.map(row => ({
      code: row.code || '',
      description: row.description || '',
      createdBy: row.createdby || 'admin',
      grantPlan: row.grantplan || row.plan || 'pro',
      grantTrialDays: parseInt(row.granttrialdays || row.trialdays || '0') || 0,
      bonusTokens: parseInt(row.bonustokens || '0') || 0,
      maxUses: parseInt(row.maxuses || '100') || 100,
      expiresAt: row.expiresat || null,
    }));
    const { data, error } = await apiBulkCreateInvitations(invitations);
    setBulkUploading(false);
    if (data) {
      setBulkResult(data);
      loadCodes();
    } else {
      alert(error || 'Bulk upload failed');
    }
  }

  function copyCode(code: string) {
    navigator.clipboard.writeText(code);
    setCopied(code);
    setTimeout(() => setCopied(null), 2000);
  }

  return (
    <div className="space-y-6">
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold">Invitation Codes</h1>
          <p className="text-sm text-muted-foreground">
            Generate invite codes that grant plan access or bonus tokens
          </p>
        </div>
        <div className="flex gap-2">
          <Button
            variant="outline"
            onClick={() => {
              setShowBulk(true);
              setCsvRows([]);
              setBulkResult(null);
            }}
          >
            <Upload className="mr-2 h-4 w-4" /> CSV Bulk Import
          </Button>
          <Button onClick={() => setShowCreate(true)}>
            <Plus className="mr-2 h-4 w-4" /> Create Code
          </Button>
        </div>
      </div>

      <div className="grid gap-4 md:grid-cols-3">
        <Card>
          <CardHeader className="pb-2">
            <CardTitle className="text-sm font-medium text-muted-foreground">Total Codes</CardTitle>
          </CardHeader>
          <CardContent>
            <div className="text-2xl font-bold">{total}</div>
          </CardContent>
        </Card>
        <Card>
          <CardHeader className="pb-2">
            <CardTitle className="text-sm font-medium text-muted-foreground">
              Active Codes
            </CardTitle>
          </CardHeader>
          <CardContent>
            <div className="text-2xl font-bold">
              {codes.filter(c => c.status === 'active').length}
            </div>
          </CardContent>
        </Card>
        <Card>
          <CardHeader className="pb-2">
            <CardTitle className="text-sm font-medium text-muted-foreground">
              Total Redemptions
            </CardTitle>
          </CardHeader>
          <CardContent>
            <div className="text-2xl font-bold">
              {codes.reduce((sum, c) => sum + c.currentUses, 0)}
            </div>
          </CardContent>
        </Card>
      </div>

      <Card>
        <CardContent className="p-0">
          {loading ? (
            <div className="p-8 text-center text-muted-foreground">Loading...</div>
          ) : codes.length === 0 ? (
            <div className="p-8 text-center text-muted-foreground">
              <Ticket className="mx-auto mb-2 h-8 w-8 opacity-40" />
              No invitation codes yet. Create one to get started.
            </div>
          ) : (
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>Code</TableHead>
                  <TableHead>Plan</TableHead>
                  <TableHead>Trial</TableHead>
                  <TableHead>Bonus Tokens</TableHead>
                  <TableHead>Uses</TableHead>
                  <TableHead>Status</TableHead>
                  <TableHead>Created</TableHead>
                  <TableHead className="w-[50px]" />
                </TableRow>
              </TableHeader>
              <TableBody>
                {codes.map(inv => {
                  const cfg = statusConfig[inv.status] || statusConfig.active;
                  const StatusIcon = cfg.icon;
                  return (
                    <TableRow key={inv.id}>
                      <TableCell>
                        <div className="flex items-center gap-2">
                          <code className="text-sm font-mono font-bold">{inv.code}</code>
                          <button
                            onClick={() => copyCode(inv.code)}
                            className="text-muted-foreground hover:text-foreground"
                            title="Copy code"
                          >
                            <Copy className="h-3.5 w-3.5" />
                          </button>
                          {copied === inv.code && (
                            <span className="text-xs text-emerald-600">Copied!</span>
                          )}
                        </div>
                        {inv.description && (
                          <p className="text-xs text-muted-foreground mt-0.5">{inv.description}</p>
                        )}
                      </TableCell>
                      <TableCell>
                        <Badge variant="outline" className="capitalize">
                          {inv.grantPlan}
                        </Badge>
                      </TableCell>
                      <TableCell>
                        {inv.grantTrialDays > 0 ? `${inv.grantTrialDays} days` : '—'}
                      </TableCell>
                      <TableCell>
                        {inv.bonusTokens > 0 ? inv.bonusTokens.toLocaleString() : '—'}
                      </TableCell>
                      <TableCell>
                        {inv.currentUses} / {inv.maxUses}
                      </TableCell>
                      <TableCell>
                        <Badge className={`${cfg.color} border-0 gap-1`}>
                          <StatusIcon className="h-3 w-3" />
                          {cfg.label}
                        </Badge>
                      </TableCell>
                      <TableCell className="text-muted-foreground text-xs">
                        {formatDate(inv.createdAt)}
                      </TableCell>
                      <TableCell>
                        <DropdownMenu>
                          <DropdownMenuTrigger asChild>
                            <Button variant="ghost" size="icon" className="h-8 w-8">
                              <MoreHorizontal className="h-4 w-4" />
                            </Button>
                          </DropdownMenuTrigger>
                          <DropdownMenuContent align="end">
                            <DropdownMenuItem onClick={() => copyCode(inv.code)}>
                              Copy Code
                            </DropdownMenuItem>
                            <DropdownMenuItem onClick={() => handleToggle(inv)}>
                              {inv.status === 'active' ? 'Disable' : 'Enable'}
                            </DropdownMenuItem>
                            <DropdownMenuItem
                              onClick={() => handleDelete(inv.id)}
                              className="text-destructive"
                            >
                              Delete
                            </DropdownMenuItem>
                          </DropdownMenuContent>
                        </DropdownMenu>
                      </TableCell>
                    </TableRow>
                  );
                })}
              </TableBody>
            </Table>
          )}
        </CardContent>
      </Card>

      <Dialog open={showCreate} onOpenChange={setShowCreate}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Create Invitation Code</DialogTitle>
            <DialogDescription>
              Generate an invite code that grants plan access or bonus tokens when redeemed.
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-4">
            <div className="space-y-2">
              <Label>Code (optional — auto-generated if empty)</Label>
              <Input
                placeholder="e.g. BETA-2026"
                value={newCode}
                onChange={e => setNewCode(e.target.value)}
              />
            </div>
            <div className="space-y-2">
              <Label>Description</Label>
              <Input
                placeholder="e.g. Beta tester invite"
                value={newDescription}
                onChange={e => setNewDescription(e.target.value)}
              />
            </div>
            <div className="grid grid-cols-2 gap-4">
              <div className="space-y-2">
                <Label>Grant Plan</Label>
                <Select value={newPlan} onValueChange={setNewPlan}>
                  <SelectTrigger>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="pro">Pro</SelectItem>
                    <SelectItem value="enterprise">Enterprise</SelectItem>
                  </SelectContent>
                </Select>
              </div>
              <div className="space-y-2">
                <Label>Trial Days (0 = permanent)</Label>
                <Input
                  type="number"
                  min="0"
                  value={newTrialDays}
                  onChange={e => setNewTrialDays(e.target.value)}
                />
              </div>
            </div>
            <div className="grid grid-cols-2 gap-4">
              <div className="space-y-2">
                <Label>Bonus Tokens</Label>
                <Input
                  type="number"
                  min="0"
                  value={newBonusTokens}
                  onChange={e => setNewBonusTokens(e.target.value)}
                />
              </div>
              <div className="space-y-2">
                <Label>Max Uses</Label>
                <Input
                  type="number"
                  min="1"
                  value={newMaxUses}
                  onChange={e => setNewMaxUses(e.target.value)}
                />
              </div>
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setShowCreate(false)}>
              Cancel
            </Button>
            <Button onClick={handleCreate} disabled={creating}>
              {creating ? 'Creating...' : 'Create Code'}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Bulk CSV Upload Dialog */}
      <Dialog open={showBulk} onOpenChange={setShowBulk}>
        <DialogContent className="max-w-2xl">
          <DialogHeader>
            <DialogTitle className="flex items-center gap-2">
              <FileSpreadsheet className="h-5 w-5" />
              CSV Bulk Import
            </DialogTitle>
            <DialogDescription>
              Upload a CSV file with columns:{' '}
              <code className="text-xs">
                code, description, grantPlan, grantTrialDays, bonusTokens, maxUses
              </code>
              . The <code className="text-xs">createdBy</code> column is optional (defaults to your
              admin ID).
            </DialogDescription>
          </DialogHeader>

          <div className="space-y-4">
            <Input type="file" accept=".csv" onChange={handleCsvFile} className="cursor-pointer" />

            {csvRows.length > 0 && !bulkResult && (
              <div className="rounded border">
                <div className="bg-muted px-3 py-2 text-sm font-medium">
                  Preview ({csvRows.length} row{csvRows.length !== 1 ? 's' : ''})
                </div>
                <div className="max-h-[200px] overflow-auto">
                  <Table>
                    <TableHeader>
                      <TableRow>
                        <TableHead>Code</TableHead>
                        <TableHead>Plan</TableHead>
                        <TableHead>Trial</TableHead>
                        <TableHead>Tokens</TableHead>
                        <TableHead>Max Uses</TableHead>
                      </TableRow>
                    </TableHeader>
                    <TableBody>
                      {csvRows.slice(0, 10).map((row, i) => (
                        <TableRow key={i}>
                          <TableCell className="font-mono text-xs">{row.code}</TableCell>
                          <TableCell>{row.grantplan || row.plan || 'pro'}</TableCell>
                          <TableCell>{row.granttrialdays || row.trialdays || '0'}</TableCell>
                          <TableCell>{row.bonustokens || '0'}</TableCell>
                          <TableCell>{row.maxuses || '100'}</TableCell>
                        </TableRow>
                      ))}
                      {csvRows.length > 10 && (
                        <TableRow>
                          <TableCell
                            colSpan={5}
                            className="text-center text-muted-foreground text-xs"
                          >
                            ...and {csvRows.length - 10} more rows
                          </TableCell>
                        </TableRow>
                      )}
                    </TableBody>
                  </Table>
                </div>
              </div>
            )}

            {bulkResult && (
              <div className="space-y-2">
                <div className="flex gap-4 text-sm">
                  <span className="text-emerald-600 font-medium">
                    ✓ {bulkResult.created} created
                  </span>
                  {bulkResult.failed > 0 && (
                    <span className="text-red-600 font-medium">✗ {bulkResult.failed} failed</span>
                  )}
                  <span className="text-muted-foreground">of {bulkResult.total} total</span>
                </div>
                {bulkResult.errors.length > 0 && (
                  <div className="rounded border border-red-200 bg-red-50 p-2 text-xs space-y-1">
                    {bulkResult.errors.map((err, i) => (
                      <div key={i}>
                        <span className="font-medium">Row {err.index + 1}:</span> {err.error}
                      </div>
                    ))}
                  </div>
                )}
              </div>
            )}
          </div>

          <DialogFooter>
            <Button variant="outline" onClick={() => setShowBulk(false)}>
              {bulkResult ? 'Close' : 'Cancel'}
            </Button>
            {!bulkResult && (
              <Button onClick={handleBulkUpload} disabled={csvRows.length === 0 || bulkUploading}>
                {bulkUploading
                  ? 'Uploading...'
                  : `Import ${csvRows.length} Code${csvRows.length !== 1 ? 's' : ''}`}
              </Button>
            )}
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
