import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { AlertCircle, CheckCircle2, X } from 'lucide-react';
import { useI18n } from '../../i18n';
import type { ChannelConfigFieldMeta, ChannelConfigFieldValueMap } from '../../lib/channel-types';
import { getChannelMeta, type ChannelMeta } from '../../lib/channel-meta';
import ChannelConfigActions from './ChannelConfigActions';
import ChannelConfigFields from './ChannelConfigFields';
import ChannelInstructionsPanel from './ChannelInstructionsPanel';

export type ChannelFieldValidationResult = {
  key: string;
  label: string;
  kind: string;
  required: boolean;
  provided: boolean;
  valid: boolean;
  errors: string[];
  warnings: string[];
};

export type ChannelCredentialsValidationResult = {
  valid: boolean;
  errors: string[];
  warnings: string[];
  details?: {
    channelType?: string;
    accountId?: string;
    channelName?: string;
    connectionType?: string;
    fields?: ChannelFieldValidationResult[];
    [key: string]: unknown;
  };
};

export type ChannelConfigModalProps = {
  open: boolean;
  selectedChannelType: string;
  values: ChannelConfigFieldValueMap;
  onValueChange: (key: string, value: string) => void;
  onClose: () => void;
  onConfirm: () => void | Promise<void>;
  onValidate?: () => void | Promise<void>;
  error?: string | null;
  submitting?: boolean;
  validating?: boolean;
  validationResult?: ChannelCredentialsValidationResult | null;
  title?: string;
  description?: string;
  confirmLabel?: string;
  validateLabel?: string;
  validatingLabel?: string;
};

function withTranslatedMeta(
  meta: ChannelMeta,
  translate: (path: string, fallback: string) => string,
): ChannelMeta {
  return {
    ...meta,
    name: translate(`channels.meta.${meta.type}.name`, meta.name),
    description: translate(`channels.meta.${meta.type}.description`, meta.description),
    docsUrl: meta.docsUrl
      ? translate(`channels.meta.${meta.type}.docsUrl`, meta.docsUrl)
      : meta.docsUrl,
    instructions: meta.instructions.map((instruction, index) => (
      translate(`channels.meta.${meta.type}.instructions.${index}`, instruction)
    )),
    configFields: meta.configFields.map((field) => withTranslatedField(meta.type, field, translate)),
  };
}

function withTranslatedField(
  channelType: string,
  field: ChannelConfigFieldMeta,
  translate: (path: string, fallback: string) => string,
): ChannelConfigFieldMeta {
  return {
    ...field,
    label: translate(`channels.meta.${channelType}.fields.${field.key}.label`, field.label),
    placeholder: field.placeholder
      ? translate(`channels.meta.${channelType}.fields.${field.key}.placeholder`, field.placeholder)
      : field.placeholder,
    description: field.description
      ? translate(`channels.meta.${channelType}.fields.${field.key}.description`, field.description)
      : field.description,
    docsUrl: field.docsUrl
      ? translate(`channels.meta.${channelType}.fields.${field.key}.docsUrl`, field.docsUrl)
      : field.docsUrl,
  };
}

export default function ChannelConfigModal({
  open,
  selectedChannelType,
  values,
  onValueChange,
  onClose,
  onConfirm,
  onValidate,
  error,
  submitting,
  validating,
  validationResult,
  title,
  description,
  confirmLabel,
  validateLabel,
  validatingLabel,
}: ChannelConfigModalProps) {
  const { t, hasMessage } = useI18n();
  const [showSecrets, setShowSecrets] = useState<Record<string, boolean>>({});
  const firstFieldRef = useRef<HTMLDivElement>(null);

  const translate = useCallback((path: string, fallback: string) => (
    hasMessage(path) ? t(path) : fallback
  ), [hasMessage, t]);

  const activeMeta = useMemo(
    () => withTranslatedMeta(getChannelMeta(selectedChannelType), translate),
    [selectedChannelType, translate],
  );
  const supportedFields = activeMeta.configFields.filter((field) => field.key !== 'accountId');
  const canValidate = Boolean(onValidate) && activeMeta.connectionType !== 'qr';

  const resolvedTitle = title ?? t('channels.modal.configureTitle', { name: activeMeta.name });
  const descriptionText = description ?? activeMeta.description;
  const instructionsHeading = t('channels.modal.howTo');
  const confirmText = confirmLabel ?? (canValidate ? t('channels.modal.saveAndConnect') : t('channels.modal.confirm'));
  const validateText = validateLabel ?? t('channels.modal.validateConfig');
  const validatingText = validatingLabel ?? t('channels.modal.validating');

  useEffect(() => {
    if (!open) {
      setShowSecrets({});
    }
  }, [open]);

  useEffect(() => {
    setShowSecrets({});
  }, [selectedChannelType]);

  useEffect(() => {
    if (open && firstFieldRef.current) {
      firstFieldRef.current.focus();
    }
  }, [open, selectedChannelType]);

  const toggleSecretVisibility = useCallback((key: string) => {
    setShowSecrets((prev) => ({ ...prev, [key]: !prev[key] }));
  }, []);

  if (!open) return null;

  return (
    <div
      className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4 backdrop-blur-[2px]"
      onMouseDown={(event) => {
        if (event.target === event.currentTarget) {
          onClose();
        }
      }}
    >
      <div
        className="flex max-h-[92vh] w-full max-w-280 flex-col overflow-hidden rounded-[34px] border border-black/10 bg-white shadow-[0_32px_90px_-24px_rgba(15,23,42,0.35)] dark:border-white/10 dark:bg-[#1c1c20]"
        onMouseDown={(event) => event.stopPropagation()}
        onClick={(event) => event.stopPropagation()}
      >
        <div className="flex items-start justify-between gap-6 px-10 pb-2 pt-9">
          <div className="min-w-0">
            <h2
              className="text-[54px] leading-[0.98] font-normal tracking-tight text-[#0f172a] dark:text-[#f3f4f6]"
              style={{ fontFamily: "Georgia, Cambria, 'Times New Roman', Times, serif" }}
            >
              {resolvedTitle}
            </h2>
            <p className="mt-5 max-w-4xl text-[16px] leading-8 text-[#667085] dark:text-gray-300">
              {descriptionText}
            </p>
          </div>

          <button
            type="button"
            className="mt-1 inline-flex h-11 w-11 shrink-0 items-center justify-center rounded-full text-[#98a2b3] transition-colors hover:bg-black/5 hover:text-[#0f172a] dark:text-gray-400 dark:hover:bg-white/5 dark:hover:text-gray-100"
            onClick={onClose}
            aria-label={t('window.close')}
          >
            <X className="h-6 w-6" />
          </button>
        </div>

        <div className="min-h-0 flex-1 overflow-y-auto px-10 pb-8 pt-6">
          <div className="space-y-8">
            {error ? (
              <div className="rounded-[22px] border border-[#efb3b3] bg-[#fff1f1] px-5 py-4 text-[14px] leading-7 text-[#b42318] dark:border-red-500/20 dark:bg-red-500/10 dark:text-red-300">
                {error}
              </div>
            ) : null}

            <ChannelInstructionsPanel
              meta={activeMeta}
              title={instructionsHeading}
              viewDocsLabel={t('channels.modal.viewDocs')}
            />

            <div ref={firstFieldRef} tabIndex={-1} className="space-y-8 outline-none">
              <ChannelConfigFields
                fields={supportedFields}
                values={values}
                onValueChange={onValueChange}
                disabled={submitting || validating}
                showSecretMap={showSecrets}
                onToggleSecret={toggleSecretVisibility}
                emptyStateText={t('channels.modal.noAdditionalFields')}
                envVarLabel={t('channels.modal.envVar')}
                showSecretLabel={t('channels.modal.showSecret')}
                hideSecretLabel={t('channels.modal.hideSecret')}
              />
            </div>

            {validationResult ? (
              <div
                className={[
                  'rounded-[22px] border px-5 py-4 text-[14px] leading-7',
                  validationResult.valid
                    ? 'border-emerald-500/20 bg-emerald-500/10 text-emerald-800 dark:text-emerald-300'
                    : 'border-red-500/20 bg-red-500/10 text-red-700 dark:text-red-300',
                ].join(' ')}
              >
                <div className="flex items-start gap-3">
                  {validationResult.valid ? (
                    <CheckCircle2 className="mt-1 h-5 w-5 shrink-0" />
                  ) : (
                    <AlertCircle className="mt-1 h-5 w-5 shrink-0" />
                  )}
                  <div className="min-w-0">
                    <div className="font-semibold">
                      {validationResult.valid ? t('channels.modal.credentialsVerified') : t('channels.modal.validationFailed')}
                    </div>

                    {validationResult.errors.length > 0 ? (
                      <ul className="mt-2 list-disc space-y-1 pl-5">
                        {validationResult.errors.map((item) => (
                          <li key={item}>{item}</li>
                        ))}
                      </ul>
                    ) : null}

                    {validationResult.warnings.length > 0 ? (
                      <div className="mt-3">
                        <div className="text-[12px] font-semibold uppercase tracking-[0.12em] opacity-80">
                          {t('channels.modal.warnings')}
                        </div>
                        <ul className="mt-2 list-disc space-y-1 pl-5">
                          {validationResult.warnings.map((item) => (
                            <li key={item}>{item}</li>
                          ))}
                        </ul>
                      </div>
                    ) : null}
                  </div>
                </div>
              </div>
            ) : null}

            <ChannelConfigActions
              confirmLabel={confirmText}
              validateLabel={validateText}
              validatingLabel={validatingText}
              onConfirm={() => {
                void onConfirm();
              }}
              onValidate={canValidate ? () => {
                void onValidate?.();
              } : undefined}
              disabled={false}
              submitting={submitting}
              validating={validating}
            />
          </div>
        </div>
      </div>
    </div>
  );
}
