"use client";

import * as React from "react";
import { useRouter, useParams } from "next/navigation";
import { toast } from "sonner";
import {
  Loader2,
  ArrowLeft,
  Save,
  Plug,
  Trash2,
  CheckCircle2,
  XCircle,
  RefreshCw,
  Zap,
  ArrowLeftRight,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Switch } from "@/components/ui/switch";
import { Badge } from "@/components/ui/badge";
import {
  Card,
  CardContent,
  CardHeader,
  CardTitle,
  CardDescription,
} from "@/components/ui/card";
import {
  FieldMappingEditor,
  type SourceField,
  type ExternalField,
  type FieldMapping,
} from "@/components/integrations/field-mapping-editor";
import {
  SetupGuidePanel,
  type SetupGuide,
} from "@/components/integrations/setup-guide-panel";

type ProviderInfo = {
  id: string;
  name: string;
  setupGuide?: SetupGuide;
};

type Integration = {
  id: string;
  provider: string;
  name: string;
  enabled: boolean;
  config: Record<string, unknown>;
  fieldMapping: Record<string, string> | null;
  triggerEvents: string[] | null;
  syncDirection: string;
  lastSyncAt: string | null;
  lastSyncStatus: string | null;
};

const TRIGGER_EVENTS = [
  { value: "ocr_complete", label: "OCR Complete" },
  { value: "card_reviewed", label: "Card Reviewed" },
  { value: "card_exported", label: "Card Exported" },
];

export default function IntegrationDetailPage() {
  const router = useRouter();
  const params = useParams();
  const id = params.id as string;

  const [integration, setIntegration] = React.useState<Integration | null>(
    null
  );
  const [loading, setLoading] = React.useState(true);
  const [saving, setSaving] = React.useState(false);
  const [testing, setTesting] = React.useState(false);
  const [testResult, setTestResult] = React.useState<{
    success: boolean;
    message: string;
  } | null>(null);
  const [syncing, setSyncing] = React.useState(false);
  const [deleting, setDeleting] = React.useState(false);
  const [confirmDelete, setConfirmDelete] = React.useState(false);

  const [sourceFields, setSourceFields] = React.useState<SourceField[]>([]);
  const [externalFields, setExternalFields] = React.useState<ExternalField[]>([]);
  const [fieldsLoading, setFieldsLoading] = React.useState(true);
  const [providerInfo, setProviderInfo] = React.useState<ProviderInfo | null>(null);

  React.useEffect(() => {
    fetch(`/api/integrations/${id}`)
      .then((r) => r.json())
      .then((data) => {
        setIntegration(data.integration);
        setLoading(false);
      })
      .catch(() => setLoading(false));
  }, [id]);

  React.useEffect(() => {
    if (!integration?.provider) return;
    fetch("/api/integrations")
      .then((r) => r.ok ? r.json() : { providers: [] })
      .then((data) => {
        const match = (data.providers || []).find(
          (p: ProviderInfo) => p.id === integration.provider
        );
        if (match) setProviderInfo(match);
      })
      .catch(() => {});
  }, [integration?.provider]);

  React.useEffect(() => {
    Promise.all([
      fetch("/api/integrations/source-fields").then((r) => r.ok ? r.json() : { fields: [] }),
      fetch(`/api/integrations/${id}/fields`).then((r) => r.ok ? r.json() : { fields: [] }),
    ])
      .then(([sourceData, externalData]) => {
        setSourceFields(sourceData.fields || []);
        setExternalFields(externalData.fields || []);
        setFieldsLoading(false);
      })
      .catch(() => setFieldsLoading(false));
  }, [id]);

  const handleSave = async () => {
    if (!integration) return;
    setSaving(true);
    try {
      const res = await fetch(`/api/integrations/${id}`, {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          name: integration.name,
          enabled: integration.enabled,
          config: integration.config,
          triggerEvents: integration.triggerEvents,
          fieldMapping: integration.fieldMapping ?? {},
        }),
      });
      if (res.ok) {
        toast.success("Integration saved");
      } else {
        toast.error("Failed to save");
      }
    } catch {
      toast.error("Failed to save");
    } finally {
      setSaving(false);
    }
  };

  const handleTest = async () => {
    setTesting(true);
    setTestResult(null);
    try {
      const res = await fetch(`/api/integrations/${id}/test`, {
        method: "POST",
      });
      const data = await res.json();
      setTestResult(data);
      if (data.success) {
        toast.success(data.message);
      } else {
        toast.error(data.message);
      }
    } catch {
      setTestResult({ success: false, message: "Test request failed" });
    } finally {
      setTesting(false);
    }
  };

  const handleSync = async () => {
    setSyncing(true);
    try {
      const res = await fetch(`/api/integrations/${id}/sync`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({}),
      });
      const data = await res.json();
      toast.success(
        `Synced ${data.synced} of ${data.total} cards${data.failed ? ` (${data.failed} failed)` : ""}`
      );
    } catch {
      toast.error("Sync failed");
    } finally {
      setSyncing(false);
    }
  };

  const handleDelete = async () => {
    if (!confirmDelete) {
      setConfirmDelete(true);
      return;
    }
    setDeleting(true);
    try {
      const res = await fetch(`/api/integrations/${id}`, {
        method: "DELETE",
      });
      if (res.ok) {
        toast.success("Integration deleted");
        router.push("/settings/integrations");
      } else {
        toast.error("Failed to delete");
      }
    } catch {
      toast.error("Failed to delete");
    } finally {
      setDeleting(false);
    }
  };

  const updateConfig = (key: string, value: string) => {
    setIntegration((prev) => {
      if (!prev) return prev;
      return {
        ...prev,
        config: { ...prev.config, [key]: value },
      };
    });
  };

  const handleMappingChange = (mapping: FieldMapping) => {
    setIntegration((prev) => (prev ? { ...prev, fieldMapping: mapping } : prev));
  };

  const toggleTriggerEvent = (event: string) => {
    setIntegration((prev) => {
      if (!prev) return prev;
      const events = prev.triggerEvents || [];
      const next = events.includes(event)
        ? events.filter((e) => e !== event)
        : [...events, event];
      return { ...prev, triggerEvents: next };
    });
  };

  if (loading) {
    return (
      <div className="flex items-center justify-center py-20">
        <Loader2 className="size-6 animate-spin text-muted-foreground" />
      </div>
    );
  }

  if (!integration) {
    return (
      <div className="space-y-4">
        <Button
          variant="ghost"
          size="sm"
          onClick={() => router.push("/settings/integrations")}
        >
          <ArrowLeft className="mr-1.5 size-3.5" />
          Back
        </Button>
        <p className="text-center text-sm text-muted-foreground">
          Integration not found.
        </p>
      </div>
    );
  }

  return (
    <div className="space-y-6">
      <div className="flex items-center justify-between">
        <Button
          variant="ghost"
          size="sm"
          onClick={() => router.push("/settings/integrations")}
        >
          <ArrowLeft className="mr-1.5 size-3.5" />
          Back to Integrations
        </Button>
        <div className="flex items-center gap-2">
          <Switch
            checked={integration.enabled}
            onCheckedChange={(v) =>
              setIntegration((prev) =>
                prev ? { ...prev, enabled: v } : prev
              )
            }
          />
          <span className="text-sm">
            {integration.enabled ? "Enabled" : "Disabled"}
          </span>
        </div>
      </div>

      {/* Status */}
      <div className="flex items-center gap-3">
        <Badge
          variant="outline"
          className={
            integration.lastSyncStatus === "connected" ||
            integration.lastSyncStatus === "success"
              ? "border-emerald-500/30 text-emerald-500"
              : integration.lastSyncStatus === "error"
                ? "border-destructive/30 text-destructive"
                : "text-muted-foreground"
          }
        >
          {integration.lastSyncStatus === "connected" ||
          integration.lastSyncStatus === "success" ? (
            <CheckCircle2 className="mr-1 size-3" />
          ) : integration.lastSyncStatus === "error" ? (
            <XCircle className="mr-1 size-3" />
          ) : null}
          {integration.lastSyncStatus || "Not tested"}
        </Badge>
        {integration.lastSyncAt && (
          <span className="text-xs text-muted-foreground">
            Last activity:{" "}
            {new Date(integration.lastSyncAt).toLocaleString()}
          </span>
        )}
      </div>

      {/* Setup Guide */}
      {providerInfo?.setupGuide && (
        <SetupGuidePanel
          providerName={providerInfo.name}
          guide={providerInfo.setupGuide}
        />
      )}

      {/* Configuration */}
      <Card className="glass-card">
        <CardHeader>
          <CardTitle className="flex items-center gap-2 text-base">
            <Plug className="size-4" />
            Configuration
          </CardTitle>
        </CardHeader>
        <CardContent className="space-y-4">
          <div className="space-y-2">
            <Label>Integration Name</Label>
            <Input
              value={integration.name}
              onChange={(e) =>
                setIntegration((prev) =>
                  prev ? { ...prev, name: e.target.value } : prev
                )
              }
            />
          </div>

          {Object.entries(integration.config).map(([key, value]) => {
            if (key.startsWith("_") || key === "columnMap") return null;
            const isSecret =
              key.toLowerCase().includes("token") ||
              key.toLowerCase().includes("secret") ||
              key.toLowerCase().includes("password");
            return (
              <div key={key} className="space-y-2">
                <Label className="capitalize">
                  {key.replace(/([A-Z])/g, " $1").trim()}
                </Label>
                <Input
                  type={isSecret ? "password" : "text"}
                  value={String(value || "")}
                  onChange={(e) => updateConfig(key, e.target.value)}
                />
              </div>
            );
          })}
        </CardContent>
      </Card>

      {/* Field Mapping — only if provider returns external fields */}
      {(fieldsLoading || externalFields.length > 0) && (
        <Card className="glass-card">
          <CardHeader>
            <CardTitle className="flex items-center gap-2 text-base">
              <ArrowLeftRight className="size-4" />
              Field Mapping
            </CardTitle>
            <CardDescription>
              Match your card fields to {integration.name} columns. Only mapped
              fields will be synced.
            </CardDescription>
          </CardHeader>
          <CardContent>
            <FieldMappingEditor
              sourceFields={sourceFields}
              externalFields={externalFields}
              value={(integration.fieldMapping as FieldMapping) || {}}
              onChange={handleMappingChange}
              externalLabel={
                integration.provider === "monday"
                  ? "Monday column"
                  : integration.provider === "airtable"
                    ? "Airtable field"
                    : integration.provider === "google_sheets"
                      ? "Sheet column"
                      : integration.provider === "planning_center"
                        ? "PCO field"
                        : "External field"
              }
              loading={fieldsLoading}
            />
          </CardContent>
        </Card>
      )}

      {/* Trigger Events */}
      <Card className="glass-card">
        <CardHeader>
          <CardTitle className="flex items-center gap-2 text-base">
            <Zap className="size-4" />
            Trigger Events
          </CardTitle>
          <CardDescription>
            When should this integration fire?
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-3">
          {TRIGGER_EVENTS.map((evt) => (
            <div key={evt.value} className="flex items-center gap-3">
              <Switch
                checked={
                  integration.triggerEvents?.includes(evt.value) ?? false
                }
                onCheckedChange={() => toggleTriggerEvent(evt.value)}
              />
              <Label className="text-sm">{evt.label}</Label>
            </div>
          ))}
        </CardContent>
      </Card>

      {/* Actions */}
      <div className="flex flex-wrap gap-2">
        <Button onClick={handleSave} disabled={saving}>
          {saving ? (
            <Loader2 className="mr-2 size-4 animate-spin" />
          ) : (
            <Save className="mr-2 size-4" />
          )}
          Save Changes
        </Button>
        <Button variant="outline" onClick={handleTest} disabled={testing}>
          {testing ? (
            <Loader2 className="mr-2 size-4 animate-spin" />
          ) : (
            <CheckCircle2 className="mr-2 size-4" />
          )}
          Test Connection
        </Button>
        <Button variant="outline" onClick={handleSync} disabled={syncing}>
          {syncing ? (
            <Loader2 className="mr-2 size-4 animate-spin" />
          ) : (
            <RefreshCw className="mr-2 size-4" />
          )}
          Sync Now
        </Button>
      </div>

      {testResult && (
        <div
          className={`rounded-lg border p-3 text-sm ${
            testResult.success
              ? "border-emerald-500/30 bg-emerald-500/10 text-emerald-400"
              : "border-destructive/30 bg-destructive/10 text-destructive"
          }`}
        >
          {testResult.message}
        </div>
      )}

      {/* Danger Zone */}
      <Card className="glass-card border-destructive/30">
        <CardContent className="flex items-center justify-between p-4">
          <div>
            <p className="text-sm font-medium text-destructive">
              Delete this integration
            </p>
            <p className="text-xs text-muted-foreground">
              This cannot be undone.
            </p>
          </div>
          <Button
            variant="destructive"
            size="sm"
            onClick={handleDelete}
            disabled={deleting}
          >
            {deleting ? (
              <Loader2 className="mr-1.5 size-3.5 animate-spin" />
            ) : (
              <Trash2 className="mr-1.5 size-3.5" />
            )}
            {confirmDelete ? "Confirm Delete" : "Delete"}
          </Button>
        </CardContent>
      </Card>
    </div>
  );
}
