'use client';

import { useState, useCallback, useMemo } from 'react';
import { useTranslations } from 'next-intl';
import { motion, AnimatePresence } from 'framer-motion';
import {
  ChevronDown,
  ChevronRight,
  Users,
  Building2,
  User,
  Maximize2,
  Minimize2,
} from 'lucide-react';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Skeleton } from '@/components/ui/skeleton';
import { cn } from '@/lib/utils';
import { useEmployees, type Employee } from '@/hooks/hr/use-employees';

interface OrgChartProps {
  /** Current locale */
  locale: string;
}

/**
 * Organization node in the hierarchy
 */
interface OrgNode {
  employee: Employee;
  children: OrgNode[];
}

/**
 * Build org tree from flat employee list
 */
function buildOrgTree(employees: Employee[]): OrgNode[] {
  // Find root nodes (employees without managers)
  const roots = employees.filter((e) => !e.managerId);

  // Build tree recursively
  function buildChildren(parentId: string): OrgNode[] {
    return employees
      .filter((e) => e.managerId === parentId)
      .map((employee) => ({
        employee,
        children: buildChildren(employee.id),
      }));
  }

  return roots.map((employee) => ({
    employee,
    children: buildChildren(employee.id),
  }));
}

/**
 * Organization chart component
 * Displays hierarchical tree view of employees
 */
export function OrgChart({ locale }: OrgChartProps) {
  const t = useTranslations('hr');

  const { data, isLoading, error } = useEmployees({ status: 'active', limit: 100 });
  const [expandedNodes, setExpandedNodes] = useState<Set<string>>(new Set());
  const [isFullscreen, setIsFullscreen] = useState(false);

  // Build tree from employee data
  const orgTree = useMemo(() => {
    if (!data?.data) return [];
    return buildOrgTree(data.data);
  }, [data?.data]);

  // Toggle node expansion
  const toggleNode = useCallback((id: string) => {
    setExpandedNodes((prev) => {
      const next = new Set(prev);
      if (next.has(id)) {
        next.delete(id);
      } else {
        next.add(id);
      }
      return next;
    });
  }, []);

  // Expand all nodes
  const expandAll = useCallback(() => {
    if (!data?.data) return;
    setExpandedNodes(new Set(data.data.map((e) => e.id)));
  }, [data?.data]);

  // Collapse all nodes
  const collapseAll = useCallback(() => {
    setExpandedNodes(new Set());
  }, []);

  // Loading state
  if (isLoading) {
    return (
      <div className="space-y-4">
        <Skeleton className="h-32 w-64 mx-auto" />
        <div className="flex justify-center gap-8">
          <Skeleton className="h-28 w-56" />
          <Skeleton className="h-28 w-56" />
          <Skeleton className="h-28 w-56" />
        </div>
      </div>
    );
  }

  // Error state
  if (error) {
    return (
      <div className="flex flex-col items-center justify-center py-12">
        <Users className="h-12 w-12 text-muted-foreground/50 mb-4" />
        <p className="text-destructive">{t('errorLoadingOrgChart')}</p>
      </div>
    );
  }

  // Empty state
  if (orgTree.length === 0) {
    return (
      <div className="flex flex-col items-center justify-center py-12">
        <Building2 className="h-12 w-12 text-muted-foreground/50 mb-4" />
        <p className="text-muted-foreground">{t('noEmployeesFound')}</p>
      </div>
    );
  }

  return (
    <div
      className={cn(
        'transition-all duration-300',
        isFullscreen && 'fixed inset-0 z-50 bg-background p-8 overflow-auto'
      )}
    >
      {/* Controls */}
      <div className="flex justify-end gap-2 mb-6">
        <Button variant="outline" size="sm" onClick={expandAll}>
          {t('expandAll')}
        </Button>
        <Button variant="outline" size="sm" onClick={collapseAll}>
          {t('collapseAll')}
        </Button>
        <Button
          variant="outline"
          size="sm"
          onClick={() => setIsFullscreen(!isFullscreen)}
        >
          {isFullscreen ? (
            <>
              <Minimize2 className="h-4 w-4 mr-2" />
              {t('exitFullscreen')}
            </>
          ) : (
            <>
              <Maximize2 className="h-4 w-4 mr-2" />
              {t('fullscreen')}
            </>
          )}
        </Button>
      </div>

      {/* Tree */}
      <div className="flex flex-col items-center">
        {orgTree.map((node) => (
          <OrgTreeNode
            key={node.employee.id}
            node={node}
            locale={locale}
            expandedNodes={expandedNodes}
            onToggle={toggleNode}
            level={0}
            t={t}
          />
        ))}
      </div>
    </div>
  );
}

interface OrgTreeNodeProps {
  node: OrgNode;
  locale: string;
  expandedNodes: Set<string>;
  onToggle: (id: string) => void;
  level: number;
  t: (key: string) => string;
}

/**
 * Single node in the org chart tree
 */
function OrgTreeNode({
  node,
  locale,
  expandedNodes,
  onToggle,
  level,
  t,
}: OrgTreeNodeProps) {
  const { employee, children } = node;
  const hasChildren = children.length > 0;
  const isExpanded = expandedNodes.has(employee.id);
  const initials = `${employee.firstName.charAt(0)}${employee.lastName.charAt(0)}`;

  // Get role badge color
  const getRoleBadgeColor = (roles: string[]) => {
    if (roles.includes('admin'))
      return 'bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400';
    if (roles.includes('manager') || roles.includes('department_head'))
      return 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400';
    return 'bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-400';
  };

  return (
    <div className="flex flex-col items-center">
      {/* Connecting line from parent */}
      {level > 0 && (
        <div className="w-px h-4 bg-border" />
      )}

      {/* Node card */}
      <motion.div
        initial={{ opacity: 0, scale: 0.9 }}
        animate={{ opacity: 1, scale: 1 }}
        transition={{ duration: 0.2 }}
      >
        <Card
          className={cn(
            'w-64 cursor-pointer hover:shadow-md transition-shadow',
            hasChildren && 'cursor-pointer'
          )}
          onClick={() => hasChildren && onToggle(employee.id)}
        >
          <CardContent className="p-4">
            <div className="flex items-center gap-3">
              <Avatar className="h-12 w-12">
                <AvatarImage
                  src={employee.avatarUrl}
                  alt={`${employee.firstName} ${employee.lastName}`}
                />
                <AvatarFallback className="bg-primary/10 text-primary font-medium">
                  {initials}
                </AvatarFallback>
              </Avatar>
              <div className="flex-1 min-w-0">
                <h4 className="font-semibold text-sm truncate">
                  {employee.firstName} {employee.lastName}
                </h4>
                <p className="text-xs text-muted-foreground truncate">
                  {employee.position}
                </p>
                <div className="flex items-center gap-1 mt-1">
                  <Building2 className="h-3 w-3 text-muted-foreground" />
                  <span className="text-xs text-muted-foreground truncate">
                    {employee.department?.name}
                  </span>
                </div>
              </div>
              {hasChildren && (
                <div className="flex items-center gap-1 text-muted-foreground">
                  <Badge variant="secondary" className="text-xs">
                    {children.length}
                  </Badge>
                  {isExpanded ? (
                    <ChevronDown className="h-4 w-4" />
                  ) : (
                    <ChevronRight className="h-4 w-4" />
                  )}
                </div>
              )}
            </div>
            <div className="mt-2 pt-2 border-t flex items-center justify-between">
              <Badge
                variant="outline"
                className={cn('text-xs', getRoleBadgeColor(employee.roles))}
              >
                {employee.roles[0]}
              </Badge>
              {hasChildren && (
                <span className="text-xs text-muted-foreground">
                  {t('directReports')}: {children.length}
                </span>
              )}
            </div>
          </CardContent>
        </Card>
      </motion.div>

      {/* Children */}
      <AnimatePresence>
        {hasChildren && isExpanded && (
          <motion.div
            initial={{ opacity: 0, height: 0 }}
            animate={{ opacity: 1, height: 'auto' }}
            exit={{ opacity: 0, height: 0 }}
            transition={{ duration: 0.3 }}
            className="flex flex-col items-center"
          >
            {/* Vertical line down */}
            <div className="w-px h-4 bg-border" />

            {/* Horizontal connector */}
            {children.length > 1 && (
              <div
                className="h-px bg-border"
                style={{
                  width: `${(children.length - 1) * 280}px`,
                }}
              />
            )}

            {/* Child nodes */}
            <div className="flex gap-4">
              {children.map((child, index) => (
                <div key={child.employee.id} className="flex flex-col items-center">
                  {/* Vertical line to child */}
                  <div className="w-px h-4 bg-border" />
                  <OrgTreeNode
                    node={child}
                    locale={locale}
                    expandedNodes={expandedNodes}
                    onToggle={onToggle}
                    level={level + 1}
                    t={t}
                  />
                </div>
              ))}
            </div>
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
}
