import { useMemo, useState } from 'react';
import { CopyButton, cn } from '@insforge/ui';
import { ShowPasswordButton } from './ShowPasswordButton';
import { useDatabaseConnectionString, useDatabasePassword } from '#lib/hooks/useMetadata';

interface ConnectionParameter {
  label: string;
  value: string | number | undefined;
}

interface ConnectionStringSectionProps {
  className?: string;
}

function formatParameterValue(value: string | number | undefined) {
  if (value === undefined || value === null || value === '') {
    return '-';
  }
  return String(value);
}

export function ConnectionStringSection({ className }: ConnectionStringSectionProps) {
  const [showConnectionPassword, setShowConnectionPassword] = useState(false);
  const [showParamsPassword, setShowParamsPassword] = useState(false);

  const { connectionData, isLoading: isConnectionLoading } = useDatabaseConnectionString();
  const { passwordData } = useDatabasePassword();

  const dbParams = connectionData?.parameters;
  const dbPassword = passwordData?.databasePassword || '';
  const maskedPassword = dbParams?.password || '*******';

  const connectionStringDisplay = useMemo(() => {
    if (!connectionData?.connectionURL) {
      return '';
    }
    if (showConnectionPassword && dbPassword) {
      return connectionData.connectionURL.replace('********', dbPassword);
    }
    return connectionData.connectionURL;
  }, [connectionData?.connectionURL, showConnectionPassword, dbPassword]);

  const connectionStringClipboard = useMemo(() => {
    if (!connectionData?.connectionURL || !dbPassword) {
      return connectionData?.connectionURL || '';
    }
    return connectionData.connectionURL.replace('********', dbPassword);
  }, [connectionData?.connectionURL, dbPassword]);

  const parameters = useMemo<ConnectionParameter[]>(() => {
    return [
      { label: 'HOST', value: dbParams?.host },
      { label: 'DATABASE', value: dbParams?.database },
      { label: 'USER', value: dbParams?.user },
      { label: 'PORT', value: dbParams?.port },
      {
        label: 'PASSWORD',
        value: showParamsPassword ? dbPassword || maskedPassword : maskedPassword,
      },
      { label: 'SSL', value: dbParams?.sslmode },
    ];
  }, [
    dbParams?.host,
    dbParams?.database,
    dbParams?.user,
    dbParams?.port,
    dbParams?.sslmode,
    dbPassword,
    maskedPassword,
    showParamsPassword,
  ]);

  return (
    <div className={cn('flex flex-col gap-3', isConnectionLoading && 'animate-pulse', className)}>
      <div className="flex flex-col gap-2 rounded border border-[var(--alpha-8)] bg-semantic-0 p-3">
        <div className="flex items-center justify-between">
          <div className="flex h-5 items-center justify-center rounded bg-[var(--alpha-8)] px-2">
            <span className="text-xs font-medium leading-4 text-muted-foreground">
              connection string
            </span>
          </div>
          <div className="flex items-center gap-2">
            <ShowPasswordButton
              show={showConnectionPassword}
              onToggle={() => setShowConnectionPassword(!showConnectionPassword)}
            />
            <CopyButton text={connectionStringClipboard} showText={false} />
          </div>
        </div>
        <p className="break-all font-mono text-sm leading-6 text-foreground">
          {connectionStringDisplay || 'Loading...'}
        </p>
      </div>

      <div className="flex flex-col gap-2 rounded border border-[var(--alpha-8)] bg-semantic-0 p-3">
        <div className="flex items-center justify-between">
          <div className="flex h-5 items-center justify-center rounded bg-[var(--alpha-8)] px-2">
            <span className="text-xs font-medium leading-4 text-muted-foreground">parameters</span>
          </div>
          <div className="flex items-center gap-2">
            <ShowPasswordButton
              show={showParamsPassword}
              onToggle={() => setShowParamsPassword(!showParamsPassword)}
            />
          </div>
        </div>
        <div className="flex flex-col gap-1 font-mono text-sm leading-5">
          {parameters.map(({ label, value }) => (
            <p key={label} className="break-all text-foreground">
              <span className="text-muted-foreground">{label}: </span>
              <span>{formatParameterValue(value)}</span>
            </p>
          ))}
        </div>
      </div>
    </div>
  );
}
