import React, { useCallback, useEffect, useRef, useState } from 'react';
import {
  Eye,
  EyeOff,
  Loader2,
  CheckCircle,
  AlertTriangle,
  XCircle,
  Save,
  KeyRound,
  Globe,
  AlertCircle,
} from 'lucide-react';
import { agentSettingsBridge } from '../../lib/agentSettingsBridge';
import {
  AgentConfigStatus,
  AgentTaskRoute,
  TASK_LABELS,
  TASK_PROFILES,
  TaskProfile,
} from '../../types/agentSettings';
import { ConfirmDialog } from './ConfirmDialog';
import { ModelSelector } from './ModelSelector';
import { ValidatedInput, ValidationStatus } from './ValidatedInput';
import { HelpIcon } from './Tooltip';

interface AgentSettingsFormProps {
  status: AgentConfigStatus | null;
  onStatusChange: (status: AgentConfigStatus) => void;
}

interface FormState {
  remoteEnabled: boolean;
  remoteBaseUrl: string;
  defaultRemoteModel: string;
  taskDefaults: Record<TaskProfile, AgentTaskRoute>;
  secEdgarUserAgent: string;
  remoteApiKey: string;
}

interface ValidationState {
  baseUrl: ValidationStatus;
  baseUrlError?: string;
  defaultModel: ValidationStatus;
  secEdgarUserAgent: ValidationStatus;
  secEdgarUserAgentError?: string;
  apiKey: ValidationStatus;
}

const mergeTaskDefaults = (
  taskDefaults: Partial<Record<TaskProfile, AgentTaskRoute>>,
  defaultRemoteModel: string,
): Record<TaskProfile, AgentTaskRoute> =>
  TASK_PROFILES.reduce((acc, profile) => {
    acc[profile] = taskDefaults[profile] ?? { model: defaultRemoteModel };
    return acc;
  }, {} as Record<TaskProfile, AgentTaskRoute>);

const validateUrl = (url: string): { valid: boolean; error?: string } => {
  if (!url.trim()) {
    return { valid: false, error: 'Base URL is required' };
  }
  try {
    new URL(url);
    return { valid: true };
  } catch {
    return { valid: false, error: 'Please enter a valid URL (e.g., https://api.example.com)' };
  }
};

const validateSecEdgarUserAgent = (
  value: string,
): { valid: boolean; error?: string } => {
  const trimmed = value.trim();
  if (!trimmed) {
    return { valid: true };
  }

  if (!trimmed.includes(' ') || !trimmed.includes('@')) {
    return {
      valid: false,
      error: 'Use a format like `MosaicIQ admin@example.com`',
    };
  }

  return { valid: true };
};

export const AgentSettingsForm: React.FC<AgentSettingsFormProps> = ({
  status,
  onStatusChange,
}) => {
  const [formState, setFormState] = useState<FormState>({
    remoteEnabled: true,
    remoteBaseUrl: '',
    defaultRemoteModel: '',
    taskDefaults: mergeTaskDefaults({}, ''),
    secEdgarUserAgent: '',
    remoteApiKey: '',
  });
  const [initialState, setInitialState] = useState<FormState | null>(null);
  const [validation, setValidation] = useState<ValidationState>({
    baseUrl: 'idle',
    defaultModel: 'idle',
    secEdgarUserAgent: 'idle',
    apiKey: 'idle',
  });
  const [showApiKey, setShowApiKey] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [success, setSuccess] = useState<string | null>(null);
  const [isBusy, setIsBusy] = useState(false);
  const [showClearConfirm, setShowClearConfirm] = useState(false);
  const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
  const [dontAskAgain, setDontAskAgain] = useState(false);
  const saveButtonRef = useRef<HTMLButtonElement>(null);

  // Initialize form state from props
  useEffect(() => {
    if (!status) return;

    const newState: FormState = {
      remoteEnabled: status.remoteEnabled,
      remoteBaseUrl: status.remoteBaseUrl,
      defaultRemoteModel: status.defaultRemoteModel,
      taskDefaults: mergeTaskDefaults(status.taskDefaults, status.defaultRemoteModel),
      secEdgarUserAgent: status.secEdgarUserAgent,
      remoteApiKey: '',
    };

    setFormState(newState);
    setInitialState(newState);
    setError(null);
    setSuccess(null);
    setHasUnsavedChanges(false);
    setValidation({
      baseUrl: 'idle',
      defaultModel: 'idle',
      secEdgarUserAgent: 'idle',
      apiKey: 'idle',
    });
  }, [status]);

  // Track unsaved changes
  useEffect(() => {
    if (!initialState) return;

    const hasChanges =
      formState.remoteEnabled !== initialState.remoteEnabled ||
      formState.remoteBaseUrl !== initialState.remoteBaseUrl ||
      formState.defaultRemoteModel !== initialState.defaultRemoteModel ||
      JSON.stringify(formState.taskDefaults) !== JSON.stringify(initialState.taskDefaults) ||
      formState.secEdgarUserAgent !== initialState.secEdgarUserAgent ||
      Boolean(formState.remoteApiKey && formState.remoteApiKey.length > 0);

    setHasUnsavedChanges(hasChanges);
  }, [formState, initialState]);

  // Validate base URL on change
  useEffect(() => {
    if (formState.remoteBaseUrl) {
      const result = validateUrl(formState.remoteBaseUrl);
      setValidation((prev) => ({
        ...prev,
        baseUrl: result.valid ? 'valid' : 'invalid',
        baseUrlError: result.error,
      }));
    } else {
      setValidation((prev) => ({ ...prev, baseUrl: 'idle', baseUrlError: undefined }));
    }
  }, [formState.remoteBaseUrl]);

  // Validate default model
  useEffect(() => {
    if (formState.defaultRemoteModel) {
      setValidation((prev) => ({ ...prev, defaultModel: 'valid' }));
    } else {
      setValidation((prev) => ({ ...prev, defaultModel: 'idle' }));
    }
  }, [formState.defaultRemoteModel]);

  useEffect(() => {
    if (formState.secEdgarUserAgent.trim()) {
      const result = validateSecEdgarUserAgent(formState.secEdgarUserAgent);
      setValidation((prev) => ({
        ...prev,
        secEdgarUserAgent: result.valid ? 'valid' : 'invalid',
        secEdgarUserAgentError: result.error,
      }));
    } else {
      setValidation((prev) => ({
        ...prev,
        secEdgarUserAgent: 'idle',
        secEdgarUserAgentError: undefined,
      }));
    }
  }, [formState.secEdgarUserAgent]);

  // Validate API key
  useEffect(() => {
    if (formState.remoteApiKey) {
      setValidation((prev) => ({ ...prev, apiKey: 'valid' }));
    } else {
      setValidation((prev) => ({ ...prev, apiKey: 'idle' }));
    }
  }, [formState.remoteApiKey]);

  if (!status) {
    return (
      <div className="rounded-lg border border-[#2a2a2a] bg-[#111111] px-6 py-4 text-sm font-mono text-[#888888]">
        <div className="flex items-center gap-3">
          <Loader2 className="h-4 w-4 animate-spin" />
          Loading AI settings...
        </div>
      </div>
    );
  }

  const runtimeRequest = {
    remoteEnabled: formState.remoteEnabled,
    remoteBaseUrl: formState.remoteBaseUrl,
    defaultRemoteModel: formState.defaultRemoteModel,
    taskDefaults: formState.taskDefaults,
    secEdgarUserAgent: formState.secEdgarUserAgent,
  };

  const setTaskRoute = useCallback(
    (task: TaskProfile, updater: (route: AgentTaskRoute) => AgentTaskRoute) => {
      setFormState((current) => ({
        ...current,
        taskDefaults: {
          ...current.taskDefaults,
          [task]: updater(current.taskDefaults[task]),
        },
      }));
    },
    [],
  );

  const saveRuntimeConfig = async () => {
    const nextStatus = await agentSettingsBridge.saveRuntimeConfig(runtimeRequest);
    onStatusChange(nextStatus);
    return nextStatus;
  };

  const handleSaveRuntime = async () => {
    // Validate before save
    const urlValidation = validateUrl(formState.remoteBaseUrl);
    if (!urlValidation.valid) {
      setError(urlValidation.error || 'Please fix validation errors before saving');
      return;
    }

    setIsBusy(true);
    setError(null);
    setSuccess(null);

    try {
      await saveRuntimeConfig();
      setSuccess('Settings saved successfully');
      setInitialState({ ...formState, remoteApiKey: '' });
      setFormState((prev) => ({ ...prev, remoteApiKey: '' }));
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to save settings. Please try again.');
    } finally {
      setIsBusy(false);
    }
  };

  const handleSaveRemoteApiKey = async () => {
    if (!formState.remoteApiKey.trim()) {
      setError('Please enter an API key');
      return;
    }

    setIsBusy(true);
    setError(null);
    setSuccess(null);

    try {
      const savedStatus = await saveRuntimeConfig();
      const nextStatus = await agentSettingsBridge.updateRemoteApiKey({
        apiKey: formState.remoteApiKey,
      });
      onStatusChange({ ...savedStatus, ...nextStatus });
      setFormState((prev) => ({ ...prev, remoteApiKey: '' }));
      setSuccess(status.hasRemoteApiKey ? 'API key updated successfully' : 'API key saved successfully');
      setValidation((prev) => ({ ...prev, apiKey: 'idle' }));
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to save API key. Please try again.');
    } finally {
      setIsBusy(false);
    }
  };

  const handleClearApiKeyClick = () => {
    if (dontAskAgain) {
      handleClearRemoteApiKey();
    } else {
      setShowClearConfirm(true);
    }
  };

  const handleClearRemoteApiKey = async () => {
    setIsBusy(true);
    setError(null);
    setSuccess(null);
    setShowClearConfirm(false);

    try {
      const savedStatus = await saveRuntimeConfig();
      const nextStatus = await agentSettingsBridge.clearRemoteApiKey();
      onStatusChange({ ...savedStatus, ...nextStatus });
      setSuccess('API key cleared successfully');
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to clear API key. Please try again.');
    } finally {
      setIsBusy(false);
    }
  };

  const handleDefaultRemoteModelChange = (nextValue: string) => {
    const previousValue = formState.defaultRemoteModel;
    setFormState((current) => {
      const nextTaskDefaults = { ...current.taskDefaults };
      for (const profile of TASK_PROFILES) {
        if (nextTaskDefaults[profile].model.trim() === previousValue.trim()) {
          nextTaskDefaults[profile] = { model: nextValue };
        }
      }
      return {
        ...current,
        defaultRemoteModel: nextValue,
        taskDefaults: nextTaskDefaults,
      };
    });
  };

  const isFormValid =
    (validation.baseUrl === 'valid' || validation.baseUrl === 'idle') &&
    (validation.secEdgarUserAgent === 'valid' || validation.secEdgarUserAgent === 'idle');

  return (
    <div className="space-y-6">
      {/* Runtime Status Section */}
      <section className="rounded-lg bg-[#0f0f0f] p-6 shadow-sm">
        <div className="mb-5 flex items-center justify-between gap-4">
          <div>
            <h3 className="text-base font-mono font-semibold text-[#e0e0e0]">Runtime Status</h3>
            <p className="mt-1.5 text-xs font-mono text-[#888888]">
              {status.configured ? 'All systems operational' : 'Configuration required'}
            </p>
          </div>
          <div className="text-right text-xs font-mono">
            <div className="flex items-center justify-end gap-2 text-[#888888]">
              <Globe className="h-3.5 w-3.5" />
              <span>Remote ready: {status.remoteConfigured ? 'Yes' : 'No'}</span>
            </div>
            <div className="mt-1 flex items-center justify-end gap-2 text-[#888888]">
              <KeyRound className="h-3.5 w-3.5" />
              <span>API key: {status.hasRemoteApiKey ? 'Stored' : 'Not set'}</span>
            </div>
          </div>
        </div>

        {/* Configuration badge */}
        <div className="flex items-center gap-2">
          <div
            className={`flex items-center gap-2 rounded-md border px-3 py-1.5 text-xs font-mono ${
              status.configured
                ? 'border-[#214f31] bg-[#102417] text-[#9ee6b3]'
                : 'border-[#5c2b2b] bg-[#211313] text-[#ffb4b4]'
            }`}
          >
            {status.configured ? (
              <>
                <CheckCircle className="h-4 w-4" />
                Configured
              </>
            ) : (
              <>
                <AlertTriangle className="h-4 w-4" />
                Needs Configuration
              </>
            )}
          </div>
          {hasUnsavedChanges && (
            <div className="flex items-center gap-2 rounded-md border border-[#3d3420] bg-[#1d170c] px-3 py-1.5 text-xs font-mono text-[#e7bb62]">
              <AlertCircle className="h-4 w-4" />
              Unsaved changes
            </div>
          )}
        </div>
      </section>

      {/* Remote Provider Section */}
      <section className="rounded-lg bg-[#0f0f0f] p-6 shadow-sm">
        <div className="mb-6 flex items-start justify-between gap-4">
          <div className="flex-1">
            <div className="flex items-center gap-2">
              <h3 className="text-base font-mono font-semibold text-[#e0e0e0]">Remote Provider</h3>
              <HelpIcon tooltip="Configure your OpenAI-compatible AI provider endpoint" />
            </div>
            <p className="mt-1.5 text-xs font-mono leading-6 text-[#888888]">
              Connect to an external AI service for enhanced capabilities
            </p>
          </div>
          <label className="flex items-center gap-2 text-xs font-mono text-[#e0e0e0]">
            <input
              type="checkbox"
              checked={formState.remoteEnabled}
              onChange={(e) => setFormState((prev) => ({ ...prev, remoteEnabled: e.target.checked }))}
              className="h-4 w-4 rounded border-[#2a2a2a] bg-[#111111] text-[#58a6ff] focus:ring-2 focus:ring-[#58a6ff] focus:ring-offset-2 focus:ring-offset-[#0f0f0f]"
              aria-describedby="remote-enabled-desc"
            />
            <span id="remote-enabled-desc">Enabled</span>
          </label>
        </div>

        <div className="grid gap-5 md:grid-cols-2">
          <ValidatedInput
            label="Remote Base URL"
            value={formState.remoteBaseUrl}
            onChange={(e) => setFormState((prev) => ({ ...prev, remoteBaseUrl: e.target.value }))}
            placeholder="https://api.example.com/v1"
            validationStatus={validation.baseUrl}
            errorMessage={validation.baseUrlError}
            helperText="The API endpoint URL for your AI provider"
            disabled={isBusy}
            aria-required="true"
          />

          <div>
            <label className="mb-2 block text-xs font-mono text-[#888888]">
              Default Remote Model
            </label>
            <ModelSelector
              value={formState.defaultRemoteModel}
              onChange={handleDefaultRemoteModelChange}
              placeholder="Select a model"
              disabled={isBusy}
            />
            <p className="mt-1.5 text-xs font-mono text-[#888888]">
              Default model used for most tasks
            </p>
          </div>
        </div>
      </section>

      {/* Task Models Section */}
      <section className="rounded-lg bg-[#0f0f0f] p-6 shadow-sm">
        <div className="mb-6">
          <div className="flex items-center gap-2">
            <h3 className="text-base font-mono font-semibold text-[#e0e0e0]">Task-Specific Models</h3>
            <HelpIcon tooltip="Assign different models to specific task types for optimal performance" />
          </div>
          <p className="mt-1.5 text-xs font-mono leading-6 text-[#888888]">
            Customize which model handles each type of task. Inherits from default if not specified.
          </p>
        </div>

        <div className="space-y-4">
          {TASK_PROFILES.map((task) => (
            <div
              key={task}
              className="rounded-lg border border-[#1a1a1a] bg-[#0a0a0a] p-4 transition-colors hover:border-[#2a2a2a]"
            >
              <div className="grid gap-4 md:grid-cols-[200px_minmax(0,1fr)]">
                <div className="text-sm font-mono text-[#e0e0e0]">{TASK_LABELS[task]}</div>
                <div>
                  <label className="sr-only" htmlFor={`model-${task}`}>
                    Model for {TASK_LABELS[task]}
                  </label>
                  <ModelSelector
                    id={`model-${task}`}
                    value={formState.taskDefaults[task].model}
                    onChange={(value) => setTaskRoute(task, () => ({ model: value }))}
                    placeholder={formState.defaultRemoteModel || 'Use default model'}
                    disabled={isBusy}
                  />
                </div>
              </div>
            </div>
          ))}
        </div>

        <div className="mt-6 flex justify-end gap-3">
          {hasUnsavedChanges && (
            <button
              type="button"
              onClick={() => {
                if (initialState) {
                  setFormState({ ...initialState, remoteApiKey: formState.remoteApiKey });
                }
              }}
              className="rounded border border-[#2a2a2a] bg-[#151515] px-4 py-2 text-xs font-mono text-[#888888] transition-colors hover:border-[#3a3a3a] hover:text-[#e0e0e0]"
              disabled={isBusy}
            >
              Discard Changes
            </button>
          )}
          <button
            ref={saveButtonRef}
            type="button"
            onClick={handleSaveRuntime}
            disabled={isBusy || !hasUnsavedChanges || !isFormValid}
            className="flex items-center gap-2 rounded border border-[#58a6ff] bg-[#0f1f31] px-4 py-2 text-xs font-mono text-[#58a6ff] transition-colors hover:bg-[#1a2d3d] disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-[#0f1f31]"
            aria-describedby="save-hint"
          >
            {isBusy ? (
              <>
                <Loader2 className="h-3.5 w-3.5 animate-spin" />
                Saving...
              </>
            ) : (
              <>
                <Save className="h-3.5 w-3.5" />
                Save Settings
              </>
            )}
          </button>
          <span id="save-hint" className="sr-only">
            Save your configuration changes
          </span>
        </div>
      </section>

      {/* API Key Section */}
      <section className="rounded-lg bg-[#0f0f0f] p-6 shadow-sm">
        <div className="mb-5">
          <div className="flex items-center gap-2">
            <h3 className="text-base font-mono font-semibold text-[#e0e0e0]">API Key</h3>
            <HelpIcon tooltip="Your API key is stored securely and used to authenticate with the remote provider" />
          </div>
          <p className="mt-1.5 text-xs font-mono leading-6 text-[#888888]">
            Authentication credential for your AI provider
          </p>
        </div>

        <div className="space-y-4">
          <div className="relative">
            <ValidatedInput
              label={status.hasRemoteApiKey ? 'Update API Key' : 'API Key'}
              type={showApiKey ? 'text' : 'password'}
              value={formState.remoteApiKey}
              onChange={(e) => setFormState((prev) => ({ ...prev, remoteApiKey: e.target.value }))}
              placeholder="Enter your API key"
              validationStatus={validation.apiKey}
              helperText={
                status.hasRemoteApiKey && !formState.remoteApiKey
                  ? 'A remote API key is currently stored.'
                  : 'Required for API requests'
              }
              disabled={isBusy}
              fullWidth
              className="pr-20"
            />
            <button
              type="button"
              onClick={() => setShowApiKey(!showApiKey)}
              className="absolute right-3 top-[2.1rem] text-[#666666] transition-colors hover:text-[#58a6ff] focus:outline-none focus:ring-2 focus:ring-[#58a6ff] focus:ring-offset-2 focus:ring-offset-[#0f0f0f]"
              aria-label={showApiKey ? 'Hide API key' : 'Show API key'}
              aria-pressed={showApiKey}
            >
              {showApiKey ? (
                <EyeOff className="h-5 w-5" />
              ) : (
                <Eye className="h-5 w-5" />
              )}
            </button>
          </div>

          <div className="flex flex-wrap justify-between gap-3">
            <div>
              {status.hasRemoteApiKey && (
                <button
                  type="button"
                  onClick={handleClearApiKeyClick}
                  disabled={isBusy}
                  className="flex items-center gap-2 rounded border border-[#3d2b2b] bg-[#1a1212] px-4 py-2 text-xs font-mono text-[#ff7b72] transition-colors hover:border-[#ff7b72] hover:bg-[#2d1a1a] disabled:cursor-not-allowed disabled:opacity-50"
                >
                  <XCircle className="h-3.5 w-3.5" />
                  Clear Key
                </button>
              )}
            </div>
            <button
              type="button"
              onClick={handleSaveRemoteApiKey}
              disabled={isBusy || !formState.remoteApiKey.trim()}
              className="rounded border border-[#58a6ff] bg-[#0f1f31] px-4 py-2 text-xs font-mono text-[#58a6ff] transition-colors hover:bg-[#1a2d3d] disabled:cursor-not-allowed disabled:opacity-50"
            >
              {isBusy ? (
                'Saving...'
              ) : status.hasRemoteApiKey ? (
                'Update API Key'
              ) : (
                'Save API Key'
              )}
            </button>
          </div>
        </div>
      </section>

      {/* Success Message */}
      {success && (
        <div
          className="flex items-center gap-3 rounded-lg border border-[#214f31] bg-[#102417] px-4 py-3 text-sm font-mono text-[#9ee6b3]"
          role="alert"
          aria-live="polite"
        >
          <CheckCircle className="h-5 w-5" aria-hidden="true" />
          <div className="flex-1">{success}</div>
          <button
            type="button"
            onClick={() => setSuccess(null)}
            className="text-[#9ee6b3] opacity-60 transition-opacity hover:opacity-100"
            aria-label="Dismiss success message"
          >
            <XCircle className="h-4 w-4" />
          </button>
        </div>
      )}

      {/* Error Message */}
      {error && (
        <div
          className="flex items-center gap-3 rounded-lg border border-[#5c2b2b] bg-[#211313] px-4 py-3 text-sm font-mono text-[#ffb4b4]"
          role="alert"
          aria-live="assertive"
        >
          <XCircle className="h-5 w-5" aria-hidden="true" />
          <div className="flex-1">{error}</div>
          <button
            type="button"
            onClick={() => setError(null)}
            className="text-[#ffb4b4] opacity-60 transition-opacity hover:opacity-100"
            aria-label="Dismiss error message"
          >
            <XCircle className="h-4 w-4" />
          </button>
        </div>
      )}

      {/* Confirmation Dialog */}
      <ConfirmDialog
        isOpen={showClearConfirm}
        title="Clear API Key?"
        message="This will remove your stored API key. You'll need to enter it again to use the remote provider. This action cannot be undone."
        confirmLabel="Clear Key"
        cancelLabel="Cancel"
        variant="danger"
        onConfirm={handleClearRemoteApiKey}
        onCancel={() => setShowClearConfirm(false)}
        showDontAskAgain
        onDontAskAgainChange={setDontAskAgain}
      />
    </div>
  );
};
