'use client';

import { useMemo, useState, type ReactNode } from 'react';
import {
  Plus,
  MoreVertical,
  Play,
  Copy,
  Trash2,
  GitBranch,
  Cpu,
  Activity,
  Search,
} from 'lucide-react';
import { Button } from '../ui/button';
import { Input } from '../ui/input';
import { Label } from '../ui/label';
import { Textarea } from '../ui/textarea';
import { Badge } from '../ui/badge';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '../ui/dialog';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from '../ui/dropdown-menu';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '../ui/table';
import { Tabs, TabsList, TabsTrigger } from '../ui/tabs';
import { cn } from '../../lib/utils';

/**
 * Minimal, in-package shape of a workflow list row. Mirrors the subset of the
 * backend list item this composer reads — kept local so the component carries
 * no app type coupling.
 */
export interface WorkflowListItem {
  uuid: string;
  name: string;
  description?: string | null;
  isBrain?: boolean;
  isTemplate?: boolean;
  nodeCount: number;
  version: number | string;
  lastExecutionStatus?: string | null;
  lastExecutionAt?: string | null;
  lastMod: string;
  executionCount?: number | null;
}

/** Payload for creating a new workflow. */
export interface WorkflowCreateInput {
  name: string;
  description?: string;
  isBrain?: boolean;
}

export interface WorkflowListComposerProps {
  /** Workflow rows to render. */
  workflows: WorkflowListItem[];
  /** Whether the list is loading (drives skeleton/empty messaging). */
  isLoading?: boolean;
  /** Error message to surface, if any. */
  error?: string | null;
  /** Navigate to a workflow's detail/canvas view. */
  onNavigateToDetail: (uuid: string) => void;
  /** Navigate to a workflow's executions view. Falls back to detail when omitted. */
  onNavigateToExecutions?: (uuid: string) => void;
  /** Delete a workflow by id. */
  onDelete: (uuid: string) => void | Promise<void>;
  /** Create a workflow from the inline create dialog. */
  onCreate: (input: WorkflowCreateInput) => void | Promise<void>;
  /** Execute a workflow by id (optional — Execute action hidden when omitted). */
  onExecute?: (uuid: string) => void | Promise<void>;
  /** Duplicate a workflow by id (optional — Duplicate action hidden when omitted). */
  onClone?: (uuid: string) => void | Promise<void>;
  /** Re-fetch the list (e.g. after search/filter/tab changes). */
  onRefresh?: (params: {
    tab: 'workflows' | 'brains';
    search: string;
    status: string;
  }) => void;
  /** Formats an ISO timestamp for display. Defaults to the raw string. */
  formatTimestamp?: (timestamp: string) => string;
}

const STATUS_OPTIONS = [
  { label: 'All', value: 'all' },
  { label: 'Active', value: 'active' },
  { label: 'Inactive', value: 'inactive' },
  { label: 'Templates', value: 'template' },
] as const;

/**
 * Inline status badge — substitute for the app's `StatusBadge` primitive
 * (not part of @startsimpli/ui). Maps common execution status slugs to a
 * theme-aware Badge color.
 */
function StatusBadge({ status }: { status: string }) {
  const tone: Record<string, string> = {
    completed:
      'border-green-200 bg-green-50 text-green-700 dark:border-green-800 dark:bg-green-950/30 dark:text-green-400',
    success:
      'border-green-200 bg-green-50 text-green-700 dark:border-green-800 dark:bg-green-950/30 dark:text-green-400',
    running:
      'border-blue-200 bg-blue-50 text-blue-700 dark:border-blue-800 dark:bg-blue-950/30 dark:text-blue-400',
    failed:
      'border-red-200 bg-red-50 text-red-700 dark:border-red-800 dark:bg-red-950/30 dark:text-red-400',
    error:
      'border-red-200 bg-red-50 text-red-700 dark:border-red-800 dark:bg-red-950/30 dark:text-red-400',
    pending:
      'border-amber-200 bg-amber-50 text-amber-700 dark:border-amber-800 dark:bg-amber-950/30 dark:text-amber-400',
    waiting:
      'border-amber-200 bg-amber-50 text-amber-700 dark:border-amber-800 dark:bg-amber-950/30 dark:text-amber-400',
  };
  return (
    <Badge
      variant="outline"
      className={cn('capitalize', tone[status.toLowerCase()])}
    >
      {status}
    </Badge>
  );
}

export function WorkflowListComposer({
  workflows,
  isLoading = false,
  error = null,
  onNavigateToDetail,
  onNavigateToExecutions,
  onDelete,
  onCreate,
  onExecute,
  onClone,
  onRefresh,
  formatTimestamp,
}: WorkflowListComposerProps) {
  const [activeTab, setActiveTab] = useState<'workflows' | 'brains'>(
    'workflows'
  );
  const [searchQuery, setSearchQuery] = useState('');
  const [statusFilter, setStatusFilter] = useState<string>('all');

  // Create dialog state
  const [createDialogOpen, setCreateDialogOpen] = useState(false);
  const [createForm, setCreateForm] = useState<WorkflowCreateInput>({
    name: '',
  });
  const [creating, setCreating] = useState(false);
  const [createNameError, setCreateNameError] = useState<string | null>(null);

  // Delete dialog state
  const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
  const [workflowToDelete, setWorkflowToDelete] =
    useState<WorkflowListItem | null>(null);

  const isBrains = activeTab === 'brains';
  const formatTime = formatTimestamp ?? ((t: string) => t);

  // Client-side filtering over the controlled `workflows` prop. The consumer
  // may also refetch via onRefresh; this keeps the UI responsive in between.
  const visibleWorkflows = useMemo(() => {
    const q = searchQuery.trim().toLowerCase();
    return workflows.filter((w) => {
      if (isBrains ? w.isBrain !== true : w.isBrain === true) return false;
      if (statusFilter === 'template' && !w.isTemplate) return false;
      if (q) {
        const haystack = `${w.name} ${w.description ?? ''}`.toLowerCase();
        if (!haystack.includes(q)) return false;
      }
      return true;
    });
  }, [workflows, isBrains, statusFilter, searchQuery]);

  const notifyRefresh = (
    next: Partial<{
      tab: 'workflows' | 'brains';
      search: string;
      status: string;
    }>
  ) => {
    onRefresh?.({
      tab: next.tab ?? activeTab,
      search: next.search ?? searchQuery,
      status: next.status ?? statusFilter,
    });
  };

  const handleTabChange = (v: string) => {
    const tab = v as 'workflows' | 'brains';
    setActiveTab(tab);
    setSearchQuery('');
    setStatusFilter('all');
    notifyRefresh({ tab, search: '', status: 'all' });
  };

  const handleSearch = (value: string) => {
    setSearchQuery(value);
    notifyRefresh({ search: value });
  };

  const handleStatusChange = (value: string) => {
    setStatusFilter(value);
    notifyRefresh({ status: value });
  };

  const handleCreate = async () => {
    if (!createForm.name.trim()) {
      setCreateNameError('Name is required');
      return;
    }
    setCreateNameError(null);
    try {
      setCreating(true);
      await onCreate({ ...createForm, isBrain: isBrains });
      setCreateDialogOpen(false);
      setCreateForm({ name: '' });
    } finally {
      setCreating(false);
    }
  };

  const handleDeleteConfirm = async () => {
    if (!workflowToDelete) return;
    try {
      await onDelete(workflowToDelete.uuid);
    } finally {
      setDeleteDialogOpen(false);
      setWorkflowToDelete(null);
    }
  };

  const emptyMessage = searchQuery
    ? `No ${isBrains ? 'brains' : 'workflows'} match your search`
    : `No ${isBrains ? 'brains' : 'workflows'} yet. Create your first ${isBrains ? 'brain' : 'workflow'} to get started.`;

  return (
    <div className="p-6 space-y-6">
      {/* Page header */}
      <div className="flex justify-between items-center">
        <div>
          <h1 className="text-3xl font-bold flex items-center gap-2">
            {isBrains ? (
              <Cpu className="h-7 w-7" />
            ) : (
              <GitBranch className="h-7 w-7" />
            )}
            {isBrains ? 'Brains' : 'Workflows'}
          </h1>
          <p className="text-muted-foreground mt-1">
            {isBrains
              ? 'Self-contained think/decide/act loops that run inside workflows'
              : 'Top-level execution loops that orchestrate your agents'}
          </p>
        </div>
        <Button
          onClick={() => setCreateDialogOpen(true)}
          data-testid={isBrains ? 'new-brain-button' : 'new-workflow-button'}
          aria-label={isBrains ? 'New brain' : 'New workflow'}
        >
          <Plus className="mr-2 h-4 w-4" />
          {isBrains ? 'New Brain' : 'New Workflow'}
        </Button>
      </div>

      <Tabs value={activeTab} onValueChange={handleTabChange}>
        <TabsList>
          <TabsTrigger
            value="workflows"
            className="gap-2"
            data-testid="workflows-tab"
          >
            <GitBranch className="h-4 w-4" />
            Workflows
          </TabsTrigger>
          <TabsTrigger value="brains" className="gap-2" data-testid="brains-tab">
            <Cpu className="h-4 w-4" />
            Brains
          </TabsTrigger>
        </TabsList>
      </Tabs>

      {/* Search + status filter (inline substitute for SearchFilterBar) */}
      <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
        <div className="relative w-full sm:max-w-sm">
          <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
          <Input
            value={searchQuery}
            onChange={(e) => handleSearch(e.target.value)}
            placeholder={
              isBrains
                ? 'Search brains by name or description...'
                : 'Search workflows by name or description...'
            }
            className="pl-9"
          />
        </div>
        <div className="flex items-center gap-1 rounded-lg border bg-muted/50 p-0.5">
          {STATUS_OPTIONS.map((opt) => (
            <Button
              key={opt.value}
              variant="ghost"
              size="sm"
              className={cn(
                'h-7 px-3 text-xs font-medium',
                statusFilter === opt.value
                  ? 'bg-background shadow-sm text-foreground'
                  : 'text-muted-foreground hover:text-foreground'
              )}
              onClick={() => handleStatusChange(opt.value)}
            >
              {opt.label}
            </Button>
          ))}
        </div>
      </div>

      {/* Data table (inline substitute for DataTable) */}
      <div className="rounded-lg border">
        <Table>
          <TableHeader>
            <TableRow>
              <TableHead>Workflow</TableHead>
              <TableHead className="text-center w-20">Nodes</TableHead>
              <TableHead className="text-center w-20">Version</TableHead>
              <TableHead className="w-24">Status</TableHead>
              <TableHead>Last Run</TableHead>
              <TableHead>Last Edit</TableHead>
              <TableHead>Executions</TableHead>
              <TableHead>Actions</TableHead>
            </TableRow>
          </TableHeader>
          <TableBody>
            {isLoading ? (
              <TableRow>
                <TableCell
                  colSpan={8}
                  className="py-12 text-center text-muted-foreground"
                >
                  Loading…
                </TableCell>
              </TableRow>
            ) : error ? (
              <TableRow>
                <TableCell
                  colSpan={8}
                  className="py-12 text-center text-destructive"
                >
                  {error}
                </TableCell>
              </TableRow>
            ) : visibleWorkflows.length === 0 ? (
              <TableRow>
                <TableCell
                  colSpan={8}
                  className="py-12 text-center text-muted-foreground"
                >
                  {emptyMessage}
                </TableCell>
              </TableRow>
            ) : (
              visibleWorkflows.map((row) => (
                <TableRow
                  key={row.uuid}
                  className="cursor-pointer"
                  onClick={() => onNavigateToDetail(row.uuid)}
                >
                  <TableCell>
                    <div>
                      <div className="font-medium flex items-center gap-1.5">
                        {row.isBrain && (
                          <Cpu className="h-3.5 w-3.5 text-teal-500 shrink-0" />
                        )}
                        {row.name}
                      </div>
                      {row.description && (
                        <div className="text-xs text-muted-foreground line-clamp-1 mt-0.5">
                          {row.description}
                        </div>
                      )}
                      {row.isTemplate && (
                        <span className="inline-flex items-center px-1.5 py-0.5 rounded text-[10px] bg-indigo-100 text-indigo-800 dark:bg-indigo-800/20 dark:text-indigo-300 mt-1">
                          template
                        </span>
                      )}
                    </div>
                  </TableCell>
                  <TableCell className="text-center w-20">
                    <span className="text-sm">{row.nodeCount}</span>
                  </TableCell>
                  <TableCell className="text-center w-20">
                    <span className="text-sm font-mono">v{row.version}</span>
                  </TableCell>
                  <TableCell className="w-24">
                    {row.lastExecutionStatus ? (
                      <StatusBadge status={row.lastExecutionStatus} />
                    ) : (
                      <span className="text-sm text-muted-foreground">—</span>
                    )}
                  </TableCell>
                  <TableCell>
                    {row.lastExecutionAt ? (
                      <span className="text-sm text-muted-foreground">
                        {formatTime(row.lastExecutionAt)}
                      </span>
                    ) : (
                      <span className="text-sm text-muted-foreground">—</span>
                    )}
                  </TableCell>
                  <TableCell>
                    <span className="text-sm text-muted-foreground">
                      {formatTime(row.lastMod)}
                    </span>
                  </TableCell>
                  <TableCell>
                    <Button
                      variant="outline"
                      size="sm"
                      className="h-7 px-2.5 text-xs rounded-full"
                      onClick={(e) => {
                        e.stopPropagation();
                        (onNavigateToExecutions ?? onNavigateToDetail)(
                          row.uuid
                        );
                      }}
                    >
                      <Activity className="mr-1 h-3 w-3" />
                      {row.executionCount ?? 0}
                    </Button>
                  </TableCell>
                  <TableCell>
                    <RowActions
                      row={row}
                      onExecute={onExecute}
                      onClone={onClone}
                      onDeleteClick={() => {
                        setWorkflowToDelete(row);
                        setDeleteDialogOpen(true);
                      }}
                    />
                  </TableCell>
                </TableRow>
              ))
            )}
          </TableBody>
        </Table>
      </div>

      {/* Create Workflow Dialog */}
      <Dialog open={createDialogOpen} onOpenChange={setCreateDialogOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>
              {isBrains ? 'Create Brain' : 'Create Workflow'}
            </DialogTitle>
            <DialogDescription>
              Create a new workflow definition. You can add nodes on the canvas
              after creation.
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-4 py-2">
            <div className="space-y-2">
              <Label htmlFor="workflow-name">Name *</Label>
              <Input
                id="workflow-name"
                name="workflow-name"
                data-testid="workflow-name-input"
                placeholder="Login Flow Automation"
                value={createForm.name}
                onChange={(e) => {
                  setCreateForm((prev) => ({ ...prev, name: e.target.value }));
                  if (createNameError) setCreateNameError(null);
                }}
                aria-invalid={createNameError ? 'true' : 'false'}
                aria-describedby={
                  createNameError ? 'workflow-name-error' : undefined
                }
                className={
                  createNameError
                    ? 'border-red-500 focus-visible:ring-red-500'
                    : ''
                }
              />
              {createNameError && (
                <p
                  id="workflow-name-error"
                  role="alert"
                  className="text-sm text-red-600"
                >
                  {createNameError}
                </p>
              )}
            </div>
            <div className="space-y-2">
              <Label htmlFor="workflow-desc">Description</Label>
              <Textarea
                id="workflow-desc"
                name="workflow-desc"
                data-testid="workflow-description-input"
                placeholder="Logs in users and navigates to dashboard"
                value={createForm.description || ''}
                onChange={(e) =>
                  setCreateForm((prev) => ({
                    ...prev,
                    description: e.target.value,
                  }))
                }
                rows={3}
              />
            </div>
          </div>
          <DialogFooter>
            <Button
              variant="outline"
              onClick={() => setCreateDialogOpen(false)}
              data-testid="workflow-create-cancel"
            >
              Cancel
            </Button>
            <Button
              onClick={handleCreate}
              disabled={creating}
              data-testid="workflow-create-submit"
            >
              {creating
                ? 'Creating...'
                : isBrains
                  ? 'Create Brain'
                  : 'Create Workflow'}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Delete confirmation dialog (inline substitute for AlertDialog) */}
      <Dialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Delete Workflow</DialogTitle>
            <DialogDescription>
              Are you sure you want to delete{' '}
              <strong>{workflowToDelete?.name}</strong>?
              <br />
              This action cannot be undone. All associated versions and execution
              history will be permanently deleted.
            </DialogDescription>
          </DialogHeader>
          <DialogFooter>
            <Button
              variant="outline"
              onClick={() => setDeleteDialogOpen(false)}
            >
              Cancel
            </Button>
            <Button
              onClick={handleDeleteConfirm}
              className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
            >
              Delete
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}

function RowActions({
  row,
  onExecute,
  onClone,
  onDeleteClick,
}: {
  row: WorkflowListItem;
  onExecute?: (uuid: string) => void | Promise<void>;
  onClone?: (uuid: string) => void | Promise<void>;
  onDeleteClick: () => void;
}): ReactNode {
  return (
    <div className="flex items-center gap-1">
      <DropdownMenu>
        <DropdownMenuTrigger asChild onClick={(e) => e.stopPropagation()}>
          <Button variant="ghost" size="sm" className="h-8 w-8 p-0">
            <MoreVertical className="h-4 w-4" />
          </Button>
        </DropdownMenuTrigger>
        <DropdownMenuContent align="end">
          {onExecute && (
            <DropdownMenuItem
              onClick={(e) => {
                e.stopPropagation();
                void onExecute(row.uuid);
              }}
            >
              <Play className="mr-2 h-4 w-4" />
              Execute
            </DropdownMenuItem>
          )}
          {onClone && (
            <DropdownMenuItem
              onClick={(e) => {
                e.stopPropagation();
                void onClone(row.uuid);
              }}
            >
              <Copy className="mr-2 h-4 w-4" />
              Duplicate
            </DropdownMenuItem>
          )}
          {!row.isTemplate && (
            <>
              <DropdownMenuSeparator />
              <DropdownMenuItem
                className="text-destructive focus:text-destructive"
                onClick={(e) => {
                  e.stopPropagation();
                  onDeleteClick();
                }}
              >
                <Trash2 className="mr-2 h-4 w-4" />
                Delete
              </DropdownMenuItem>
            </>
          )}
        </DropdownMenuContent>
      </DropdownMenu>
    </div>
  );
}
