"use client";

import {
  Alert,
  Badge,
  Button,
  Container,
  FileButton,
  Group,
  Modal,
  Paper,
  Stack,
  Switch,
  Tabs,
  TagsInput,
  Text,
  Textarea,
  TextInput,
  Title,
} from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import { notifications } from "@mantine/notifications";
import {
  IconAlertCircle,
  IconArrowLeft,
  IconChecklist,
  IconCode,
  IconDeviceFloppy,
  IconDownload,
  IconEye,
  IconFileUpload,
  IconHistory,
  IconInfoCircle,
  IconLink,
  IconMail,
  IconProgressCheck,
  IconSend,
  IconTrash,
  IconRefresh,
} from "@tabler/icons-react";
import moment from "moment";
import React, { useRef, useState } from "react";
import { useNavigate } from "react-router";
import { createEDMTemplate, deleteEDMTemplate, sendEDMTestEmail, updateEDMTemplate } from "@/lib/features/edm/action";
import type { AccessScope } from "@/lib/features/types";
import type { EDMTemplate } from "@/lib/features/edm/types";
import { useRoleAccess } from "@/hooks/useRoleAccess";
import { WorkflowSidebar } from "@/components/WorkflowSidebar";
import { EDMLogsPanel } from "../_components/EDMLogsPanel";
import { EDMHtmlEditor } from "../_components/EDMHtmlEditor";
import { TestFlowPanel } from "./test-flow/TestFlowPanel";

interface Props {
  initialTemplate: EDMTemplate | null;
  isNew: boolean;
  initialError?: string;
  accessScope: AccessScope;
}

export default function EDMEditorClientPage({ initialTemplate, isNew, initialError, accessScope }: Props) {
  const navigate = useNavigate();
  const { checkClientAccess } = useRoleAccess();
  const canViewAdminLogs = checkClientAccess("read", "admin-logs");
  const activeVer = initialTemplate?.versions.find((v) => v.active === 1) ?? initialTemplate?.versions[0] ?? null;

  const [name, setName] = useState(initialTemplate?.name ?? "");
  const [subject, setSubject] = useState(activeVer?.subject ?? "");
  const [htmlContent, setHtmlContent] = useState(activeVer?.html_content ?? "");
  const [plainContent, setPlainContent] = useState(activeVer?.plain_content ?? "");
  const [active, setActive] = useState<0 | 1>(activeVer?.active ?? 1);
  const [generatePlain, setGeneratePlain] = useState(activeVer?.generate_plain_content ?? true);
  const [saving, setSaving] = useState(false);
  const [partialError, setPartialError] = useState<{ templateId: string; message: string } | null>(null);

  const [deleteOpened, { open: openDelete, close: closeDelete }] = useDisclosure(false);
  const [deleting, setDeleting] = useState(false);

  const [sendEmailOpened, { open: openSendEmail, close: closeSendEmail }] = useDisclosure(false);
  const [sendToEmails, setSendToEmails] = useState<string[]>([]);
  const [sending, setSending] = useState(false);

  const [sentSuccessOpened, { open: openSentSuccess, close: closeSentSuccess }] = useDisclosure(false);
  const [lastSentTo, setLastSentTo] = useState("");

  const htmlFileResetRef = useRef<() => void>(null);
  const plainFileResetRef = useRef<() => void>(null);

  const handleHtmlFileUpload = (file: File | null) => {
    if (!file) return;
    const reader = new FileReader();
    reader.onload = (e) => {
      const text = e.target?.result as string;
      setHtmlContent(text);
    };
    reader.readAsText(file);
  };

  const handlePlainFileUpload = (file: File | null) => {
    if (!file) return;
    const reader = new FileReader();
    reader.onload = (e) => {
      const text = e.target?.result as string;
      setPlainContent(text);
    };
    reader.readAsText(file);
  };

  const handleSave = async () => {
    if (!name.trim()) {
      notifications.show({ color: "red", message: "Template name is required" });
      return;
    }
    if (!subject.trim()) {
      notifications.show({ color: "red", message: "Subject line is required" });
      return;
    }
    setSaving(true);
    setPartialError(null);
    try {
      if (isNew) {
        const res = await createEDMTemplate({ name: name.trim(), subject: subject.trim(), html_content: htmlContent, plain_content: plainContent || undefined, active, generate_plain_content: generatePlain });
        if (res.success && res.data) {
          notifications.show({ color: "green", message: "Template created" });
          navigate(`/admin/edm/${res.data.id}`);
        } else if ((res as any).partial) {
          setPartialError({ templateId: (res as any).templateId, message: res.message ?? "Template shell created but version failed. Edit to retry." });
        } else {
          notifications.show({ color: "red", message: res.message || "Create failed" });
        }
      } else {
        const res = await updateEDMTemplate(initialTemplate!.id, { name: name.trim(), subject: subject.trim(), html_content: htmlContent, plain_content: plainContent || undefined, active, generate_plain_content: generatePlain });
        if (res.success) {
          notifications.show({ color: "green", message: "Template saved" });
        } else {
          notifications.show({ color: "red", message: res.message || "Save failed" });
        }
      }
    } catch {
      notifications.show({ color: "red", message: "Save failed" });
    } finally {
      setSaving(false);
    }
  };

  const handleDelete = async () => {
    if (!initialTemplate) return;
    setDeleting(true);
    try {
      const res = await deleteEDMTemplate(initialTemplate.id);
      if (res.success) {
        notifications.show({ color: "green", message: "Template deleted" });
        navigate("/admin/edm");
      } else {
        notifications.show({ color: "red", message: res.message || "Delete failed" });
      }
    } catch {
      notifications.show({ color: "red", message: "Delete failed" });
    } finally {
      setDeleting(false);
    }
  };

  const handleDownloadHtml = () => {
    const blob = new Blob([htmlContent], { type: "text/html" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = `${name.trim() || "email-template"}.html`;
    a.click();
    URL.revokeObjectURL(url);
  };

  const handleRegeneratePlain = () => {
    if (!htmlContent) {
      notifications.show({ color: "orange", message: "No HTML content to generate from" });
      return;
    }
    const tempDiv = document.createElement("div");
    tempDiv.innerHTML = htmlContent;

    // Remove scripts and styles so they don't appear in plain text
    const scriptsAndStyles = tempDiv.querySelectorAll("script, style");
    scriptsAndStyles.forEach((el) => el.remove());

    const text = tempDiv.innerText || tempDiv.textContent || "";
    const cleanedText = text.replace(/\n\s*\n/g, '\n\n').trim();
    setPlainContent(cleanedText);
    notifications.show({ color: "blue", message: "Plain text generated from HTML" });
  };

  const handleSendEmail = async () => {
    if (sendToEmails.length === 0) {
      notifications.show({ color: "red", message: "At least one email address is required" });
      return;
    }
    setSending(true);
    try {
      const res = await sendEDMTestEmail(initialTemplate!.id, sendToEmails.join(","));
      if (res.success) {
        setLastSentTo(sendToEmails.join(", "));
        openSentSuccess();
        closeSendEmail();
        setSendToEmails([]);
      } else {
        notifications.show({ color: "red", message: res.message || "Send failed" });
      }
    } catch {
      notifications.show({ color: "red", message: "Send failed" });
    } finally {
      setSending(false);
    }
  };

  const canEdit = isNew ? accessScope.create : accessScope.update;

  /** Approval drawer. Only meaningful once the template exists. */
  const [workflowOpen, setWorkflowOpen] = useState(false);

  return (
    <Container fluid px="xl" py="xl">
      {/* Header */}
      <Group justify="space-between" mb="lg">
        <Group gap="sm">
          <Button variant="subtle" size="compact-sm" leftSection={<IconArrowLeft size={14} />} onClick={() => navigate("/admin/edm")}>
            Back
          </Button>
          <IconMail size={24} />
          <Title order={2}>{isNew ? "New Email Template" : name || "Email Template"}</Title>
          {!isNew && activeVer && (
            <Badge color={activeVer.active === 1 ? "green" : "gray"} variant="light">
              {activeVer.active === 1 ? "Active" : "Inactive"}
            </Badge>
          )}
        </Group>
        <Group>
          {!isNew && initialTemplate?.id && (
            <Button
              variant="light"
              color="grape"
              leftSection={<IconProgressCheck size={16} />}
              onClick={() => setWorkflowOpen(true)}
            >
              Approval
            </Button>
          )}
          {!isNew && accessScope.delete && (
            <Button variant="subtle" color="red" leftSection={<IconTrash size={16} />} onClick={openDelete}>
              Delete
            </Button>
          )}
          {!isNew && htmlContent && (
            <Button variant="light" color="blue" leftSection={<IconSend size={16} />} onClick={openSendEmail}>
              Send as Email
            </Button>
          )}
          {canEdit && (
            <Button leftSection={<IconDeviceFloppy size={16} />} onClick={handleSave} loading={saving}>
              {isNew ? "Create Template" : "Save Changes"}
            </Button>
          )}
        </Group>
      </Group>

      {initialError && <Alert color="red" icon={<IconAlertCircle size={16} />} mb="lg">{initialError}</Alert>}

      {partialError && (
        <Alert color="orange" icon={<IconAlertCircle size={16} />} mb="lg" title="Partial creation — template shell created">
          <Text size="sm">{partialError.message}</Text>
          <Text size="xs" c="dimmed" ff="monospace" mt={4}>{partialError.templateId}</Text>
          <Text size="xs" mt={4}>The template was created in SendGrid but the version (HTML/subject) failed. You can still edit and save to retry.</Text>
        </Alert>
      )}

      <Tabs defaultValue="details">
        <Tabs.List mb="md">
          <Tabs.Tab value="details" leftSection={<IconInfoCircle size={14} />}>Details</Tabs.Tab>
          <Tabs.Tab value="html" leftSection={<IconCode size={14} />}>HTML Content</Tabs.Tab>
          <Tabs.Tab value="plain" leftSection={<IconFileUpload size={14} />}>Plain Content</Tabs.Tab>
          {!isNew && <Tabs.Tab value="info" leftSection={<IconEye size={14} />}>Template Info</Tabs.Tab>}
          {!isNew && canViewAdminLogs && <Tabs.Tab value="logs" leftSection={<IconHistory size={14} />}>Logs</Tabs.Tab>}
          {!isNew && accessScope.read && <Tabs.Tab value="test" leftSection={<IconChecklist size={14} />}>Test the Template</Tabs.Tab>}
        </Tabs.List>

        {/* Details tab */}
        <Tabs.Panel value="details">
          <Paper withBorder radius="md" p="lg">
            <Stack gap="md" style={{ maxWidth: 560 }}>
              <TextInput
                label="Template Name"
                placeholder="e.g. Welcome Email"
                value={name}
                onChange={(e) => setName(e.currentTarget.value)}
                required
                readOnly={!canEdit}
              />
              <TextInput
                label="Subject Line"
                placeholder="e.g. Welcome to Karma!"
                value={subject}
                onChange={(e) => setSubject(e.currentTarget.value)}
                required
                readOnly={!canEdit}
              />
              <Switch
                label="Active"
                description="Only one version can be active per template"
                checked={active === 1}
                onChange={(e) => setActive(e.currentTarget.checked ? 1 : 0)}
                disabled={!canEdit}
              />
            </Stack>
          </Paper>
        </Tabs.Panel>

        {/* HTML Content tab */}
        <Tabs.Panel value="html">
          <Stack gap="md">
            {canEdit && (
              <Paper withBorder radius="md" p="md">
                <Group>
                  <FileButton resetRef={htmlFileResetRef} onChange={handleHtmlFileUpload} accept=".html,.htm">
                    {(props) => (
                      <Button {...props} variant="light" leftSection={<IconFileUpload size={16} />}>
                        Upload HTML File
                      </Button>
                    )}
                  </FileButton>
                  {htmlContent && (
                    <Button variant="subtle" color="gray" size="compact-sm" onClick={() => { setHtmlContent(""); htmlFileResetRef.current?.(); }}>
                      Clear
                    </Button>
                  )}
                  <Text size="sm" c="dimmed">.html or .htm files only</Text>
                </Group>
              </Paper>
            )}

            {htmlContent ? (
              <Paper withBorder radius="md" p={0} style={{ overflow: "hidden" }}>
                <Group px="md" py="xs" justify="space-between" style={{ borderBottom: "1px solid var(--mantine-color-default-border)" }}>
                  <Group gap="xs">
                    <IconEye size={14} />
                    <Text size="sm" fw={500}>HTML Preview</Text>
                  </Group>
                  <Group gap="xs">
                    <Button variant="subtle" size="compact-sm" leftSection={<IconEye size={14} />} onClick={() => {
                      if (!isNew && initialTemplate) {
                        window.open(`/public/edm/preview/${initialTemplate.id}`, '_blank');
                      } else {
                        localStorage.setItem('edm_preview_html', htmlContent);
                        window.open('/admin/edm/preview', '_blank');
                      }
                    }}>
                      View in Browser
                    </Button>
                    <Button variant="subtle" size="compact-sm" leftSection={<IconDownload size={14} />} onClick={handleDownloadHtml}>
                      Download HTML
                    </Button>
                  </Group>
                </Group>
                <iframe
                  srcDoc={htmlContent}
                  style={{ width: "100%", height: 600, border: "none", display: "block" }}
                  sandbox="allow-scripts allow-same-origin"
                  title="HTML Preview"
                />
              </Paper>
            ) : (
              <Paper withBorder radius="md" p="xl">
                <Stack align="center" gap="xs">
                  <IconCode size={40} opacity={0.3} />
                  <Text c="dimmed" size="md">No HTML content yet.</Text>
                  {canEdit && <Text c="dimmed" size="sm">Upload an HTML file above to preview it here.</Text>}
                </Stack>
              </Paper>
            )}

            {canEdit && (
              <Paper withBorder radius="md" p="md">
                <Text size="sm" fw={500} mb="xs">Edit HTML directly</Text>
                <EDMHtmlEditor value={htmlContent} onChange={setHtmlContent} />
              </Paper>
            )}
          </Stack>
        </Tabs.Panel>

        {/* Plain Content tab */}
        <Tabs.Panel value="plain">
          <Paper withBorder radius="md" p="lg">
            <Stack gap="md">
              {canEdit && (
                <Group>
                  <FileButton resetRef={plainFileResetRef} onChange={handlePlainFileUpload} accept=".txt">
                    {(props) => (
                      <Button {...props} variant="light" leftSection={<IconFileUpload size={16} />}>
                        Upload .txt File
                      </Button>
                    )}
                  </FileButton>
                  {plainContent && (
                    <Button variant="subtle" color="gray" size="compact-sm" onClick={() => { setPlainContent(""); plainFileResetRef.current?.(); }}>
                      Clear
                    </Button>
                  )}
                </Group>
              )}
              <Switch
                label="Auto-generate plain text"
                description="Automatically convert the HTML to plain text. Check this if you don't want to write it manually."
                checked={generatePlain}
                onChange={(e) => setGeneratePlain(e.currentTarget.checked)}
                disabled={!canEdit}
              />
              <Textarea
                label="Plain Text Content"
                description="Fallback for email clients that don't support HTML"
                value={plainContent}
                onChange={(e) => setPlainContent(e.currentTarget.value)}
                readOnly={!canEdit}
                autosize
                minRows={10}
                maxRows={30}
                styles={{ input: { fontFamily: "monospace", fontSize: 13 } }}
                placeholder="Plain text version of the email…"
              />
            </Stack>
          </Paper>
        </Tabs.Panel>

        {/* Template Info tab (existing templates only) */}
        {!isNew && (
          <Tabs.Panel value="info">
            <Paper withBorder radius="md" p="lg">
              <Stack gap="md" style={{ maxWidth: 560 }}>
                <Group>
                  <Text size="sm" fw={500} w={160}>Template ID</Text>
                  <Text size="sm" ff="monospace" c="dimmed">{initialTemplate?.id ?? "—"}</Text>
                </Group>
                <Group>
                  <Text size="sm" fw={500} w={160}>Version ID</Text>
                  <Text size="sm" ff="monospace" c="dimmed">{activeVer?.id ?? "—"}</Text>
                </Group>
                <Group>
                  <Text size="sm" fw={500} w={160}>Generation</Text>
                  <Badge variant="outline" size="sm">{initialTemplate?.generation ?? "—"}</Badge>
                </Group>
                <Group>
                  <Text size="sm" fw={500} w={160}>Version Name</Text>
                  <Text size="sm" c="dimmed">{activeVer?.name ?? "—"}</Text>
                </Group>
                <Group>
                  <Text size="sm" fw={500} w={160}>Editor</Text>
                  <Text size="sm" c="dimmed">{activeVer?.editor ?? "—"}</Text>
                </Group>
                <Group>
                  <Text size="sm" fw={500} w={160}>Template Updated</Text>
                  <Text size="sm" c="dimmed">
                    {initialTemplate?.updated_at ? moment(initialTemplate.updated_at).format("DD MMM YYYY, HH:mm") : "—"}
                  </Text>
                </Group>
                <Group>
                  <Text size="sm" fw={500} w={160}>Version Updated</Text>
                  <Text size="sm" c="dimmed">
                    {activeVer?.updated_at ? moment(activeVer.updated_at).format("DD MMM YYYY, HH:mm") : "—"}
                  </Text>
                </Group>
                {initialTemplate && initialTemplate.versions.length > 1 && (
                  <>
                    <Text size="sm" fw={500} mt="xs">All Versions ({initialTemplate.versions.length})</Text>
                    {initialTemplate.versions.map((v) => (
                      <Paper key={v.id} withBorder radius="sm" p="sm">
                        <Group justify="space-between">
                          <Stack gap={2}>
                            <Text size="sm" fw={500}>{v.name}</Text>
                            <Text size="xs" ff="monospace" c="dimmed">{v.id}</Text>
                            <Text size="xs" c="dimmed">{v.subject}</Text>
                          </Stack>
                          <Badge color={v.active === 1 ? "green" : "gray"} variant="light" size="sm">
                            {v.active === 1 ? "Active" : "Inactive"}
                          </Badge>
                        </Group>
                      </Paper>
                    ))}
                  </>
                )}
              </Stack>
            </Paper>
          </Tabs.Panel>
        )}

        {/* Logs tab */}
        {!isNew && canViewAdminLogs && (
          <Tabs.Panel value="logs">
            <Paper withBorder radius="md" p="lg">
              <EDMLogsPanel templateId={initialTemplate?.id} />
            </Paper>
          </Tabs.Panel>
        )}

        {/* Test the Template tab — QA checks against the current editor content */}
        {!isNew && accessScope.read && (
          <Tabs.Panel value="test">
            <TestFlowPanel
              template={{ name, subject, htmlContent, plainContent }}
              canRun={accessScope.update}
            />
          </Tabs.Panel>
        )}
      </Tabs>

      {/* Delete confirmation modal */}
      <Modal opened={deleteOpened} onClose={closeDelete} title="Delete Email Template" centered size="sm">
        <Stack>
          <Text size="sm">
            Are you sure you want to delete{" "}
            <Text span fw={700}>{initialTemplate?.name}</Text>?
            This will permanently delete the template and all its versions from SendGrid.
          </Text>
          <Text size="xs" c="dimmed" ff="monospace">{initialTemplate?.id}</Text>
          <Group justify="flex-end">
            <Button variant="subtle" onClick={closeDelete}>Cancel</Button>
            <Button color="red" onClick={handleDelete} loading={deleting}>Delete</Button>
          </Group>
        </Stack>
      </Modal>

      {/* Send as Email modal */}
      <Modal
        opened={sendEmailOpened}
        onClose={() => { closeSendEmail(); setSendToEmails([]); }}
        title="Send as Email"
        centered
        size="sm"
      >
        <Stack>
          <Text size="sm">Send this EDM template as a test.</Text>
          <TagsInput
            label="Recipient Emails"
            description="Type an email and press Enter"
            placeholder="e.g. test@example.com"
            value={sendToEmails}
            onChange={setSendToEmails}
            clearable
            required
          />
          <Group justify="flex-end">
            <Button variant="subtle" onClick={() => { closeSendEmail(); setSendToEmails([]); }}>Cancel</Button>
            <Button leftSection={<IconSend size={14} />} onClick={handleSendEmail} loading={sending}>Send</Button>
          </Group>
        </Stack>
      </Modal>

      {/* Success confirmation modal */}
      <Modal opened={sentSuccessOpened} onClose={closeSentSuccess} title="Email Sent" centered size="sm">
        <Stack align="center" gap="md" py="md">
          <IconMail size={48} color="var(--mantine-color-green-6)" />
          <Text size="md" ta="center">
            EDM Email successfully sent to:
            <br />
            <Text span fw={700}>{lastSentTo}</Text>
          </Text>
          <Button onClick={closeSentSuccess} fullWidth mt="sm">Close</Button>
        </Stack>
      </Modal>

      {workflowOpen && initialTemplate?.id && (
        <WorkflowSidebar
          opened
          onClose={() => setWorkflowOpen(false)}
          entityType="EDM_TEMPLATE"
          entityId={initialTemplate.id}
          crTargets={[
            { value: initialTemplate.id, label: initialTemplate.name ?? initialTemplate.id },
          ]}
          defaultCrTarget={initialTemplate.id}
        />
      )}
    </Container>
  );
}
