import { useState } from 'react';
import { Link, useLocation, useNavigate } from 'react-router';
import { FolderKanban, Plus, Pencil, Trash2, Search, Rocket } from 'lucide-react';
import { useQueryClient } from '@tanstack/react-query';
import { useGlobal } from 'hooks/useGlobal';
import { useClient } from 'hooks/useClient';
import { generateSlug } from 'helpers/slug';
import { useDashboardState } from 'state/useDashboardState';
import type { ProjectDefinition, ProjectType } from '../../components/Workspace';
import { PublishDialog } from './PublishDialog';
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import {
  SELECTED_PROJECT,
  CREATING_PROJECT,
  EDITING_PROJECT,
  NEW_PROJ_NAME,
  NEW_PROJ_DESC,
  NEW_PROJ_TEMPLATE,
  NEW_PROJ_TYPE,
  NEW_PROJ_HAS_BACKEND,
  NEW_PROJ_HAS_AUTH,
} from './constants';

const PROJECT_TYPE_LABELS: Record<ProjectType, string> = {
  'landing-page': 'Landing Page',
  'website': 'Website',
  'app': 'App',
};

export const ProjectListApp = () => {
  const location = useLocation();
  const navigate = useNavigate();
  const client = useClient();
  const queryClient = useQueryClient();
  const { value: projects } = useDashboardState<ProjectDefinition[]>('projects', []);
  const [selected, setSelected] = useGlobal<string | null>(SELECTED_PROJECT, null);
  const [, setCreating] = useGlobal<boolean>(CREATING_PROJECT, false);
  const [, setEditing] = useGlobal<string | null>(EDITING_PROJECT, null);
  const [, setName] = useGlobal<string>(NEW_PROJ_NAME, '');
  const [, setDescription] = useGlobal<string>(NEW_PROJ_DESC, '');
  const [, setTemplateIdx] = useGlobal<number>(NEW_PROJ_TEMPLATE, 0);
  const [, setProjectType] = useGlobal<ProjectType>(NEW_PROJ_TYPE, 'app');
  const [, setHasBackend] = useGlobal<boolean>(NEW_PROJ_HAS_BACKEND, false);
  const [, setHasAuth] = useGlobal<boolean>(NEW_PROJ_HAS_AUTH, false);

  const [search, setSearch] = useState('');
  const [deleting, setDeleting] = useState<ProjectDefinition | null>(null);
  const [publishing, setPublishing] = useState<ProjectDefinition | null>(null);
  const isProjectsPage = location.pathname === '/projects';
  const filtered = search
    ? projects.filter((p) => {
        const q = search.toLowerCase();
        return [p.name, p.id, p.description ?? '', p.cwd ?? '', p.projectType].some((field) =>
          field.toLowerCase().includes(q),
        );
      })
    : projects;

  const handleEdit = (ev: React.MouseEvent, p: ProjectDefinition) => {
    ev.stopPropagation();
    setSelected(null);
    setCreating(false);
    setEditing(p.id);
    setName(p.name);
    setDescription(p.description ?? '');
    setTemplateIdx(p.templateIdx ?? 0);
    setProjectType(p.projectType);
    setHasBackend(p.hasBackend ?? false);
    setHasAuth(p.hasAuth ?? false);
  };

  const handleDelete = (ev: React.MouseEvent, p: ProjectDefinition) => {
    ev.stopPropagation();
    setDeleting(p);
  };

  const handlePublish = (ev: React.MouseEvent, p: ProjectDefinition) => {
    ev.stopPropagation();
    setPublishing(p);
  };

  const confirmDelete = () => {
    if (!deleting) return;
    // Optimistic: remove from cache immediately
    const current = queryClient.getQueryData<Record<string, unknown>>(['DASHBOARD_STATE']) ?? {};
    const optimistic = { ...current };
    optimistic['projects'] = (optimistic['projects'] as ProjectDefinition[]).filter((p) => p.id !== deleting.id);
    delete optimistic[`proj-layout-${deleting.id}`];
    delete optimistic[`proj-terminals-${deleting.id}`];
    delete optimistic[`proj-host-terminals-${deleting.id}`];
    queryClient.setQueryData(['DASHBOARD_STATE'], optimistic);

    if (selected === deleting.id) setSelected(null);
    setDeleting(null);
    client
      .patch('/dashboards', { [`proj-meta-${deleting.id}`]: null })
      .then((res) => queryClient.setQueryData(['DASHBOARD_STATE'], res))
      .catch(() => {});
  };

  const handleClick = (p: ProjectDefinition) => {
    if (isProjectsPage) {
      setSelected(p.id);
      setCreating(false);
      setEditing(null);
    } else {
      navigate(`/projects/${p.id}`);
    }
  };

  return (
    <div className="flex flex-col h-full overflow-y-auto">
      <div className="p-3 pb-0 flex flex-col gap-2">
        <Link
          to="/projects"
          className="flex items-center gap-2.5 rounded-lg px-3 py-2 text-sm font-medium bg-emerald-500/15 text-emerald-400"
        >
          <FolderKanban className="h-4 w-4" />
          Projects
        </Link>
        <button
          type="button"
          onClick={() => {
            setSelected(null);
            setEditing(null);
            setName(generateSlug());
            setDescription('');
            setTemplateIdx(0);
            setProjectType('app');
            setHasBackend(false);
            setHasAuth(false);
            setCreating(true);
            if (!isProjectsPage) navigate('/projects');
          }}
          className="flex items-center justify-center gap-1 py-2 px-3 rounded-lg text-sm font-medium bg-emerald-500 hover:bg-emerald-500/90 text-white transition-all cursor-pointer"
        >
          <Plus className="h-4 w-4 shrink-0" />
          New Project
        </button>
      </div>
      <div className="relative px-3 pt-2">
        <Search className="absolute left-6 top-1/2 h-3.5 w-3.5 text-gray-500 pointer-events-none" />
        <input
          type="text"
          value={search}
          onChange={(ev) => setSearch(ev.target.value)}
          placeholder="Search projects"
          className="w-full rounded-lg border border-duck-dark/15 bg-transparent py-1.5 pl-8 pr-3 text-sm text-white placeholder:text-gray-500 focus:outline-none focus:ring-1 focus:ring-emerald-500/30 focus:border-emerald-500/40"
        />
      </div>
      <div className="flex flex-col gap-0.5 px-3 pt-2">
        {filtered.map((p) => (
          <div
            key={p.id}
            className={`flex items-center gap-2.5 py-2 px-3 rounded-lg text-sm font-medium cursor-pointer group ${
              isProjectsPage && selected === p.id
                ? 'bg-emerald-500/10 text-emerald-400'
                : 'text-duck-dark/80 dark:text-white/80 hover:bg-duck-dark/5'
            }`}
            onClick={() => handleClick(p)}
          >
            <FolderKanban className="h-4 w-4 shrink-0" />
            <span className="flex-1 text-left truncate">{p.name}</span>
            <span className="text-[10px] text-duck-dark/30 shrink-0">{PROJECT_TYPE_LABELS[p.projectType]}</span>
            {isProjectsPage && (
              <>
                <button
                  type="button"
                  onClick={(ev) => handlePublish(ev, p)}
                  className="shrink-0 p-1 rounded text-duck-dark/20 md:opacity-0 md:group-hover:opacity-100 hover:text-blue-400 transition-opacity cursor-pointer"
                  title="Publish"
                >
                  <Rocket className="h-3.5 w-3.5" />
                </button>
                <button
                  type="button"
                  onClick={(ev) => handleEdit(ev, p)}
                  className="shrink-0 p-1 rounded text-duck-dark/20 md:opacity-0 md:group-hover:opacity-100 hover:text-emerald-400 transition-opacity cursor-pointer"
                >
                  <Pencil className="h-3.5 w-3.5" />
                </button>
                <button
                  type="button"
                  onClick={(ev) => handleDelete(ev, p)}
                  className="shrink-0 p-1 rounded text-duck-dark/20 md:opacity-0 md:group-hover:opacity-100 hover:text-red-500 transition-opacity cursor-pointer"
                >
                  <Trash2 className="h-3.5 w-3.5" />
                </button>
              </>
            )}
          </div>
        ))}
        {filtered.length === 0 && (
          <p className="text-xs text-gray-500 px-3 py-4 text-center">
            {search ? 'No matches' : 'No projects yet'}
          </p>
        )}
      </div>

      <AlertDialog open={deleting !== null} onOpenChange={(open) => { if (!open) setDeleting(null); }}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Delete project</AlertDialogTitle>
            <AlertDialogDescription>
              Are you sure you want to delete <strong>{deleting?.name}</strong>? This action cannot be undone.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>Cancel</AlertDialogCancel>
            <AlertDialogAction onClick={confirmDelete} className="bg-red-600 hover:bg-red-700">
              Delete
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      {publishing && (
        <PublishDialog
          open={true}
          onOpenChange={(open) => { if (!open) setPublishing(null); }}
          projectSlug={publishing.id}
          projectName={publishing.name}
        />
      )}
    </div>
  );
};
