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

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

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 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 websitesToText(websites?: string[]): string {
  return (websites || []).join("\n");
}

function parseWebsitesInput(input: string): string[] {
  return input
    .split(/[\n,]/)
    .map((entry) => entry.trim())
    .filter((entry) => entry.length > 0);
}

type ResultPanelProps = {
  title: string;
  payload: unknown;
};

function ResultPanel({ title, payload }: ResultPanelProps) {
  return (
    <Paper withBorder p="md">
      <Text fw={600} size="sm" mb="xs">
        {title}
      </Text>
      <Code block>{toPrettyJSON(payload)}</Code>
    </Paper>
  );
}

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

  const [phoneNumberIdForCode, setPhoneNumberIdForCode] = useState("");
  const [codeMethod, setCodeMethod] = useState<"SMS" | "VOICE">("SMS");
  const [language, setLanguage] = useState("en_US");

  const [phoneNumberIdForVerify, setPhoneNumberIdForVerify] = useState("");
  const [verificationCode, setVerificationCode] = useState("");

  const [phoneNumberIdForRegister, setPhoneNumberIdForRegister] = useState("");
  const [pin, setPin] = useState("");

  const [businessProfile, setBusinessProfile] = useState<BusinessProfile | null>(null);
  const [about, setAbout] = useState("");
  const [address, setAddress] = useState("");
  const [description, setDescription] = useState("");
  const [email, setEmail] = useState("");
  const [websites, setWebsites] = useState("");
  const [vertical, setVertical] = useState("");

  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],
  );

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

  const phoneNumberOptions = phoneNumbers.map((entry) => ({
    value: entry.id,
    label: `${entry.display_phone_number || entry.phone_number} (${entry.id})`,
  }));

  useEffect(() => {
    const loadAccounts = async () => {
      try {
        setLoadingAccounts(true);
        const result = await apiClient.getAccountConfigs();
        setAccounts(result || []);
      } catch (error) {
        notifications.show({
          title: "Error",
          message: "Failed to load WhatsApp accounts",
          color: "red",
        });
        console.error(error);
      } 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(`[WhatsApp Business] ${entry.title} success`, entry.payload);
    } else {
      console.error(`[WhatsApp Business] ${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 first",
        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",
      });
      console.error(error);
      return undefined;
    } finally {
      setActionLoading((prev) => ({ ...prev, [key]: false }));
    }
  };

  const handleListPhoneNumbers = async () => {
    const result = await runAction("listPhoneNumbers", "List Phone Numbers", async () => {
      return apiClient.listPhoneNumbers(accountId);
    });

    if (result) {
      setPhoneNumbers(result.data || []);
      notifications.show({
        title: "Success",
        message: `Loaded ${result.data?.length || 0} phone number(s)`,
        color: "green",
      });
    }
  };

  const handleRequestVerificationCode = async (e: React.FormEvent) => {
    e.preventDefault();
    const response = await runAction("requestCode", "Request Verification Code", async () => {
      return apiClient.requestVerificationCode({
        account_id: accountId,
        phone_number_id: phoneNumberIdForCode.trim(),
        code_method: codeMethod,
        language: language.trim() || "en_US",
      });
    });

    if (response) {
      notifications.show({
        title: "Success",
        message: "Verification code requested",
        color: "green",
      });
    }
  };

  const handleVerifyCode = async (e: React.FormEvent) => {
    e.preventDefault();
    const response = await runAction("verifyCode", "Verify Code", async () => {
      return apiClient.verifyPhoneCode({
        account_id: accountId,
        phone_number_id: phoneNumberIdForVerify.trim(),
        code: verificationCode.trim(),
      });
    });

    if (response) {
      notifications.show({
        title: "Success",
        message: "Verification code accepted",
        color: "green",
      });
    }
  };

  const handleRegisterPhoneNumber = async (e: React.FormEvent) => {
    e.preventDefault();
    const response = await runAction("registerPhoneNumber", "Register Phone Number", async () => {
      return apiClient.registerPhoneNumber({
        account_id: accountId,
        phone_number_id: phoneNumberIdForRegister.trim(),
        pin: pin.trim(),
      });
    });

    if (response) {
      notifications.show({
        title: "Success",
        message: "Phone number registration submitted",
        color: "green",
      });
    }
  };

  const handleGetBusinessProfile = async () => {
    const profile = await runAction("getBusinessProfile", "Get Business Profile", async () => {
      return apiClient.getBusinessProfile(accountId);
    });

    if (profile) {
      setBusinessProfile(profile);
      setAbout(profile.about || "");
      setAddress(profile.address || "");
      setDescription(profile.description || "");
      setEmail(profile.email || "");
      setWebsites(websitesToText(profile.websites));
      setVertical(profile.vertical || "");
      notifications.show({
        title: "Success",
        message: "Business profile loaded",
        color: "green",
      });
    }
  };

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

    const payload = {
      account_id: accountId,
      about: about.trim(),
      address: address.trim(),
      description: description.trim(),
      email: email.trim(),
      websites: parseWebsitesInput(websites),
      vertical: vertical.trim(),
    };

    const response = await runAction("updateBusinessProfile", "Update Business Profile", async () => {
      const result = await apiClient.updateBusinessProfile(payload);
      return { payload, response: result };
    });

    if (response) {
      notifications.show({
        title: "Success",
        message: "Business profile updated",
        color: "green",
      });
    }
  };

  return (
    <Container size="xl" py="xl">
      <Stack gap="lg">
        <div>
          <Title order={2}>WhatsApp Business Management</Title>
          <Text c="dimmed" size="sm">
            Select a business account, then manage phone number verification/registration and business profile details.
          </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. Add one in the WhatsApp Accounts page first.
              </Alert>
            )}
          </Stack>
        </Paper>

        <Paper withBorder p="md">
          <Stack gap="md">
            <Group>
              <IconPhoneCall size={20} />
              <Text fw={600}>Phone Number Management</Text>
            </Group>

            <Group>
              <Button
                onClick={handleListPhoneNumbers}
                loading={!!actionLoading.listPhoneNumbers}
                disabled={!accountId}
              >
                List Phone Numbers
              </Button>
            </Group>

            {phoneNumbers.length > 0 && (
              <Table withTableBorder withColumnBorders>
                <Table.Thead>
                  <Table.Tr>
                    <Table.Th>Display Number</Table.Th>
                    <Table.Th>Verified Name</Table.Th>
                    <Table.Th>Status</Table.Th>
                    <Table.Th>Quality</Table.Th>
                    <Table.Th>Throughput</Table.Th>
                    <Table.Th>Phone Number ID</Table.Th>
                  </Table.Tr>
                </Table.Thead>
                <Table.Tbody>
                  {phoneNumbers.map((entry) => (
                    <Table.Tr key={entry.id}>
                      <Table.Td>{entry.display_phone_number || "-"}</Table.Td>
                      <Table.Td>{entry.verified_name || "-"}</Table.Td>
                      <Table.Td>{entry.code_verification_status || "-"}</Table.Td>
                      <Table.Td>{entry.quality_rating || "-"}</Table.Td>
                      <Table.Td>{entry.throughput?.level || "-"}</Table.Td>
                      <Table.Td>
                        <Code>{entry.id}</Code>
                      </Table.Td>
                    </Table.Tr>
                  ))}
                </Table.Tbody>
              </Table>
            )}

            <SimpleGrid cols={{ base: 1, lg: 3 }}>
              <Paper withBorder p="sm">
                <form onSubmit={handleRequestVerificationCode}>
                  <Stack>
                    <Text fw={600} size="sm">
                      Request Verification Code
                    </Text>
                    <Select
                      label="Phone Number ID"
                      data={phoneNumberOptions}
                      value={phoneNumberIdForCode}
                      onChange={(value) => setPhoneNumberIdForCode(value || "")}
                      searchable
                      clearable
                    />
                    <TextInput
                      label="Or enter ID manually"
                      value={phoneNumberIdForCode}
                      onChange={(e) => setPhoneNumberIdForCode(e.currentTarget.value)}
                      required
                    />
                    <Select
                      label="Code Method"
                      value={codeMethod}
                      onChange={(value) => setCodeMethod((value as "SMS" | "VOICE") || "SMS")}
                      data={[
                        { value: "SMS", label: "SMS" },
                        { value: "VOICE", label: "VOICE" },
                      ]}
                      required
                    />
                    <TextInput
                      label="Language"
                      value={language}
                      onChange={(e) => setLanguage(e.currentTarget.value)}
                      placeholder="en_US"
                    />
                    <Button type="submit" loading={!!actionLoading.requestCode} disabled={!accountId}>
                      Request Code
                    </Button>
                  </Stack>
                </form>
              </Paper>

              <Paper withBorder p="sm">
                <form onSubmit={handleVerifyCode}>
                  <Stack>
                    <Text fw={600} size="sm">
                      Verify Code
                    </Text>
                    <Select
                      label="Phone Number ID"
                      data={phoneNumberOptions}
                      value={phoneNumberIdForVerify}
                      onChange={(value) => setPhoneNumberIdForVerify(value || "")}
                      searchable
                      clearable
                    />
                    <TextInput
                      label="Or enter ID manually"
                      value={phoneNumberIdForVerify}
                      onChange={(e) => setPhoneNumberIdForVerify(e.currentTarget.value)}
                      required
                    />
                    <TextInput
                      label="Verification Code"
                      value={verificationCode}
                      onChange={(e) => setVerificationCode(e.currentTarget.value)}
                      required
                    />
                    <Button type="submit" loading={!!actionLoading.verifyCode} disabled={!accountId}>
                      Verify Code
                    </Button>
                  </Stack>
                </form>
              </Paper>

              <Paper withBorder p="sm">
                <form onSubmit={handleRegisterPhoneNumber}>
                  <Stack>
                    <Text fw={600} size="sm">
                      Register Phone Number
                    </Text>
                    <Select
                      label="Phone Number ID"
                      data={phoneNumberOptions}
                      value={phoneNumberIdForRegister}
                      onChange={(value) => setPhoneNumberIdForRegister(value || "")}
                      searchable
                      clearable
                    />
                    <TextInput
                      label="Or enter ID manually"
                      value={phoneNumberIdForRegister}
                      onChange={(e) => setPhoneNumberIdForRegister(e.currentTarget.value)}
                      required
                    />
                    <TextInput
                      label="PIN (4-8 digits)"
                      value={pin}
                      onChange={(e) => setPin(e.currentTarget.value)}
                      required
                    />
                    <Button type="submit" loading={!!actionLoading.registerPhoneNumber} disabled={!accountId}>
                      Register Number
                    </Button>
                  </Stack>
                </form>
              </Paper>
            </SimpleGrid>
          </Stack>
        </Paper>

        <Paper withBorder p="md">
          <Stack gap="md">
            <Group>
              <IconBuildingStore size={20} />
              <Text fw={600}>Business Profile</Text>
            </Group>

            <Group>
              <Button
                variant="light"
                onClick={handleGetBusinessProfile}
                loading={!!actionLoading.getBusinessProfile}
                disabled={!accountId}
              >
                Get Business Profile
              </Button>
            </Group>

            {businessProfile?.profile_picture_url && (
              <Alert color="blue" title="Profile Picture URL">
                {businessProfile.profile_picture_url}
              </Alert>
            )}

            <form onSubmit={handleUpdateBusinessProfile}>
              <Stack>
                <TextInput label="About" value={about} onChange={(e) => setAbout(e.currentTarget.value)} />
                <TextInput label="Address" value={address} onChange={(e) => setAddress(e.currentTarget.value)} />
                <Textarea
                  label="Description"
                  value={description}
                  onChange={(e) => setDescription(e.currentTarget.value)}
                  minRows={3}
                />
                <TextInput label="Email" value={email} onChange={(e) => setEmail(e.currentTarget.value)} />
                <Textarea
                  label="Websites"
                  description="One URL per line or comma-separated"
                  value={websites}
                  onChange={(e) => setWebsites(e.currentTarget.value)}
                  minRows={2}
                />
                <TextInput label="Vertical" value={vertical} onChange={(e) => setVertical(e.currentTarget.value)} />
                <Button type="submit" loading={!!actionLoading.updateBusinessProfile} disabled={!accountId}>
                  Update Business Profile
                </Button>
              </Stack>
            </form>
          </Stack>
        </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) => (
              <ResultPanel
                key={entry.id}
                title={`${entry.title} - ${entry.status.toUpperCase()} - ${new Date(entry.createdAt).toLocaleString()}`}
                payload={entry.payload}
              />
            ))}
          </Stack>
        )}
      </Stack>
    </Container>
  );
}
