"use client";

import Link from "next/link";
import { useReducer, useEffect } from "react";
import AIProviderPanel from "@/components/admin/AIProviderPanel";
import { savePaymentSettings } from "@/actions/payments";
import {
  saveResendCredentials,
  saveTwilioCredentials,
  testResendConnection,
  testTwilioConnection,
  getResendCredentials,
  getTwilioCredentials,
} from "@/actions/integrations/credentials";
import { AdminInput, AdminTextInput, AdminSelect, AdminButton } from "@/components/admin/design-system";

type Props = {
  brandId: string;
  brands: { id: string; name: string }[];
  isPlatformAdmin: boolean;
};

type CredentialField = {
  key: string;
  label: string;
  placeholder: string;
  isSecret?: boolean;
};

type Integration = {
  id: string;
  name: string;
  icon: string;
  description: string;
  accentColor: string;
  credentials: CredentialField[];
  connected?: boolean;
};

// Integration cards configured below. AI is handled by AIProviderPanel
// and Stripe/Resend/Twilio each render their own IntegrationCard.
const INTEGRATIONS: Integration[] = [
  {
    id: "openai",
    name: "OpenAI",
    icon: "🤖",
    description: "Power AI tools like Campaign Writer, Report Explainer, and Pricing Advisor.",
    accentColor: "border-violet-200 bg-violet-50/50",
    credentials: [],
  },
  {
    id: "resend",
    name: "Resend",
    icon: "📧",
    description: "Send transactional and marketing emails via Harvest Reach.",
    accentColor: "border-amber-200 bg-amber-50/50",
    credentials: [
      { key: "RESEND_API_KEY", label: "API Key", placeholder: "re_...", isSecret: true },
      { key: "RESEND_FROM_EMAIL", label: "From Email Address", placeholder: "orders@yourbrand.com" },
      { key: "RESEND_FROM_NAME", label: "From Name", placeholder: "Your Brand Name" },
    ],
  },
  {
    id: "stripe",
    name: "Stripe",
    icon: "💳",
    description: "Process online payments for orders.",
    accentColor: "border-stone-200 bg-stone-50/50",
    credentials: [
      { key: "STRIPE_PUBLISHABLE_KEY", label: "Publishable Key", placeholder: "pk_live_..." },
      { key: "STRIPE_SECRET_KEY", label: "Secret Key", placeholder: "sk_live_...", isSecret: true },
    ],
  },
  {
    id: "twilio",
    name: "Twilio",
    icon: "📱",
    description: "Send SMS campaigns and alerts via Harvest Reach.",
    accentColor: "border-blue-200 bg-blue-50/50",
    credentials: [
      { key: "TWILIO_ACCOUNT_SID", label: "Account SID", placeholder: "AC..." },
      { key: "TWILIO_AUTH_TOKEN", label: "Auth Token", placeholder: "Your Twilio auth token", isSecret: true },
      { key: "TWILIO_PHONE_NUMBER", label: "Phone Number", placeholder: "+1234567890" },
    ],
  },
];

const INTEGRATIONS_WITHOUT_OPENAI: Integration[] = INTEGRATIONS.filter(
  (i) => i.id !== "openai"
);

type CardState = {
  credentials: Record<string, string>;
  showSecrets: Record<string, boolean>;
  testResult: { ok: boolean; message: string } | null;
  saving: boolean;
  saved: boolean;
  error: string | null;
};

type CardAction =
  | { type: "SET_CREDENTIAL"; key: string; value: string }
  | { type: "TOGGLE_SECRET"; key: string }
  | { type: "SET_TEST_RESULT"; value: { ok: boolean; message: string } | null }
  | { type: "SET_SAVING"; value: boolean }
  | { type: "SET_SAVED"; value: boolean }
  | { type: "SET_ERROR"; value: string | null }
  | { type: "CLEAR_TEST_AND_ERROR" };

const initialCardState: CardState = {
  credentials: {},
  showSecrets: {},
  testResult: null,
  saving: false,
  saved: false,
  error: null,
};

function cardReducer(state: CardState, action: CardAction): CardState {
  switch (action.type) {
    case "SET_CREDENTIAL":
      return { ...state, credentials: { ...state.credentials, [action.key]: action.value } };
    case "TOGGLE_SECRET":
      return { ...state, showSecrets: { ...state.showSecrets, [action.key]: !state.showSecrets[action.key] } };
    case "SET_TEST_RESULT":
      return { ...state, testResult: action.value };
    case "SET_SAVING":
      return { ...state, saving: action.value };
    case "SET_SAVED":
      return { ...state, saved: action.value };
    case "SET_ERROR":
      return { ...state, error: action.value };
    case "CLEAR_TEST_AND_ERROR":
      return { ...state, testResult: null, error: null };
  }
}

function IntegrationCard({
  integration,
  initialCredentials,
  brandId,
}: {
  integration: Integration;
  initialCredentials?: Record<string, string>;
  brandId: string;
}) {
  const [state, dispatch] = useReducer(cardReducer, {
    ...initialCardState,
    credentials: initialCredentials ?? {},
  });

  // Derived from `credentials` + `initialCredentials` during render so we
  // don't pay for an extra commit and stale-frame window.
  const hasValues = Object.values(state.credentials).some((v) => v.trim().length > 0);
  const dirty = hasValues && JSON.stringify(initialCredentials) !== JSON.stringify(state.credentials);

  async function handleTest() {
    dispatch({ type: "CLEAR_TEST_AND_ERROR" });

    if (integration.id === "resend") {
      const apiKey = state.credentials["RESEND_API_KEY"];
      if (!apiKey?.trim()) {
        dispatch({ type: "SET_TEST_RESULT", value: { ok: false, message: "API key is required" } });
        return;
      }
      const result = await testResendConnection(apiKey);
      dispatch({ type: "SET_TEST_RESULT", value: result });
    } else if (integration.id === "twilio") {
      const accountSid = state.credentials["TWILIO_ACCOUNT_SID"];
      const authToken = state.credentials["TWILIO_AUTH_TOKEN"];
      if (!accountSid?.trim() || !authToken?.trim()) {
        dispatch({ type: "SET_TEST_RESULT", value: { ok: false, message: "Account SID and Auth Token are required" } });
        return;
      }
      const result = await testTwilioConnection(accountSid, authToken);
      dispatch({ type: "SET_TEST_RESULT", value: result });
    } else {
      // Default test (placeholder)
      await new Promise((r) => setTimeout(r, 500));
      const hasKey = Object.values(state.credentials).some((v) => v.trim().length > 0);
      dispatch({
        type: "SET_TEST_RESULT",
        value: hasKey
          ? { ok: true, message: `Successfully connected to ${integration.name}` }
          : { ok: false, message: `No API key configured for ${integration.name}` },
      });
    }
  }

  async function handleSave() {
    dispatch({ type: "SET_SAVING", value: true });
    dispatch({ type: "CLEAR_TEST_AND_ERROR" });

    try {
      if (integration.id === "resend") {
        const result = await saveResendCredentials(brandId, {
          api_key: state.credentials["RESEND_API_KEY"]?.trim() || null,
          from_email: state.credentials["RESEND_FROM_EMAIL"]?.trim() || null,
          from_name: state.credentials["RESEND_FROM_NAME"]?.trim() || null,
        });
        if (!result.success) {
          dispatch({ type: "SET_ERROR", value: result.error ?? "Failed to save" });
          return;
        }
        dispatch({ type: "SET_TEST_RESULT", value: { ok: true, message: "Resend credentials saved successfully" } });
        dispatch({ type: "SET_SAVED", value: true });
        window.setTimeout(() => dispatch({ type: "SET_SAVED", value: false }), 3000);
      } else if (integration.id === "twilio") {
        const result = await saveTwilioCredentials(brandId, {
          account_sid: state.credentials["TWILIO_ACCOUNT_SID"]?.trim() || null,
          auth_token: state.credentials["TWILIO_AUTH_TOKEN"]?.trim() || null,
          phone_number: state.credentials["TWILIO_PHONE_NUMBER"]?.trim() || null,
        });
        if (!result.success) {
          dispatch({ type: "SET_ERROR", value: result.error ?? "Failed to save" });
          return;
        }
        dispatch({ type: "SET_TEST_RESULT", value: { ok: true, message: "Twilio credentials saved successfully" } });
        dispatch({ type: "SET_SAVED", value: true });
        window.setTimeout(() => dispatch({ type: "SET_SAVED", value: false }), 3000);
      } else if (integration.id === "stripe") {
        const result = await savePaymentSettings({
          brandId,
          provider: "stripe",
          stripePublishableKey: state.credentials["STRIPE_PUBLISHABLE_KEY"]?.trim() || undefined,
          stripeSecretKey: state.credentials["STRIPE_SECRET_KEY"]?.trim() || undefined,
        });
        if (!result.success) {
          dispatch({ type: "SET_ERROR", value: result.error ?? "Failed to save" });
          return;
        }
        dispatch({ type: "SET_TEST_RESULT", value: { ok: true, message: "Stripe credentials saved successfully" } });
        dispatch({ type: "SET_SAVED", value: true });
        window.setTimeout(() => dispatch({ type: "SET_SAVED", value: false }), 3000);
      } else {
        // Other integrations - just show success for now
        dispatch({ type: "SET_TEST_RESULT", value: { ok: true, message: `${integration.name} settings saved` } });
        dispatch({ type: "SET_SAVED", value: true });
        window.setTimeout(() => dispatch({ type: "SET_SAVED", value: false }), 3000);
      }
    } catch (err) {
      dispatch({ type: "SET_ERROR", value: err instanceof Error ? err.message : "Failed to save settings" });
    } finally {
      dispatch({ type: "SET_SAVING", value: false });
    }
  }

  return (
    <div className={`rounded-2xl border p-6 bg-white ${integration.accentColor}`}>
      <IntegrationHeader name={integration.name} icon={integration.icon} description={integration.description} ok={state.testResult?.ok ?? false} />

      <StatusBanners error={state.error} saved={state.saved} testResult={state.testResult} />

      <CredentialsForm
        credentials={integration.credentials}
        values={state.credentials}
        showSecrets={state.showSecrets}
        onChange={(key, value) => dispatch({ type: "SET_CREDENTIAL", key, value })}
        onToggleSecret={(key) => dispatch({ type: "TOGGLE_SECRET", key })}
      />

      <ActionButtons
        saving={state.saving}
        dirty={dirty}
        ok={state.testResult?.ok ?? false}
        onTest={handleTest}
        onSave={handleSave}
      />
    </div>
  );
}

function IntegrationHeader({
  name,
  icon,
  description,
  ok,
}: {
  name: string;
  icon: string;
  description: string;
  ok: boolean;
}) {
  return (
    <div className="flex items-start justify-between mb-5">
      <div className="flex items-center gap-3">
        <div className="flex h-10 w-10 items-center justify-center rounded-xl bg-[var(--admin-bg)] text-lg">
          {icon}
        </div>
        <div>
          <h3 className="text-base font-semibold text-[var(--admin-text-primary)]">{name}</h3>
          <p className="text-xs text-[var(--admin-text-muted)] mt-0.5">{description}</p>
        </div>
      </div>
      {ok && (
        <span className="inline-flex items-center gap-1.5 rounded-full bg-[var(--admin-success)]/10 px-3 py-1 text-xs font-medium text-[var(--admin-success)]">
          <span className="w-1.5 h-1.5 rounded-full bg-[var(--admin-success)]" />
          Connected
        </span>
      )}
    </div>
  );
}

type StatusBannersProps = {
  error: string | null;
  saved: boolean;
  testResult: { ok: boolean; message: string } | null;
};

function StatusBanners({ error, saved, testResult }: StatusBannersProps) {
  return (
    <>
      {error && (
        <div className="mb-4 rounded-xl p-4 text-sm border flex items-start gap-3 bg-[var(--admin-danger)]/10 border-[var(--admin-danger)]/30 text-[var(--admin-danger)]">
          <svg className="w-5 h-5 shrink-0 mt-0.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
            <path strokeLinecap="round" strokeLinejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" />
          </svg>
          {error}
        </div>
      )}
      {saved && (
        <div className="mb-4 rounded-xl p-4 text-sm border flex items-center gap-3 bg-[var(--admin-success)]/10 border-[var(--admin-success)]/30 text-[var(--admin-success)]">
          <svg className="w-5 h-5 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
            <path strokeLinecap="round" strokeLinejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
          </svg>
          Settings saved successfully!
        </div>
      )}
      {testResult && (
        <div className={`mb-4 rounded-xl p-4 text-sm border flex items-start gap-3 ${
          testResult.ok
            ? "bg-[var(--admin-success)]/10 border-[var(--admin-success)]/30 text-[var(--admin-success)]"
            : "bg-[var(--admin-danger)]/10 border-[var(--admin-danger)]/30 text-[var(--admin-danger)]"
        }`}>
          {testResult.ok ? (
            <svg className="w-5 h-5 shrink-0 mt-0.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
              <path strokeLinecap="round" strokeLinejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
            </svg>
          ) : (
            <svg className="w-5 h-5 shrink-0 mt-0.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
              <path strokeLinecap="round" strokeLinejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" />
            </svg>
          )}
          {testResult.message}
        </div>
      )}
    </>
  );
}

type CredentialsFormProps = {
  credentials: CredentialField[];
  values: Record<string, string>;
  showSecrets: Record<string, boolean>;
  onChange: (key: string, value: string) => void;
  onToggleSecret: (key: string) => void;
};

function CredentialsForm({ credentials, values, showSecrets, onChange, onToggleSecret }: CredentialsFormProps) {
  return (
    <div className="space-y-4 mb-5">
      {credentials.map((field) => (
        <AdminInput
          key={field.key}
          label={field.label}
          helpText={field.isSecret ? "Click Show/Hide to reveal" : undefined}
        >
          <div className="relative">
            <AdminTextInput
              type={field.isSecret && !showSecrets[field.key] ? "password" : "text"}
              value={values[field.key] ?? ""}
              onChange={(e) => onChange(field.key, e.target.value)}
              placeholder={field.placeholder}
            />
            {field.isSecret && (
              <button
                type="button"
                onClick={() => onToggleSecret(field.key)}
                className="absolute right-3 top-1/2 -translate-y-1/2 text-xs px-2 py-1 rounded-lg hover:bg-[var(--admin-bg)] transition-colors"
                style={{ color: "var(--admin-text-muted)" }}
              >
                {showSecrets[field.key] ? "Hide" : "Show"}
              </button>
            )}
          </div>
        </AdminInput>
      ))}
    </div>
  );
}

type ActionButtonsProps = {
  saving: boolean;
  dirty: boolean;
  ok: boolean;
  onTest: () => void;
  onSave: () => void;
};

function ActionButtons({ saving, dirty, ok, onTest, onSave }: ActionButtonsProps) {
  return (
    <div className="flex items-center gap-3 pt-4 border-t border-[var(--admin-border)]">
      <AdminButton
        variant="secondary"
        size="sm"
        onClick={onTest}
        disabled={saving}
      >
        {ok ? "Re-test" : "Test Connection"}
      </AdminButton>
      <AdminButton
        variant="primary"
        size="sm"
        onClick={onSave}
        disabled={saving || !dirty}
      >
        {saving ? (
          <span className="flex items-center gap-2">
            <span className="h-4 w-4 rounded-full border-2 border-current border-t-transparent animate-spin" />
            Saving...
          </span>
        ) : (
          <>
            <svg className="w-4 h-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
              <path strokeLinecap="round" strokeLinejoin="round" d="M4.5 12.75l6 6 9-13.5" />
            </svg>
            Save
          </>
        )}
      </AdminButton>
      {dirty && !saving && (
        <span className="text-xs text-[var(--admin-text-muted)]">Unsaved changes</span>
      )}
    </div>
  );
}

type PageState = {
  selectedBrandId: string;
  initialCredentials: Record<string, Record<string, string>>;
  loading: boolean;
};

type PageAction =
  | { type: "SET_SELECTED_BRAND"; value: string }
  | { type: "SET_INITIAL_CREDENTIALS"; value: Record<string, Record<string, string>> }
  | { type: "SET_LOADING"; value: boolean };

const initialPageState: PageState = {
  selectedBrandId: "",
  initialCredentials: {},
  loading: true,
};

function pageReducer(state: PageState, action: PageAction): PageState {
  switch (action.type) {
    case "SET_SELECTED_BRAND":
      return { ...state, selectedBrandId: action.value };
    case "SET_INITIAL_CREDENTIALS":
      return { ...state, initialCredentials: action.value };
    case "SET_LOADING":
      return { ...state, loading: action.value };
  }
}

export default function IntegrationsClientPage({ brandId, brands, isPlatformAdmin }: Props) {
  // `selectedBrandId` is the platform admin's explicit brand selection. The
  // initial value is not derived from a prop so the value stays in sync with
  // the server-truth `brandId` once a user makes a choice: we always render
  // off `effectiveBrandId = selectedBrandId || brandId`, so any change to
  // `brandId` (e.g., route nav) is reflected until the user picks another.
  const [state, dispatch] = useReducer(pageReducer, initialPageState);
  const effectiveBrandId = state.selectedBrandId || brandId;

  // Fetch initial credentials for each integration
  useEffect(() => {
    async function fetchCredentials() {
      dispatch({ type: "SET_LOADING", value: true });
      try {
        const [resendCreds, twilioCreds] = await Promise.all([
          getResendCredentials(effectiveBrandId),
          getTwilioCredentials(effectiveBrandId),
        ]);

        dispatch({
          type: "SET_INITIAL_CREDENTIALS",
          value: {
            resend: {
              RESEND_API_KEY: resendCreds.api_key ?? "",
              RESEND_FROM_EMAIL: resendCreds.from_email ?? "",
              RESEND_FROM_NAME: resendCreds.from_name ?? "",
            },
            twilio: {
              TWILIO_ACCOUNT_SID: twilioCreds.account_sid ?? "",
              TWILIO_AUTH_TOKEN: twilioCreds.auth_token ?? "",
              TWILIO_PHONE_NUMBER: twilioCreds.phone_number ?? "",
            },
          },
        });
      } finally {
        dispatch({ type: "SET_LOADING", value: false });
      }
    }
    fetchCredentials();
  }, [effectiveBrandId]);

  return (
    <div className="space-y-8 max-w-4xl">
      <BrandSelector
        isPlatformAdmin={isPlatformAdmin}
        brands={brands}
        effectiveBrandId={effectiveBrandId}
        onSelectBrand={(value) => dispatch({ type: "SET_SELECTED_BRAND", value })}
      />

      <AIProviderSection brandId={effectiveBrandId} />

      <IntegrationsList
        loading={state.loading}
        initialCredentials={state.initialCredentials}
        effectiveBrandId={effectiveBrandId}
      />

      <HelpFooter />
    </div>
  );
}

type BrandSelectorProps = {
  isPlatformAdmin: boolean;
  brands: { id: string; name: string }[];
  effectiveBrandId: string;
  onSelectBrand: (value: string) => void;
};

function BrandSelector({ isPlatformAdmin, brands, effectiveBrandId, onSelectBrand }: BrandSelectorProps) {
  if (!isPlatformAdmin || brands.length === 0) return null;
  return (
    <div className="rounded-2xl bg-white border border-[var(--admin-border)] p-5">
      <AdminInput label="Select Brand" helpText="Choose a brand to configure integrations for:">
        <AdminSelect
          value={effectiveBrandId}
          onChange={(e) => onSelectBrand(e.target.value)}
          options={brands.map((b) => ({ value: b.id, label: b.name }))}
        />
      </AdminInput>
    </div>
  );
}

function AIProviderSection({ brandId }: { brandId: string }) {
  return (
    <div className="rounded-2xl bg-white border border-[var(--admin-border)] overflow-hidden">
      <div className="px-5 py-4 border-b border-[var(--admin-border)] bg-[var(--admin-bg-subtle)] flex items-center justify-between">
        <div className="flex items-center gap-3">
          <div className="flex h-8 w-8 items-center justify-center rounded-lg bg-violet-100 text-violet-700 text-sm">🤖</div>
          <div>
            <h3 className="text-sm font-semibold text-[var(--admin-text-primary)]">AI Provider</h3>
            <p className="text-xs text-[var(--admin-text-muted)]">Configure AI models for intelligent features</p>
          </div>
        </div>
        <Link href="/admin/settings/ai" className="inline-flex items-center gap-1 text-xs font-medium text-[var(--admin-accent)] hover:text-[var(--admin-accent-hover)]">
          Configure AI
          <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
            <path strokeLinecap="round" strokeLinejoin="round" d="M13.5 4.5L21 12m0 0l-7.5 7.5M21 12H3" />
          </svg>
        </Link>
      </div>
      <div className="p-5">
        <AIProviderPanel brandId={brandId} />
      </div>
    </div>
  );
}

type IntegrationsListProps = {
  loading: boolean;
  initialCredentials: Record<string, Record<string, string>>;
  effectiveBrandId: string;
};

function IntegrationsList({ loading, initialCredentials, effectiveBrandId }: IntegrationsListProps) {
  return (
    <div>
      <h2 className="text-lg font-semibold text-[var(--admin-text-primary)] mb-4">Communication &amp; Payments</h2>
      <div className="space-y-4">
        {loading ? (
          <div className="flex items-center justify-center py-12">
            <div className="flex items-center gap-3">
              <div className="h-5 w-5 rounded-full border-2 border-[var(--admin-accent)] border-t-transparent animate-spin" />
              <span className="text-sm text-[var(--admin-text-muted)]">Loading integrations...</span>
            </div>
          </div>
        ) : (
          INTEGRATIONS_WITHOUT_OPENAI.map((integration) => (
            <IntegrationCard
              key={integration.id}
              integration={integration}
              initialCredentials={initialCredentials[integration.id]}
              brandId={effectiveBrandId}
            />
          ))
        )}
      </div>
    </div>
  );
}

function HelpFooter() {
  return (
    <div className="rounded-xl bg-[var(--admin-bg-subtle)] border border-[var(--admin-border)] p-4">
      <div className="flex items-start gap-3">
        <svg className="w-5 h-5 text-[var(--admin-text-muted)] shrink-0 mt-0.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
          <path strokeLinecap="round" strokeLinejoin="round" d="M9.879 7.519c1.171-1.025 3.071-1.025 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45 1.827v.75M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9 5.25h.008v.008H12v-.008z" />
        </svg>
        <div>
          <p className="text-sm font-medium text-[var(--admin-text-primary)]">Need help?</p>
          <p className="text-xs text-[var(--admin-text-muted)] mt-1">
            Contact us at <a href="mailto:support@cielohermosa.com" className="underline hover:text-[var(--admin-accent)]">support@cielohermosa.com</a> for assistance setting up integrations.
          </p>
        </div>
      </div>
    </div>
  );
}