import { useEffect, useMemo, useState } from "react";
import {
  Alert,
  Badge,
  Button,
  Code,
  Container,
  Group,
  Paper,
  Select,
  Stack,
  Table,
  Text,
  TextInput,
  Textarea,
  Title,
} from "@mantine/core";
import { notifications } from "@mantine/notifications";
import { IconAlertCircle, IconFileText } from "@tabler/icons-react";
import { AxiosError } from "axios";
import { apiClient } from "../lib/api";
import type {
  TemplateInfo,
  TemplateUploadComponent,
  TemplateUploadRequest,
  WhatsAppAccountConfig,
} from "../types";

function toPrettyJSON(value: unknown): string {
  return JSON.stringify(value, null, 2);
}

function extractErrorPayload(error: unknown): unknown {
  if (error instanceof AxiosError) return error.response?.data ?? { message: error.message };
  if (error instanceof Error) return { message: error.message };
  return { message: "Request failed" };
}

function formatError(error: unknown): string {
  if (error instanceof AxiosError) {
    if (typeof error.response?.data === "string") return error.response.data;
    if (error.response?.data && typeof error.response.data === "object") return toPrettyJSON(error.response.data);
    return error.message;
  }
  if (error instanceof Error) return error.message;
  return "Request failed";
}

function parseComponents(input: string): TemplateUploadComponent[] {
  const parsed = JSON.parse(input) as unknown;
  if (!Array.isArray(parsed)) {
    throw new Error("Components must be a JSON array");
  }
  return parsed as TemplateUploadComponent[];
}

export default function TemplateManagementPage() {
  const [accounts, setAccounts] = useState<WhatsAppAccountConfig[]>([]);
  const [loadingAccounts, setLoadingAccounts] = useState(true);
  const [accountId, setAccountId] = useState("");

  const [templates, setTemplates] = useState<TemplateInfo[]>([]);

  const [uploadName, setUploadName] = useState("");
  const [uploadLanguage, setUploadLanguage] = useState("en_US");
  const [uploadCategory, setUploadCategory] = useState("UTILITY");
  const [uploadComponents, setUploadComponents] = useState(
    '[{"type":"BODY","text":"Hello {{1}}"}]',
  );

  const [deleteName, setDeleteName] = useState("");
  const [deleteLanguage, setDeleteLanguage] = useState("en_US");

  const [actionLoading, setActionLoading] = useState<Record<string, boolean>>({});
  const [responseHistory, setResponseHistory] = useState<
    Array<{
      id: string;
      title: string;
      status: "success" | "error";
      payload: unknown;
      createdAt: string;
    }>
  >([]);

  const businessAccounts = useMemo(
    () =>
      accounts
        .filter((entry) => entry.type === "business-api" && !entry.disabled)
        .sort((a, b) => a.id.localeCompare(b.id, undefined, { sensitivity: "base" })),
    [accounts],
  );

  useEffect(() => {
    const loadAccounts = async () => {
      try {
        setLoadingAccounts(true);
        const result = await apiClient.getAccountConfigs();
        setAccounts(result || []);
      } catch (error) {
        notifications.show({ title: "Error", message: "Failed to load accounts", color: "red" });
      } finally {
        setLoadingAccounts(false);
      }
    };
    loadAccounts();
  }, []);

  useEffect(() => {
    if (!accountId && businessAccounts.length > 0) {
      setAccountId(businessAccounts[0].id);
    }
  }, [businessAccounts, accountId]);

  const appendResponse = (entry: { title: string; status: "success" | "error"; payload: unknown }) => {
    const item = {
      id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
      createdAt: new Date().toISOString(),
      ...entry,
    };
    setResponseHistory((prev) => [item, ...prev].slice(0, 20));
    if (entry.status === "success") {
      console.info(`[Templates] ${entry.title} success`, entry.payload);
    } else {
      console.error(`[Templates] ${entry.title} error`, entry.payload);
    }
  };

  const runAction = async <T,>(key: string, actionTitle: string, action: () => Promise<T>) => {
    if (!accountId) {
      notifications.show({ title: "Validation Error", message: "Select a business account", color: "red" });
      return undefined;
    }

    try {
      setActionLoading((prev) => ({ ...prev, [key]: true }));
      const result = await action();
      appendResponse({ title: actionTitle, status: "success", payload: result });
      return result;
    } catch (error) {
      appendResponse({ title: actionTitle, status: "error", payload: extractErrorPayload(error) });
      notifications.show({ title: "Request Failed", message: formatError(error), color: "red" });
      return undefined;
    } finally {
      setActionLoading((prev) => ({ ...prev, [key]: false }));
    }
  };

  const handleListTemplates = async () => {
    const result = await runAction("list", "List Templates", async () => apiClient.listTemplates(accountId));
    if (result) {
      setTemplates(result.data || []);
      notifications.show({ title: "Success", message: `Loaded ${result.data?.length || 0} templates`, color: "green" });
    }
  };

  const handleUploadTemplate = async (e: React.FormEvent) => {
    e.preventDefault();

    let components: TemplateUploadComponent[];
    try {
      components = parseComponents(uploadComponents);
    } catch (error) {
      notifications.show({
        title: "Validation Error",
        message: error instanceof Error ? error.message : "Invalid components JSON",
        color: "red",
      });
      return;
    }

    const payload: TemplateUploadRequest = {
      account_id: accountId,
      name: uploadName.trim(),
      language: uploadLanguage.trim(),
      category: uploadCategory,
      components,
    };

    const result = await runAction("upload", "Upload Template", async () => {
      const response = await apiClient.uploadTemplate(payload);
      return { payload, response };
    });

    if (result) {
      notifications.show({ title: "Success", message: "Template upload requested", color: "green" });
      await handleListTemplates();
    }
  };

  const handleDeleteTemplate = async (e: React.FormEvent) => {
    e.preventDefault();

    const payload = {
      account_id: accountId,
      name: deleteName.trim(),
      language: deleteLanguage.trim(),
    };

    const result = await runAction("delete", "Delete Template", async () => {
      const response = await apiClient.deleteTemplate(payload);
      return { payload, response };
    });

    if (result) {
      notifications.show({ title: "Success", message: "Template deleted", color: "green" });
      await handleListTemplates();
    }
  };

  const accountOptions = businessAccounts.map((entry) => ({
    value: entry.id,
    label: `${entry.id} (business-api)`,
  }));

  return (
    <Container size="xl" py="xl">
      <Stack gap="lg">
        <div>
          <Title order={2}>Business Template Management</Title>
          <Text c="dimmed" size="sm">
            List, upload, and delete WhatsApp Business templates.
          </Text>
        </div>

        <Paper withBorder p="md">
          <Stack gap="sm">
            <Group justify="space-between">
              <Text fw={600}>Business Account</Text>
              <Badge variant="light" color="blue">
                {businessAccounts.length} business account(s)
              </Badge>
            </Group>
            <Select
              label="Account"
              data={accountOptions}
              value={accountId}
              onChange={(value) => setAccountId(value || "")}
              searchable
              disabled={loadingAccounts}
              placeholder="Select an account"
            />
            {businessAccounts.length === 0 && !loadingAccounts && (
              <Alert icon={<IconAlertCircle size={16} />} color="yellow" title="No Business API Accounts">
                No enabled `business-api` accounts were found.
              </Alert>
            )}
          </Stack>
        </Paper>

        <Paper withBorder p="md">
          <Stack>
            <Group justify="space-between">
              <Text fw={600}>Templates</Text>
              <Button onClick={handleListTemplates} loading={!!actionLoading.list} disabled={!accountId}>
                List Templates
              </Button>
            </Group>

            <Table withTableBorder withColumnBorders>
              <Table.Thead>
                <Table.Tr>
                  <Table.Th>Name</Table.Th>
                  <Table.Th>Language</Table.Th>
                  <Table.Th>Category</Table.Th>
                  <Table.Th>Status</Table.Th>
                  <Table.Th>Template ID</Table.Th>
                </Table.Tr>
              </Table.Thead>
              <Table.Tbody>
                {templates.length === 0 ? (
                  <Table.Tr>
                    <Table.Td colSpan={5}>
                      <Group justify="center" py="md">
                        <IconFileText size={20} />
                        <Text c="dimmed">No templates loaded yet.</Text>
                      </Group>
                    </Table.Td>
                  </Table.Tr>
                ) : (
                  templates.map((template) => (
                    <Table.Tr key={template.id}>
                      <Table.Td>{template.name}</Table.Td>
                      <Table.Td>{template.language}</Table.Td>
                      <Table.Td>{template.category}</Table.Td>
                      <Table.Td>{template.status}</Table.Td>
                      <Table.Td>
                        <Code>{template.id}</Code>
                      </Table.Td>
                    </Table.Tr>
                  ))
                )}
              </Table.Tbody>
            </Table>
          </Stack>
        </Paper>

        <Paper withBorder p="md">
          <form onSubmit={handleUploadTemplate}>
            <Stack>
              <Text fw={600}>Upload Template</Text>
              <Group grow>
                <TextInput label="Name" value={uploadName} onChange={(e) => setUploadName(e.currentTarget.value)} required />
                <TextInput label="Language" value={uploadLanguage} onChange={(e) => setUploadLanguage(e.currentTarget.value)} required />
                <Select
                  label="Category"
                  value={uploadCategory}
                  onChange={(value) => setUploadCategory(value || "UTILITY")}
                  data={[
                    { value: "MARKETING", label: "MARKETING" },
                    { value: "UTILITY", label: "UTILITY" },
                    { value: "AUTHENTICATION", label: "AUTHENTICATION" },
                  ]}
                  required
                />
              </Group>
              <Textarea
                label="Components JSON"
                description="Array of template components"
                value={uploadComponents}
                onChange={(e) => setUploadComponents(e.currentTarget.value)}
                minRows={6}
                required
              />
              <Button type="submit" loading={!!actionLoading.upload} disabled={!accountId}>
                Upload Template
              </Button>
            </Stack>
          </form>
        </Paper>

        <Paper withBorder p="md">
          <form onSubmit={handleDeleteTemplate}>
            <Stack>
              <Text fw={600}>Delete Template</Text>
              <Group grow>
                <TextInput label="Template Name" value={deleteName} onChange={(e) => setDeleteName(e.currentTarget.value)} required />
                <TextInput
                  label="Language"
                  value={deleteLanguage}
                  onChange={(e) => setDeleteLanguage(e.currentTarget.value)}
                  required
                />
              </Group>
              <Button type="submit" color="red" loading={!!actionLoading.delete} disabled={!accountId}>
                Delete Template
              </Button>
            </Stack>
          </form>
        </Paper>

        {responseHistory.length > 0 && (
          <Stack gap="sm">
            <Group justify="space-between">
              <Text fw={600}>Response History</Text>
              <Button variant="subtle" color="gray" size="xs" onClick={() => setResponseHistory([])}>
                Clear
              </Button>
            </Group>
            {responseHistory.map((entry) => (
              <Paper key={entry.id} withBorder p="md">
                <Text fw={600} size="sm" mb="xs">
                  {`${entry.title} - ${entry.status.toUpperCase()} - ${new Date(entry.createdAt).toLocaleString()}`}
                </Text>
                <Code block>{toPrettyJSON(entry.payload)}</Code>
              </Paper>
            ))}
          </Stack>
        )}
      </Stack>
    </Container>
  );
}
