"use client";

import { useEffect, useState } from "react";
import {
  Link2,
  Loader2,
  AlertCircle,
  Building,
  Calendar,
  Activity,
  Pencil,
  Save,
  X,
  Shield,
  FileCode,
  List,
  FileText,
  Eye,
  Download,
} from "lucide-react";
import { toast } from "sonner";
import { useRepositories } from "@/di/repository-provider";
import { useApiQuery } from "@/presentation/hooks/use-api-query";
import { useT, useLocale } from "@/shared/i18n/client";
import { Badge } from "@/presentation/components/ui/badge";
import { Button } from "@/presentation/components/ui/button";
import { Input } from "@/presentation/components/ui/input";
import { Textarea } from "@/presentation/components/ui/textarea";
import { env } from "@/infrastructure/config/env";
import { apiClient } from "@/infrastructure/api/api-client";
import {
  Sheet,
  SheetContent,
  SheetHeader,
  SheetTitle,
} from "@/presentation/components/ui/sheet";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/presentation/components/ui/select";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
} from "@/presentation/components/ui/dialog";
import { formatDateTime } from "@/shared/lib/format-date";
import type { IntegrationCredentialItem } from "@/domain/entities/integration";

interface Props {
  connectionId: number | null;
  onClose: () => void;
  onChanged?: () => void;
}

const STATUSES = ["connected", "disconnected", "requested", "rejected", "error"];

export function IntegrationConnectionDetailSheet({
  connectionId,
  onClose,
  onChanged,
}: Props) {
  const t = useT();
  const locale = useLocale();
  const container = useRepositories();
  const d = t.pages.integrationConnections.detail;

  const [isEditing, setIsEditing] = useState(false);
  const [saving, setSaving] = useState(false);
  const [editMode, setEditMode] = useState<"fields" | "json">("fields");

  // Form states
  const [status, setStatus] = useState<string>("connected");
  const [credentialsFields, setCredentialsFields] = useState<IntegrationCredentialItem[]>([]);
  const [credentialsJson, setCredentialsJson] = useState<string>("[]");
  const [jsonError, setJsonError] = useState<string | null>(null);

  // Document preview states
  const [loadingDocument, setLoadingDocument] = useState<string | null>(null);
  const [previewOpen, setPreviewOpen] = useState(false);
  const [previewUrl, setPreviewUrl] = useState<string | null>(null);
  const [previewType, setPreviewType] = useState<string>("");
  const [previewName, setPreviewName] = useState<string>("");

  // Fetch connection details from API
  const {
    data: connection,
    loading,
    error,
    refetch,
  } = useApiQuery(
    () => container.integrationConnectionRepository.findById(connectionId as number),
    { enabled: connectionId !== null, deps: [connectionId] }
  );

  // Initialize form fields when connection data is loaded or edit mode changes
  useEffect(() => {
    if (connection) {
      setStatus(connection.status);
      const creds = connection.credentials || [];
      
      // Setup Fields Editor state
      setCredentialsFields(JSON.parse(JSON.stringify(creds)));

      // Setup JSON Editor state
      setCredentialsJson(JSON.stringify(creds, null, 2));
      setJsonError(null);
    }
  }, [connection, isEditing]);

  const handleJsonChange = (val: string) => {
    setCredentialsJson(val);
    try {
      if (val.trim() === "") {
        setJsonError(null);
        return;
      }
      const parsed = JSON.parse(val);
      if (!Array.isArray(parsed)) {
        setJsonError("Credentials must be a JSON array of objects");
        return;
      }
      setJsonError(null);
    } catch (err: any) {
      setJsonError(err.message || "Invalid JSON");
    }
  };

  const handleSave = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!connection) return;
    setSaving(true);

    try {
      let finalCredentials: IntegrationCredentialItem[] = [];

      if (editMode === "json") {
        if (jsonError) {
          toast.error(d.invalidJson);
          setSaving(false);
          return;
        }
        finalCredentials = credentialsJson.trim() ? JSON.parse(credentialsJson) : [];
      } else {
        finalCredentials = credentialsFields;
      }

      await container.integrationConnectionRepository.update(connection.id, {
        status: status as any,
        credentials: finalCredentials,
      });

      toast.success(d.toasts.updated);
      setIsEditing(false);
      refetch();
      onChanged?.();
    } catch (err) {
      toast.error(d.toasts.error);
    } finally {
      setSaving(false);
    }
  };

  const handlePreviewDocument = async (filePath: string) => {
    setLoadingDocument(filePath);
    try {
      const response = await apiClient.get(
        `/integration-connections/${connection?.id}/connection-document`,
        {
          params: { file_path: filePath },
          responseType: "blob",
        }
      );

      const blob = response.data;
      const fileType = blob.type || "application/pdf";
      const url = URL.createObjectURL(blob);

      setPreviewUrl(url);
      setPreviewType(fileType);
      setPreviewName(filePath.split("/").pop() || "Document");
      setPreviewOpen(true);
    } catch (err: any) {
      toast.error("Failed to load document");
    } finally {
      setLoadingDocument(null);
    }
  };

  const handleClosePreview = () => {
    if (previewUrl) {
      URL.revokeObjectURL(previewUrl);
    }
    setPreviewOpen(false);
    setPreviewUrl(null);
  };

  const getStatusBadgeStyles = (statusVal: string) => {
    switch (statusVal) {
      case "connected":
        return "bg-emerald-50 text-emerald-700 border-emerald-200 dark:bg-emerald-950/40 dark:text-emerald-400 dark:border-emerald-500/20";
      case "disconnected":
        return "bg-slate-100 text-slate-700 border-slate-200 dark:bg-slate-800 dark:text-slate-300 dark:border-slate-700";
      case "requested":
        return "bg-blue-50 text-blue-700 border-blue-200 dark:bg-blue-950/40 dark:text-blue-400 dark:border-blue-500/20";
      case "rejected":
        return "bg-rose-50 text-rose-700 border-rose-200 dark:bg-rose-950/40 dark:text-rose-400 dark:border-rose-500/20";
      case "error":
        return "bg-amber-50 text-amber-700 border-amber-200 dark:bg-amber-950/40 dark:text-amber-400 dark:border-amber-500/20";
      default:
        return "bg-slate-100 text-slate-700 border-slate-200 dark:bg-slate-800 dark:text-slate-300 dark:border-slate-700";
    }
  };

  const getStatusLabel = (statusVal: string) => {
    return t.pages.integrationConnections.statusLabels[statusVal] || statusVal;
  };

  const logoSrc = connection?.integration?.logo
    ? `${env.backendOrigin}/${connection.integration.logo}`
    : null;

  return (
    <>
      <Sheet
        open={connectionId !== null}
        onOpenChange={(open) => {
          if (!open) {
            setIsEditing(false);
            onClose();
          }
        }}
      >
        <SheetContent className="sm:max-w-xl w-[550px] overflow-y-auto flex flex-col h-full border-l border-border bg-card p-0">
          <SheetHeader className="border-b border-border p-6 pb-4">
            <SheetTitle className="flex items-center gap-3">
              <Link2 className="w-5 h-5 text-primary" />
              <span>{isEditing ? d.editTitle : d.title}</span>
            </SheetTitle>
          </SheetHeader>

          {loading ? (
            <div className="flex-1 flex items-center justify-center">
              <Loader2 className="w-8 h-8 animate-spin text-muted-foreground" />
            </div>
          ) : error ? (
            <div className="flex-1 flex flex-col items-center justify-center p-6 text-center">
              <AlertCircle className="w-8 h-8 text-destructive mb-3" />
              <p className="text-sm font-semibold text-destructive">{error}</p>
              <Button variant="outline" size="sm" onClick={refetch} className="mt-4">
                {t.common.retry}
              </Button>
            </div>
          ) : connection ? (
            <div className="flex-1 flex flex-col justify-between overflow-hidden">
              {/* Main content viewport */}
              <div className="flex-1 overflow-y-auto p-6 space-y-6">
                {/* Connector Card Header */}
                <div className="bg-muted/40 border border-border/80 rounded-xl p-4 flex items-start gap-4 shadow-sm">
                  <div className="w-14 h-14 rounded-lg bg-background flex items-center justify-center border border-border shrink-0 overflow-hidden shadow-inner">
                    {logoSrc ? (
                      <img
                        src={logoSrc}
                        alt={connection.integration?.name || ""}
                        className="w-full h-full object-contain p-1.5"
                      />
                    ) : (
                      <Link2 className="w-6 h-6 text-muted-foreground" />
                    )}
                  </div>
                  <div className="min-w-0 flex-1">
                    <h3 className="text-base font-bold text-foreground truncate">
                      {connection.integration?.name}
                    </h3>
                    <div className="text-xs text-muted-foreground mt-1 flex items-center gap-1.5">
                      <span className="font-medium">{d.code}:</span>
                      <span className="bg-muted px-1.5 py-0.5 rounded font-mono text-[10px] text-foreground border border-border">
                        {connection.integration?.code}
                      </span>
                    </div>
                    <div className="mt-2.5 flex items-center justify-between">
                      <span className="text-[11px] font-medium text-muted-foreground">
                        {d.fields.status}
                      </span>
                      <Badge variant="outline" className={`font-semibold ${getStatusBadgeStyles(connection.status)}`}>
                        {getStatusLabel(connection.status)}
                      </Badge>
                    </div>
                  </div>
                </div>

                {isEditing ? (
                  /* Editing Layout */
                  <form onSubmit={handleSave} className="space-y-5">
                    {/* Status selection */}
                    <div className="space-y-1.5">
                      <label className="text-xs font-semibold text-muted-foreground">
                        {d.fields.status}
                      </label>
                      <Select value={status} onValueChange={setStatus}>
                        <SelectTrigger className="w-full">
                          <SelectValue />
                        </SelectTrigger>
                        <SelectContent>
                          {STATUSES.map((s) => (
                            <SelectItem key={s} value={s}>
                              {getStatusLabel(s)}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    </div>

                    {/* Credentials Editor Container */}
                    <div className="space-y-3 pt-3 border-t border-border">
                      <div className="flex items-center justify-between">
                        <label className="text-xs font-bold text-foreground">
                          {d.credentials}
                        </label>
                        <div className="flex bg-muted rounded-lg p-0.5 border border-border">
                          <Button
                            type="button"
                            variant={editMode === "fields" ? "secondary" : "ghost"}
                            size="sm"
                            className="h-7 px-2.5 text-[10px] gap-1.5"
                            onClick={() => setEditMode("fields")}
                          >
                            <List className="w-3 h-3" />
                            {d.editFields}
                          </Button>
                          <Button
                            type="button"
                            variant={editMode === "json" ? "secondary" : "ghost"}
                            size="sm"
                            className="h-7 px-2.5 text-[10px] gap-1.5"
                            onClick={() => setEditMode("json")}
                          >
                            <FileCode className="w-3 h-3" />
                            {d.editJson}
                          </Button>
                        </div>
                      </div>

                      {editMode === "json" ? (
                        /* Raw JSON Textarea Editor */
                        <div className="space-y-2">
                          <span className="text-[10px] text-muted-foreground font-medium block">
                            {d.rawJson}
                          </span>
                          <Textarea
                            value={credentialsJson}
                            onChange={(e) => handleJsonChange(e.target.value)}
                            className={`font-mono text-xs h-48 focus-visible:ring-0 ${
                              jsonError ? "border-destructive focus-visible:border-destructive" : "border-border"
                            }`}
                          />
                          {jsonError && (
                            <div className="text-[10px] text-destructive flex items-center gap-1.5">
                              <AlertCircle className="w-3 h-3 shrink-0" />
                              <span>{jsonError}</span>
                            </div>
                          )}
                        </div>
                      ) : (
                        /* Flat Field-by-Field Inputs Editor */
                        <div className="space-y-3.5 max-h-60 overflow-y-auto pr-1">
                          {credentialsFields.length === 0 ? (
                            <div className="text-center py-4 bg-muted/40 border border-border/80 border-dashed rounded-lg">
                              <span className="text-xs text-muted-foreground">
                                {d.noCredentials}
                              </span>
                              <Button
                                type="button"
                                variant="link"
                                size="sm"
                                className="text-[10px] block mx-auto mt-1"
                                onClick={() => setEditMode("json")}
                              >
                                {d.editJson}
                              </Button>
                            </div>
                          ) : (
                            credentialsFields.map((item, index) => (
                              <div key={index} className="space-y-1">
                                <label className="text-[10px] font-bold text-muted-foreground uppercase tracking-wider block">
                                  {item.name}
                                </label>
                                <Input
                                  value={item.value}
                                  onChange={(e) => {
                                    const newVal = e.target.value;
                                    const updated = [...credentialsFields];
                                    updated[index].value = newVal;
                                    setCredentialsFields(updated);
                                    // Keep JSON string synchronized
                                    setCredentialsJson(JSON.stringify(updated, null, 2));
                                  }}
                                  className="h-8 text-xs"
                                />
                              </div>
                            ))
                          )}
                        </div>
                      )}
                    </div>
                  </form>
                ) : (
                  /* Read-Only Details Layout */
                  <div className="space-y-5">
                    {/* Company Details Card */}
                    <div className="space-y-2">
                      <h4 className="text-xs font-bold uppercase tracking-wider text-muted-foreground flex items-center gap-2">
                        <Building className="w-3.5 h-3.5" />
                        {d.companyInfo}
                      </h4>
                      <div className="bg-muted/30 border border-border/60 rounded-xl p-3.5 space-y-2">
                        <div className="flex items-center justify-between text-xs">
                          <span className="text-muted-foreground font-medium">{d.fields.name}</span>
                          <span className="font-semibold text-foreground">
                            {connection.company?.name || `ID: ${connection.company_id}`}
                          </span>
                        </div>
                        {connection.company?.email && (
                          <div className="flex items-center justify-between text-xs">
                            <span className="text-muted-foreground font-medium">{d.fields.email}</span>
                            <span className="font-semibold text-foreground">
                              {connection.company.email}
                            </span>
                          </div>
                        )}
                      </div>
                    </div>

                    {/* Sync & Timing Metrics Card */}
                    <div className="space-y-2">
                      <h4 className="text-xs font-bold uppercase tracking-wider text-muted-foreground flex items-center gap-2">
                        <Calendar className="w-3.5 h-3.5" />
                        {d.connectionInfo}
                      </h4>
                      <div className="bg-muted/30 border border-border/60 rounded-xl p-3.5 space-y-2 text-xs">
                        <div className="flex items-center justify-between">
                          <span className="text-muted-foreground font-medium">{d.fields.connectedAt}</span>
                          <span className="font-semibold text-foreground">
                            {connection.connected_at
                              ? formatDateTime(connection.connected_at, locale)
                              : "—"}
                          </span>
                        </div>
                        <div className="flex items-center justify-between">
                          <span className="text-muted-foreground font-medium">{d.fields.lastSyncAt}</span>
                          <span className="font-semibold text-foreground">
                            {connection.last_sync_at
                              ? formatDateTime(connection.last_sync_at, locale)
                              : "—"}
                          </span>
                        </div>
                        {connection.created_at && (
                          <div className="flex items-center justify-between">
                            <span className="text-muted-foreground font-medium">{d.fields.createdAt}</span>
                            <span className="font-semibold text-foreground">
                              {formatDateTime(connection.created_at, locale)}
                            </span>
                          </div>
                        )}
                        {connection.updated_at && (
                          <div className="flex items-center justify-between">
                            <span className="text-muted-foreground font-medium">{d.fields.updatedAt}</span>
                            <span className="font-semibold text-foreground">
                              {formatDateTime(connection.updated_at, locale)}
                            </span>
                          </div>
                        )}
                      </div>
                    </div>

                    {/* Credentials Read-only Panel */}
                    <div className="space-y-2">
                      <h4 className="text-xs font-bold uppercase tracking-wider text-muted-foreground flex items-center gap-2">
                        <Shield className="w-3.5 h-3.5" />
                        {d.credentials}
                      </h4>
                      <div className="bg-muted/30 border border-border/60 rounded-xl p-3.5">
                        {!connection.credentials || connection.credentials.length === 0 ? (
                          <span className="text-xs text-muted-foreground italic">
                            {d.noCredentials}
                          </span>
                        ) : (
                          <div className="space-y-2">
                            {connection.credentials.map((item, index) => (
                              <div key={index} className="flex flex-col gap-0.5 text-xs">
                                <span className="text-[10px] font-bold text-muted-foreground uppercase tracking-wider">
                                  {item.name}
                                </span>
                                {item.type === "file" ? (
                                  <div className="flex items-center justify-between bg-muted/60 border border-border/40 p-1.5 rounded text-foreground">
                                    <div className="flex items-center gap-2 min-w-0">
                                      <FileText className="w-4 h-4 text-muted-foreground shrink-0" />
                                      <span className="truncate text-xs font-mono font-medium">
                                        {item.value.split("/").pop()}
                                      </span>
                                    </div>
                                    <div className="flex items-center gap-1 shrink-0">
                                      <Button
                                        variant="ghost"
                                        size="icon"
                                        className="w-7 h-7"
                                        disabled={loadingDocument !== null}
                                        onClick={() => handlePreviewDocument(item.value)}
                                      >
                                        {loadingDocument === item.value ? (
                                          <Loader2 className="w-3.5 h-3.5 animate-spin" />
                                        ) : (
                                          <Eye className="w-3.5 h-3.5" />
                                        )}
                                      </Button>
                                    </div>
                                  </div>
                                ) : (
                                  <span className="font-mono bg-muted/60 border border-border/40 p-1.5 rounded text-foreground select-all break-all leading-relaxed">
                                    {item.value}
                                  </span>
                                )}
                              </div>
                            ))}
                          </div>
                        )}
                      </div>
                    </div>
                  </div>
                )}
              </div>

              {/* Sticky Actions Footer */}
              <div className="border-t border-border p-4 bg-muted/30 flex justify-end gap-2.5">
                {isEditing ? (
                  <>
                    <Button
                      variant="ghost"
                      onClick={() => {
                        setIsEditing(false);
                        setJsonError(null);
                      }}
                      disabled={saving}
                      className="h-9 text-xs"
                    >
                      <X className="w-4 h-4 mr-1.5" />
                      {d.actions.cancel}
                    </Button>
                    <Button
                      onClick={handleSave}
                      disabled={saving || (editMode === "json" && !!jsonError)}
                      className="h-9 text-xs gap-1.5 shadow-sm"
                    >
                      {saving ? (
                        <Loader2 className="w-4 h-4 animate-spin" />
                      ) : (
                        <Save className="w-4 h-4" />
                      )}
                      {d.actions.save}
                    </Button>
                  </>
                ) : (
                  <Button
                    onClick={() => setIsEditing(true)}
                    className="h-9 text-xs gap-1.5 shadow-sm"
                  >
                    <Pencil className="w-4 h-4" />
                    {d.actions.edit}
                  </Button>
                )}
              </div>
            </div>
          ) : null}
        </SheetContent>
      </Sheet>

      {/* Document Preview Dialog */}
      <Dialog open={previewOpen} onOpenChange={(open) => { if (!open) handleClosePreview(); }}>
        <DialogContent className="max-w-4xl w-[90vw] h-[85vh] flex flex-col p-4">
          <DialogHeader className="border-b border-border pb-3 shrink-0">
            <DialogTitle className="text-sm font-bold truncate">{previewName}</DialogTitle>
          </DialogHeader>
          <div className="flex-1 overflow-hidden flex items-center justify-center bg-muted/20 rounded-lg border border-border">
            {previewUrl && previewType.includes("pdf") ? (
              <iframe src={previewUrl} className="w-full h-full border-0" />
            ) : previewUrl && previewType.includes("image") ? (
              <img src={previewUrl} alt={previewName} className="max-w-full max-h-full object-contain" />
            ) : previewUrl ? (
              <div className="text-center p-6 space-y-4">
                <AlertCircle className="w-10 h-10 text-muted-foreground mx-auto" />
                <p className="text-sm font-medium text-foreground">{d.previewNotAvailable}</p>
                <a href={previewUrl} download={previewName} className="inline-block">
                  <Button size="sm" className="gap-2">
                    <Download className="w-4 h-4" />
                    {d.downloadFile}
                  </Button>
                </a>
              </div>
            ) : null}
          </div>
        </DialogContent>
      </Dialog>
    </>
  );
}
