import { useState } from 'react';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { RefreshCw, Download, Circle, Copy, Check } from 'lucide-react';
import { toast } from 'sonner';
import { Button } from '@/components/ui/button';
import { useClient } from 'hooks/useClient';

type AppStatus = {
  id: string;
  name: string;
  description: string;
  installed: boolean;
  version: string | null;
  running: boolean | null;
  hasInstall: boolean;
  hasUpdate: boolean;
  manualInstallCommand: string | null;
  manualUpdateCommand: string | null;
};

const CopyCommand = ({ command }: { command: string }) => {
  const [copied, setCopied] = useState(false);

  const copy = () => {
    navigator.clipboard.writeText(command);
    setCopied(true);
    setTimeout(() => setCopied(false), 1500);
  };

  return (
    <div className="flex items-center gap-1 mt-1">
      <code className="flex-1 bg-duck-dark/5 dark:bg-foreground/5 rounded px-2 py-1 text-xs text-duck-dark/70 dark:text-foreground/70">{command}</code>
      <button
        type="button"
        onClick={copy}
        className="shrink-0 p-1 rounded hover:bg-duck-dark/10 dark:hover:bg-foreground/10 cursor-pointer transition-colors"
      >
        {copied ? <Check className="h-3.5 w-3.5 text-green-600" /> : <Copy className="h-3.5 w-3.5 text-duck-dark/50 dark:text-foreground/50" />}
      </button>
    </div>
  );
};

export const Applications = () => {
  const client = useClient();
  const queryClient = useQueryClient();
  const [actionInProgress, setActionInProgress] = useState<string | null>(null);

  const { data: apps, isLoading } = useQuery({
    queryKey: ['APPLICATIONS'],
    queryFn: () => client.get<AppStatus[]>('/server-settings/applications'),
  });

  const runAction = async (id: string, action: 'install' | 'update') => {
    setActionInProgress(id);
    try {
      await client.post<AppStatus>(`/server-settings/applications/${id}/${action}`);
      await queryClient.invalidateQueries({ queryKey: ['APPLICATIONS'] });
      toast.success(`${action === 'install' ? 'Installed' : 'Updated'} successfully`);
    } catch (err) {
      const message = err instanceof Error ? err.message : `${action} failed`;
      toast.error(message);
    } finally {
      setActionInProgress(null);
    }
  };

  const getManualCommand = (app: AppStatus): string | null => {
    if (!app.installed) return app.manualInstallCommand;
    return app.manualUpdateCommand ?? app.manualInstallCommand;
  };

  const hasAutoAction = (app: AppStatus): boolean => {
    if (!app.installed) return app.hasInstall && !app.manualInstallCommand;
    return app.hasUpdate && !(app.manualUpdateCommand ?? app.manualInstallCommand);
  };

  return (
    <div className="h-full overflow-y-auto p-6">
      <h2 className="text-lg font-bold text-duck-dark dark:text-foreground mb-4" title="System tools and dependencies used by Officer.dev">Applications</h2>

      {isLoading && <p className="text-sm text-duck-dark/50 dark:text-foreground/50">Checking applications...</p>}

      {apps && (
        <div className="flex flex-col gap-3">
          {apps.map((app: AppStatus) => {
            const manualCmd = getManualCommand(app);
            const canAutoRun = hasAutoAction(app);

            return (
              <div key={app.id} className="flex flex-col rounded-lg border border-duck-dark/10 dark:border-foreground/10 px-4 py-3">
                <div className="flex items-center justify-between gap-4">
                  <div className="flex-1 min-w-0">
                    <div className="flex items-center gap-2">
                      <span className="text-sm font-semibold text-duck-dark dark:text-foreground">{app.name}</span>
                      {app.installed && (
                        <span className="text-xs bg-green-100 text-green-700 rounded-full px-2 py-0.5">
                          {app.version}
                        </span>
                      )}
                      {!app.installed && (
                        <span className="text-xs bg-duck-dark/5 dark:bg-foreground/5 text-duck-dark/40 dark:text-foreground/40 rounded-full px-2 py-0.5">
                          Not installed
                        </span>
                      )}
                      {app.running !== null && (
                        <Circle
                          className={`h-2.5 w-2.5 ${app.running ? 'fill-green-500 text-green-500' : 'fill-duck-dark/20 text-duck-dark/20'}`}
                        />
                      )}
                    </div>
                    <p className="text-xs text-duck-dark/50 dark:text-foreground/50 mt-0.5">{app.description}</p>
                  </div>

                  <div className="shrink-0">
                    {canAutoRun && !app.installed && (
                      <Button
                        size="sm"
                        className="bg-duck-teal text-duck-yellow hover:bg-duck-teal/90"
                        disabled={actionInProgress === app.id}
                        onClick={() => runAction(app.id, 'install')}
                      >
                        {actionInProgress === app.id ? (
                          <RefreshCw className="h-3.5 w-3.5 animate-spin" />
                        ) : (
                          <Download className="h-3.5 w-3.5" />
                        )}
                        {actionInProgress === app.id ? 'Installing...' : 'Install'}
                      </Button>
                    )}
                    {canAutoRun && app.installed && (
                      <Button
                        size="sm"
                        variant="outline"
                        disabled={actionInProgress === app.id}
                        onClick={() => runAction(app.id, 'update')}
                      >
                        {actionInProgress === app.id ? (
                          <RefreshCw className="h-3.5 w-3.5 animate-spin" />
                        ) : (
                          <RefreshCw className="h-3.5 w-3.5" />
                        )}
                        {actionInProgress === app.id ? 'Updating...' : 'Update'}
                      </Button>
                    )}
                  </div>
                </div>

                {manualCmd && (
                  <div className="mt-2 text-xs text-duck-dark/50 dark:text-foreground/50">
                    {app.installed ? 'Update' : 'Install'} manually:
                    <CopyCommand command={manualCmd} />
                  </div>
                )}
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
};
