import { useCallback, useEffect, useMemo, useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import apiClient from '../api/client';
import { useBusiness } from '../context/BusinessContext';

const BASE_PROFILE_KEYS = new Set(['providerName', 'senderId', 'dltEntityId']);
const PENDING_SENDER_ID_PROFILE_NAME = 'Pending Sender ID';

function formatUpdatedAt(value) {
  if (!value) return 'Not updated yet';

  try {
    return new Date(value).toLocaleString();
  } catch {
    return 'Not updated yet';
  }
}

function buildProfilePatchPayload(inputs = [], values = {}) {
  const provider = {};
  const profileInputValues = {};

  inputs.forEach((input) => {
    const rawValue = String(values[input.key] ?? '').trim();
    if (!rawValue) return;

    if (BASE_PROFILE_KEYS.has(input.key)) {
      provider[input.key] = input.key === 'senderId' ? rawValue.toUpperCase() : rawValue;
      return;
    }

    profileInputValues[input.key] = rawValue;
  });

  return {
    ...(Object.keys(provider).length > 0 ? { provider } : {}),
    ...(Object.keys(profileInputValues).length > 0 ? { profileInputValues } : {}),
  };
}

function getInputInitialValues(inputs = []) {
  return inputs.reduce((accumulator, input) => {
    accumulator[input.key] = input.value || '';
    return accumulator;
  }, {});
}

function getProfileSummary(profile) {
  const parts = [];
  const provider = profile?.provider || {};
  const missingCount = profile?.executionReadiness?.missingProfileInputs?.length || 0;

  if (provider.providerName) parts.push(provider.providerName);
  if (provider.senderId) parts.push(`Sender ${provider.senderId}`);
  if (provider.dltEntityId) parts.push('DLT ready');
  if (missingCount > 0) parts.push(`${missingCount} required field${missingCount === 1 ? '' : 's'} pending`);

  return parts.join(' • ') || 'Profile saved. Complete the remaining setup fields to continue.';
}

function isPendingSenderIdProfile(profile) {
  const normalizedName = String(profile?.name || '').trim();
  const senderId = String(profile?.provider?.senderId || '').trim();
  return (profile?.isAutoNamed === true && !senderId) || normalizedName === PENDING_SENDER_ID_PROFILE_NAME;
}

function DeleteProfileModal({ preview, deleting, onCancel, onConfirm }) {
  if (!preview) return null;

  const impactedTemplates = Array.isArray(preview.impactedTemplates) ? preview.impactedTemplates : [];

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-gray-900/55 p-4 backdrop-blur-sm">
      <div className="w-full max-w-xl rounded-2xl border border-gray-200 bg-white shadow-xl">
        <div className="border-b border-gray-200 px-6 py-5">
          <h3 className="text-lg font-bold text-gray-900">Delete cURL Profile</h3>
          <p className="mt-1 text-sm text-gray-500">
            {preview.profile?.name || 'This profile'} will be deleted. Bound templates will be removed, but event definitions will stay.
          </p>
        </div>

        <div className="space-y-4 px-6 py-5">
          {impactedTemplates.length > 0 ? (
            <>
              <p className="text-sm font-semibold text-gray-900">Affected templates</p>
              <div className="max-h-72 space-y-3 overflow-y-auto">
                {impactedTemplates.map((template) => (
                  <div key={`${template.eventSlug}-${template.status}`} className="rounded-xl border border-gray-200 bg-gray-50 px-4 py-3">
                    <div className="flex items-center justify-between gap-3">
                      <p className="font-medium text-gray-900">{template.eventLabel || template.eventSlug}</p>
                      <span className="rounded-full border border-gray-200 bg-white px-2.5 py-1 text-[11px] font-semibold uppercase tracking-[0.14em] text-gray-500">
                        {template.status || 'generated'}
                      </span>
                    </div>
                    {template.templateId && (
                      <p className="mt-2 font-mono text-xs text-gray-500">DLT Template ID: {template.templateId}</p>
                    )}
                  </div>
                ))}
              </div>
            </>
          ) : (
            <div className="rounded-xl border border-gray-200 bg-gray-50 px-4 py-3 text-sm text-gray-600">
              No templates are currently bound to this profile.
            </div>
          )}
        </div>

        <div className="flex gap-3 border-t border-gray-200 px-6 py-4">
          <button
            type="button"
            onClick={onCancel}
            disabled={deleting}
            className="flex-1 rounded-lg border border-gray-300 px-4 py-2 text-sm font-semibold text-gray-700 transition hover:bg-gray-50 disabled:opacity-50"
          >
            Cancel
          </button>
          <button
            type="button"
            onClick={onConfirm}
            disabled={deleting}
            className="flex-1 rounded-lg bg-red-600 px-4 py-2 text-sm font-semibold text-white transition hover:bg-red-700 disabled:opacity-50"
          >
            {deleting ? 'Deleting…' : 'Delete Profile'}
          </button>
        </div>
      </div>
    </div>
  );
}

export default function GlobalSms() {
  const { businessId } = useParams();
  const navigate = useNavigate();
  const { isSetupComplete, setHasGlobalSms, setIsSetupComplete } = useBusiness();
  const [loading, setLoading] = useState(true);
  const [profiles, setProfiles] = useState([]);
  const [activeProfileId, setActiveProfileId] = useState(null);
  const [saving, setSaving] = useState(false);
  const [savingInputs, setSavingInputs] = useState(false);
  const [error, setError] = useState('');
  const [success, setSuccess] = useState('');
  const [formCurl, setFormCurl] = useState('');
  const [formSetActive, setFormSetActive] = useState(true);
  const [inputForm, setInputForm] = useState({});
  const [revealedProfiles, setRevealedProfiles] = useState({});
  const [visibleProfileIds, setVisibleProfileIds] = useState({});
  const [deletePreview, setDeletePreview] = useState(null);
  const [deletingProfileId, setDeletingProfileId] = useState('');

  const activeProfile = useMemo(
    () => profiles.find((profile) => profile.id === activeProfileId) || null,
    [profiles, activeProfileId],
  );
  const missingInputs = useMemo(
    () => activeProfile?.executionReadiness?.missingProfileInputs || [],
    [activeProfile?.executionReadiness?.missingProfileInputs],
  );
  const hasProfiles = profiles.length > 0;
  const eventsPath = `/${businessId}/events`;

  const loadProfiles = useCallback(async () => {
    try {
      setLoading(true);
      const res = await apiClient.get(`/api/businesses/${businessId}/global-sms/profiles`);
      const fetchedProfiles = res.data?.profiles || [];
      const nextActiveProfileId = res.data?.activeProfileId || null;
      const nextActiveProfile = fetchedProfiles.find((profile) => profile.id === nextActiveProfileId) || null;
      const nextIsSetupComplete = nextActiveProfile?.executionReadiness?.isSetupComplete === true;

      setProfiles(fetchedProfiles);
      setActiveProfileId(nextActiveProfileId);
      setHasGlobalSms(fetchedProfiles.length > 0);
      setIsSetupComplete(nextIsSetupComplete);

      return {
        activeProfile: nextActiveProfile,
        hasProfile: !!nextActiveProfile,
        complete: nextIsSetupComplete,
      };
    } catch {
      setError('Failed to load cURL profiles');
      setHasGlobalSms(false);
      setIsSetupComplete(false);
      return { activeProfile: null, hasProfile: false, complete: false };
    } finally {
      setLoading(false);
    }
  }, [businessId, setHasGlobalSms, setIsSetupComplete]);

  useEffect(() => {
    loadProfiles();
  }, [loadProfiles]);

  useEffect(() => {
    setInputForm(getInputInitialValues(missingInputs));
  }, [activeProfileId, missingInputs]);

  const ensureRevealData = useCallback(async (profileId) => {
    if (revealedProfiles[profileId]) return revealedProfiles[profileId];

    const res = await apiClient.get(`/api/businesses/${businessId}/global-sms/profiles/${profileId}/reveal`);
    setRevealedProfiles((current) => ({ ...current, [profileId]: res.data }));
    return res.data;
  }, [businessId, revealedProfiles]);

  async function handleSubmit(event) {
    event.preventDefault();
    if (!formCurl.trim()) return;

    setSaving(true);
    setError('');
    setSuccess('');
    const shouldAutoAdvance = !isSetupComplete;

    try {
      await apiClient.post(`/api/businesses/${businessId}/global-sms/profiles`, {
        rawCurl: formCurl.trim(),
        setActive: formSetActive,
      });

      setFormCurl('');
      setFormSetActive(true);
      setSuccess('Profile created successfully.');

      const nextState = await loadProfiles();
      if (shouldAutoAdvance && nextState.complete) {
        navigate(eventsPath);
      }
    } catch (err) {
      setError(err.response?.data?.error || 'Failed to save cURL profile');
    } finally {
      setSaving(false);
    }
  }

  async function handleActivate(profileId) {
    const shouldAutoAdvance = !isSetupComplete;
    setError('');
    setSuccess('');

    try {
      await apiClient.post(`/api/businesses/${businessId}/global-sms/profiles/${profileId}/activate`);
      const nextState = await loadProfiles();
      setSuccess('Active profile updated.');
      if (shouldAutoAdvance && nextState.complete) {
        navigate(eventsPath);
      }
    } catch (err) {
      setError(err.response?.data?.error || 'Failed to activate profile');
    }
  }

  async function handleCopyCurl(profile) {
    try {
      const revealData = await ensureRevealData(profile.id);
      const textToCopy = revealData?.rawCurl || profile.maskedCurl || '';
      if (!textToCopy) return;

      await navigator.clipboard.writeText(textToCopy);
      setSuccess(`Copied ${profile.name} cURL.`);
    } catch {
      setError('Failed to copy the cURL command.');
    }
  }

  async function handleToggleCurl(profile) {
    setError('');

    if (!visibleProfileIds[profile.id]) {
      try {
        await ensureRevealData(profile.id);
      } catch (err) {
        setError(err.response?.data?.error || 'Failed to reveal stored cURL');
        return;
      }
    }

    setVisibleProfileIds((current) => ({
      ...current,
      [profile.id]: !current[profile.id],
    }));
  }

  async function handleProviderSubmit(event) {
    event.preventDefault();
    if (!activeProfileId || missingInputs.length === 0) return;

    setSavingInputs(true);
    setError('');
    setSuccess('');
    const shouldAutoAdvance = !isSetupComplete;

    try {
      const payload = buildProfilePatchPayload(missingInputs, inputForm);
      await apiClient.patch(`/api/businesses/${businessId}/global-sms/profiles/${activeProfileId}`, payload);
      setSuccess('Required profile fields saved.');
      const nextState = await loadProfiles();
      if (shouldAutoAdvance && nextState.complete) {
        navigate(eventsPath);
      }
    } catch (err) {
      setError(err.response?.data?.error || 'Failed to save required profile fields');
    } finally {
      setSavingInputs(false);
    }
  }

  async function handleDeleteRequest(profile) {
    setError('');
    setSuccess('');

    try {
      const res = await apiClient.get(`/api/businesses/${businessId}/global-sms/profiles/${profile.id}/delete-impact`);
      setDeletePreview(res.data);
    } catch (err) {
      setError(err.response?.data?.error || 'Failed to load delete impact');
    }
  }

  async function handleDeleteConfirm() {
    if (!deletePreview?.profile?.id) return;

    setDeletingProfileId(deletePreview.profile.id);
    setError('');
    setSuccess('');

    try {
      await apiClient.delete(`/api/businesses/${businessId}/global-sms/profiles/${deletePreview.profile.id}`);
      setDeletePreview(null);
      setVisibleProfileIds((current) => {
        const nextState = { ...current };
        delete nextState[deletePreview.profile.id];
        return nextState;
      });
      setRevealedProfiles((current) => {
        const nextState = { ...current };
        delete nextState[deletePreview.profile.id];
        return nextState;
      });
      await loadProfiles();
      setSuccess('Profile deleted successfully.');
    } catch (err) {
      setError(err.response?.data?.error || 'Failed to delete profile');
    } finally {
      setDeletingProfileId('');
    }
  }

  if (loading) {
    return (
      <div className="flex h-64 items-center justify-center">
        <span className="h-8 w-8 animate-spin rounded-full border-4 border-spinner-track border-t-primary-blue" />
      </div>
    );
  }

  return (
    <>
      <DeleteProfileModal
        preview={deletePreview}
        deleting={deletingProfileId === deletePreview?.profile?.id}
        onCancel={() => setDeletePreview(null)}
        onConfirm={handleDeleteConfirm}
      />

      <div className="mx-auto max-w-4xl space-y-8 pb-12">
        <div>
          <h2 className="mb-2 text-2xl font-bold text-text-primary">Omni-channel SMS</h2>
          <p className="text-sm text-text-muted">
            Add and activate a validated provider cURL, complete the required profile fields, and then continue to event template setup.
          </p>
        </div>

        {error && (
          <div className="flex items-center justify-between rounded-md border border-gray-200 bg-white px-4 py-2 text-sm font-medium text-error-text">
            {error}
            <button type="button" onClick={() => setError('')} className="font-bold text-error-text hover:text-red-900">
              &times;
            </button>
          </div>
        )}

        {success && (
          <div className="flex items-center justify-between rounded-md border border-gray-200 bg-white px-4 py-2 text-sm font-medium text-gray-700">
            {success}
            <button type="button" onClick={() => setSuccess('')} className="font-bold text-gray-700 hover:opacity-75">
              &times;
            </button>
          </div>
        )}

        {activeProfile ? (
          <div className={`rounded-lg border p-5 ${activeProfile.executionReadiness?.isSetupComplete ? 'border-primary-blue bg-white' : 'border-gray-200 bg-white'}`}>
            <div className="mb-4 flex items-center gap-3">
              <h3 className="text-lg font-bold text-text-primary">
                Active Setup:{' '}
                <span className={isPendingSenderIdProfile(activeProfile) ? 'text-error-text' : 'text-text-primary'}>
                  {activeProfile.name}
                </span>
              </h3>
              <span className="rounded-full border border-gray-200 bg-white px-3 py-1 text-xs font-bold uppercase tracking-wide text-gray-700">
                {activeProfile.executionReadiness?.isSetupComplete ? 'Setup Complete' : 'Missing Information'}
              </span>
            </div>

            <div className="grid gap-5 md:grid-cols-2">
              <div className="space-y-3">
                <p className="text-sm font-medium text-text-primary">Current Profile Summary</p>
                <ul className="space-y-2 text-sm">
                  <li className="flex items-center justify-between rounded border border-border-soft bg-surface-white p-2">
                    <span className="text-text-muted">Provider</span>
                    <span className="font-bold text-text-primary">
                      {activeProfile.provider?.providerName || <span className="text-xs uppercase text-error-text">Missing</span>}
                    </span>
                  </li>
                  <li className="flex items-center justify-between rounded border border-border-soft bg-surface-white p-2">
                    <span className="text-text-muted">Sender ID</span>
                    <span className="font-bold text-text-primary">
                      {activeProfile.provider?.senderId || <span className="text-xs uppercase text-error-text">Missing</span>}
                    </span>
                  </li>
                  <li className="flex items-center justify-between rounded border border-border-soft bg-surface-white p-2">
                    <span className="text-text-muted">DLT Entity ID</span>
                    <span className="font-bold text-text-primary">
                      {activeProfile.provider?.dltEntityId || <span className="text-xs uppercase text-error-text">Missing</span>}
                    </span>
                  </li>
                  <li className="rounded border border-border-soft bg-surface-white p-3">
                    <p className="text-xs font-semibold uppercase tracking-wide text-text-muted">Setup Status</p>
                    <p className="mt-2 text-sm text-text-primary">{getProfileSummary(activeProfile)}</p>
                  </li>
                </ul>
              </div>

              {!activeProfile.executionReadiness?.isSetupComplete ? (
                <div className="rounded-lg border border-border-main bg-surface-white p-4">
                  <p className="mb-3 text-sm font-semibold text-text-primary">Complete the required fields</p>
                  <form onSubmit={handleProviderSubmit} className="space-y-3">
                    {missingInputs.map((input) => (
                      <div key={input.key}>
                        <label className="mb-1.5 block text-sm font-semibold text-text-primary">{input.label}</label>
                        <input
                          type={input.secret ? 'password' : 'text'}
                          value={inputForm[input.key] || ''}
                          onChange={(event) => setInputForm((current) => ({
                            ...current,
                            [input.key]: input.key === 'senderId'
                              ? event.target.value.toUpperCase()
                              : event.target.value,
                          }))}
                          className="w-full rounded border border-border-main bg-page-bg px-3 py-2 text-sm text-text-primary focus:ring-1 focus:ring-primary-blue"
                          placeholder={input.label}
                          required={input.required !== false}
                        />
                      </div>
                    ))}
                    <button
                      type="submit"
                      disabled={savingInputs || missingInputs.some((input) => !String(inputForm[input.key] || '').trim())}
                      className="w-full rounded bg-primary-blue py-2 text-sm font-bold text-white transition hover:bg-primary-dark disabled:opacity-50"
                    >
                      {savingInputs ? 'Saving...' : 'Save Required Details'}
                    </button>
                  </form>
                </div>
              ) : (
                <div className="flex h-full flex-col items-center justify-center space-y-4">
                  <p className="text-center text-sm font-medium text-text-muted">Your active cURL profile is fully configured.</p>
                  <button
                    type="button"
                    onClick={() => navigate(eventsPath)}
                    className="w-full rounded-lg bg-primary-blue px-6 py-2 text-sm font-semibold text-white transition hover:bg-primary-dark"
                  >
                    Continue to Events →
                  </button>
                </div>
              )}
            </div>
          </div>
        ) : hasProfiles ? (
          <div className="rounded-lg border border-amber-200 bg-amber-50 p-4 text-sm text-amber-800">
            Select an active cURL profile to continue. Your saved profiles are still available below.
          </div>
        ) : null}

        {hasProfiles && (
          <div className="space-y-4 border-t border-border-soft pt-4">
            <h3 className="text-lg font-bold text-text-primary">Saved Profiles</h3>
            {profiles.map((profile) => {
              const isActive = profile.id === activeProfileId;
              const isVisible = visibleProfileIds[profile.id] === true;
              const revealedProfile = revealedProfiles[profile.id];
              const displayCurl = isVisible ? (revealedProfile?.rawCurl || profile.maskedCurl) : profile.maskedCurl;

              return (
                <div
                  key={profile.id}
                  className={`rounded-xl border p-5 transition-colors ${isActive ? 'border-primary-blue bg-white' : 'border-border-main bg-surface-white'}`}
                >
                  <div className="flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
                    <div className="min-w-0 flex-1">
                      <div className="mb-3 flex flex-wrap items-center gap-3">
                        <h3 className={`truncate text-base font-bold ${isPendingSenderIdProfile(profile) ? 'text-error-text' : 'text-text-primary'}`}>{profile.name}</h3>
                        {isActive && (
                          <span className="rounded-full border border-indigo-200 bg-indigo-50 px-2.5 py-1 text-[11px] font-bold uppercase tracking-wider text-primary-dark">
                            Active Profile
                          </span>
                        )}
                        <span className={`rounded-full border px-2.5 py-1 text-[11px] font-bold uppercase tracking-wider ${profile.executionReadiness?.isSetupComplete ? 'border-emerald-200 bg-emerald-50 text-emerald-700' : 'border-amber-200 bg-amber-50 text-amber-700'}`}>
                          {profile.executionReadiness?.isSetupComplete ? 'Ready' : 'Needs Fields'}
                        </span>
                      </div>
                      <p className="mb-2 text-xs font-medium text-text-muted">Updated: {formatUpdatedAt(profile.updatedAt)}</p>
                      <p className="mb-3 text-sm text-text-muted">{getProfileSummary(profile)}</p>
                      <div className="overflow-hidden rounded-xl border border-gray-200 bg-gray-950">
                        <div className="flex items-center justify-between border-b border-gray-800 px-4 py-2">
                          <p className="text-[11px] font-semibold uppercase tracking-[0.18em] text-gray-400">Stored cURL</p>
                          <button
                            type="button"
                            onClick={() => handleToggleCurl(profile)}
                            className="text-xs font-semibold text-gray-300 transition hover:text-white"
                          >
                            {isVisible ? 'Hide' : 'Show'}
                          </button>
                        </div>
                        <pre className="max-h-56 overflow-auto px-4 py-4 text-xs leading-relaxed text-gray-100">
                          <code>{displayCurl || 'No cURL stored.'}</code>
                        </pre>
                      </div>
                    </div>

                    <div className="flex shrink-0 flex-wrap items-center gap-2 lg:justify-end">
                      {!isActive && (
                        <button
                          type="button"
                          onClick={() => handleActivate(profile.id)}
                          className="rounded-lg bg-primary-blue px-4 py-2 text-sm font-semibold text-white transition hover:bg-primary-dark"
                        >
                          Use this cURL
                        </button>
                      )}
                      <button
                        type="button"
                        onClick={() => handleCopyCurl(profile)}
                        className="rounded-lg border border-border-main px-3 py-2 text-sm font-medium text-text-muted transition hover:border-primary-blue hover:bg-page-bg hover:text-primary-blue"
                      >
                        Copy
                      </button>
                      <button
                        type="button"
                        onClick={() => handleDeleteRequest(profile)}
                        className="rounded-lg border border-border-main px-3 py-2 text-sm font-medium text-text-muted transition hover:border-error-text hover:bg-red-50 hover:text-error-text"
                      >
                        Delete
                      </button>
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
        )}

        <div className={`overflow-hidden rounded-xl border ${!hasProfiles ? 'border-indigo-100 bg-white shadow-sm' : 'border-border-main bg-surface-white'}`}>
          <div className={`flex items-start justify-between gap-4 px-6 py-5 ${!hasProfiles ? 'border-b border-indigo-100 bg-indigo-50/60' : 'border-b border-border-main bg-table-header'}`}>
            <div>
              <h3 className="text-md font-bold text-text-primary">Add New Profile</h3>
              <p className="mt-1 text-sm text-text-muted">
                Paste a provider cURL exactly once. After validation, the stored cURL becomes immutable and can only be replaced by creating a new profile.
              </p>
            </div>
          </div>

          <div className="p-6">
            {!hasProfiles && (
              <div className="mb-6 rounded-xl border border-indigo-100 bg-indigo-50/50 px-4 py-4">
                <p className="text-sm font-semibold text-text-primary">Start by adding a cURL profile</p>
                <p className="mt-1 text-sm text-text-muted">
                  This becomes the base for validating provider details and unlocking event template generation.
                </p>
              </div>
            )}

            <form onSubmit={handleSubmit} className="space-y-5">
              <div>
                <label className="mb-1.5 block text-sm font-semibold text-text-primary">Provider cURL Command</label>
                <textarea
                  value={formCurl}
                  onChange={(event) => setFormCurl(event.target.value)}
                  placeholder="curl --request POST --url ..."
                  className="h-48 w-full resize-none rounded-lg border border-border-main bg-white px-4 py-3 font-mono text-sm leading-relaxed text-text-primary transition focus:outline-none focus:ring-2 focus:ring-primary-blue"
                  required
                  spellCheck="false"
                />
                <p className="mt-2 text-xs font-medium text-text-muted">
                  Profile name is generated automatically from Sender ID. If Sender ID is not detected yet, it stays as <span className="text-error-text">{PENDING_SENDER_ID_PROFILE_NAME}</span> until completed.
                </p>
              </div>

              <label className="flex cursor-pointer items-center gap-2">
                <input
                  type="checkbox"
                  className="h-4 w-4 rounded border-border-main text-primary-blue focus:ring-primary-blue"
                  checked={formSetActive}
                  onChange={(event) => setFormSetActive(event.target.checked)}
                />
                <span className="text-sm font-semibold text-text-primary">Set as active profile immediately</span>
              </label>

              <div className="flex gap-3 pt-2">
                <button
                  type="submit"
                  disabled={saving}
                  className="flex items-center justify-center gap-2 rounded-lg bg-primary-blue px-6 py-2 text-sm font-semibold text-white transition hover:bg-primary-dark disabled:opacity-50"
                >
                  {saving ? 'Saving…' : 'Save Profile'}
                </button>
              </div>
            </form>
          </div>
        </div>
      </div>
    </>
  );
}
