import { BuildTable } from "@/components/blocks/Table/table";
import type { AdminActivityLog } from "@/lib/features/activity-logs/query";
import { Badge, Flex, Stack, Title, Text, Tooltip, Select, Code, Group, Paper, ScrollArea, Button, Tabs, Box, TextInput } from "@mantine/core";
import { notifications } from "@mantine/notifications";
import { modals } from "@mantine/modals";
import { IconHistory, IconLink, IconX, IconTag, IconUser, IconCalendar, IconFilter, IconSearch, IconTrash } from "@tabler/icons-react";
import { DatePickerInput } from "@mantine/dates";
import type { MRT_ColumnDef, MRT_RowData } from "mantine-react-table";
import moment from "moment";
import React from "react";
import { useSearchParams, useNavigate } from "react-router";
import LogFilters, { type LogFilterState } from "./LogFilters";
import { useUser } from "@/providers/UserProvider";
import { deleteAllAdminLogs } from "@/lib/features/activity-logs/query";

const getStatusColor = (status: number) => {
  if (status >= 200 && status < 300) return "green";
  if (status >= 400 && status < 500) return "orange";
  if (status >= 500) return "red";
  return "gray";
};

const columns: MRT_ColumnDef<AdminActivityLog>[] = [
  {
    accessorKey: "admin_email",
    header: "Admin",
    size: 240,
    Cell: ({ cell }) => {
      const email = cell.getValue<string>();
      if (email === "anonymous") {
        return <Text size="sm" c="dimmed" fs="italic">anonymous</Text>;
      }
      return <Text size="sm" fw={500}>{email}</Text>;
    }
  },
  {
    accessorKey: "log_category",
    header: "Category",
    size: 100,
    Cell: ({ cell }) => (
      <Badge size="sm" variant="light" color={cell.getValue<string>() === "API" ? "blue" : cell.getValue<string>() === "UI" ? "grape" : "orange"}>
        {cell.getValue<string>()}
      </Badge>
    ),
  },
  {
    accessorKey: "method",
    header: "Method",
    size: 100,
    Cell: ({ cell }) => (
      <Badge size="sm" variant="light">
        {cell.getValue<string>()}
      </Badge>
    ),
  },
  {
    accessorKey: "action",
    header: "Action",
    size: 300,
    Cell: ({ row }) => (
      <Tooltip label={row.original.url}>
        <Text size="sm" truncate="end">
          {row.original.action}
        </Text>
      </Tooltip>
    ),
  },
  {
    accessorKey: "status_code",
    header: "Status",
    size: 100,
    Cell: ({ cell }) => (
      <Badge color={getStatusColor(cell.getValue<number>())} variant="dot">
        {cell.getValue<number>()}
      </Badge>
    ),
  },
  {
    accessorKey: "ip_address",
    header: "IP Address",
    size: 150,
    Cell: ({ cell }) => (
      <Text size="sm">{cell.getValue<string>()}</Text>
    ),
  },
  {
    accessorFn: (row) => moment(row.performed_at).format("LLL"),
    id: "performed_at",
    header: "Time",
    size: 200,
    Cell: ({ cell }) => (
      <Text size="sm">{cell.getValue<string>()}</Text>
    ),
  },
];

const LogsClientPage: React.FC<{
  data: AdminActivityLog[];
  totalCount: number;
}> = ({ data, totalCount }) => {
  const [searchParams, setSearchParams] = useSearchParams();
  const { user } = useUser();
  const navigate = useNavigate();
  const [rowSelection, setRowSelection] = React.useState<Record<string, boolean>>({});
  const selectedIds = Object.keys(rowSelection).filter((id) => rowSelection[id]);

  const handleClearAll = () => {
    modals.openConfirmModal({
      title: 'Clear All Activity Logs',
      centered: true,
      children: (
        <Text size="sm">
          Are you sure you want to delete all activity logs from the database? This action is permanent and cannot be undone.
        </Text>
      ),
      labels: { confirm: 'Delete Everything', cancel: 'Cancel' },
      confirmProps: { color: 'red' },
      onConfirm: async () => {
        try {
          const res = await deleteAllAdminLogs();
          if (res && res.success) {
            notifications.show({
              title: 'Logs Cleared',
              message: 'Database activity logs have been successfully wiped.',
              color: 'green'
            });
            setRowSelection({});
            const newParams = new URLSearchParams();
            newParams.set("page", "1");
            setSearchParams(newParams);
          }
        } catch (e) {
          notifications.show({
            title: 'System Error',
            message: 'An unexpected error occurred while clearing logs.',
            color: 'red'
          });
        }
      },
    });
  };

  const handleDeleteSelected = () => {
    modals.openConfirmModal({
      title: `Delete ${selectedIds.length} Selected Logs`,
      centered: true,
      children: (
        <Text size="sm">
          Are you sure you want to delete the {selectedIds.length} selected activity logs? This action cannot be undone.
        </Text>
      ),
      labels: { confirm: 'Delete Selected', cancel: 'Cancel' },
      confirmProps: { color: 'red' },
      onConfirm: async () => {
        try {
          const res = await deleteAllAdminLogs(selectedIds);
          if (res && res.success) {
            notifications.show({
              title: 'Batch Deleted',
              message: `${selectedIds.length} logs have been removed.`,
              color: 'green'
            });
            setRowSelection({});
            const newParams = new URLSearchParams(searchParams);
            newParams.set("page", "1");
            setSearchParams(newParams);
          }
        } catch (e) {
          notifications.show({ title: 'Error', message: 'Failed to delete selected logs', color: 'red' });
        }
      },
    });
  };

  const handleApplyFilters = (filters: LogFilterState) => {
    const newParams = new URLSearchParams(searchParams);

    // Clear existing array params
    newParams.delete("admin_email");
    newParams.delete("log_category");
    newParams.delete("method");
    newParams.delete("status_group");

    // Add new ones
    Object.entries(filters).forEach(([key, values]) => {
      values.forEach((val: string) => newParams.append(key, val));
    });

    newParams.set("page", "1"); // Reset to page 1
    setSearchParams(newParams);
  };

  const handleFilterChange = (key: string, value: string | null) => {
    const newParams = new URLSearchParams(searchParams);
    if (value) {
      newParams.set(key, value);
    } else {
      newParams.delete(key);
    }
    newParams.set("page", "1");
    setSearchParams(newParams);
  };

  const handleRowClick = (rowData: MRT_RowData) => {
    const log = rowData as AdminActivityLog;

    const parseJSON = (val: any) => {
      if (!val) return null;
      try {
        if (typeof val === "string") return JSON.parse(val);
        return val;
      } catch (e) {
        return val;
      }
    };

    const displayPayload = parseJSON(log.payload);
    const displayResponse = parseJSON(log.response_payload);
    const displayQueryParams = parseJSON(log.query_params);

    modals.open({
      title: (
        <Group>
          <IconHistory size={20} />
          <Text fw={600}>Activity Details</Text>
        </Group>
      ),
      size: "xxl",
      centered: true,
      children: (
        <Stack gap="md">
          <Paper p="md" withBorder bg="gray.0">
            <Stack gap="xs">
              <Group justify="space-between" align="flex-start">
                <Stack gap={4}>
                  <Group>
                    <Badge color={getStatusColor(log.status_code)} variant="filled">
                      {log.method}
                    </Badge>
                    <Text size="sm" fw={700} style={{ wordBreak: 'break-all' }}>
                      {log.url}
                    </Text>
                  </Group>
                  <Text size="sm" c="dimmed">
                    Performed by: <strong>{log.admin_email}</strong> • {moment(log.performed_at).format("LLL")}
                  </Text>
                </Stack>
                {log.origin_page && (
                  <Button
                    variant="subtle"
                    size="compact-xs"
                    component="a"
                    href={log.origin_page}
                    target="_blank"
                    leftSection={<IconLink size={14} />}
                  >
                    Origin Page
                  </Button>
                )}
              </Group>
            </Stack>
          </Paper>

          <Tabs defaultValue="payload">
            <Tabs.List>
              <Tabs.Tab value="payload" size="md" disabled={!displayPayload}>Request Payload</Tabs.Tab>
              <Tabs.Tab value="params" size="md" disabled={!displayQueryParams || Object.keys(displayQueryParams).length === 0}>Query Params</Tabs.Tab>
              <Tabs.Tab value="response" size="md" disabled={!displayResponse}>Response</Tabs.Tab>
            </Tabs.List>

            <Tabs.Panel value="payload" pt="sm">
              {displayPayload ? (
                <Stack gap="xs">
                  <ScrollArea h={300} offsetScrollbars>
                    <Code
                      block
                      color="blue.0"
                      c="blue.9"
                      fz="sm"
                      style={{ padding: '16px', borderRadius: '8px' }}
                    >
                      {JSON.stringify(displayPayload, null, 2)}
                    </Code>
                  </ScrollArea>
                  <Button
                    variant="light"
                    size="sm"
                    onClick={() => {
                      navigator.clipboard.writeText(JSON.stringify(displayPayload, null, 2));
                      notifications.show({ title: 'Copied', message: 'Payload copied to clipboard', color: 'blue' });
                    }}
                  >
                    Copy Request Payload
                  </Button>
                </Stack>
              ) : (
                <Text size="sm" c="dimmed" py="xl" ta="center">No request payload for this action</Text>
              )}
            </Tabs.Panel>

            <Tabs.Panel value="params" pt="sm">
              <ScrollArea h={300} offsetScrollbars>
                <Code
                  block
                  color="orange.0"
                  c="orange.9"
                  fz="sm"
                  style={{ padding: '16px', borderRadius: '8px' }}
                >
                  {JSON.stringify(displayQueryParams, null, 2)}
                </Code>
              </ScrollArea>
            </Tabs.Panel>

            <Tabs.Panel value="response" pt="sm">
              <Stack gap="xs">
                <ScrollArea h={300} offsetScrollbars>
                  <Code
                    block
                    color="green.0"
                    c="green.9"
                    fz="sm"
                    style={{ padding: '16px', borderRadius: '8px' }}
                  >
                    {JSON.stringify(displayResponse, null, 2)}
                  </Code>
                </ScrollArea>
                <Button
                  variant="light"
                  size="sm"
                  color="green"
                  onClick={() => {
                    navigator.clipboard.writeText(JSON.stringify(displayResponse, null, 2));
                    notifications.show({ title: 'Copied', message: 'Response copied to clipboard', color: 'green' });
                  }}
                >
                  Copy Response
                </Button>
              </Stack>
            </Tabs.Panel>
          </Tabs>
        </Stack>
      ),
    });
  };

  const handleDateChange = (dates: any) => {
    const [start, end] = dates;
    const newParams = new URLSearchParams(searchParams);

    if (start) {
      newParams.set("from_date", new Date(start).toISOString());
    } else {
      newParams.delete("from_date");
    }

    if (end) {
      newParams.set("to_date", new Date(end).toISOString());
    } else {
      newParams.delete("to_date");
    }

    newParams.set("page", "1");
    setSearchParams(newParams);
  };

  const clearFilters = () => {
    const newParams = new URLSearchParams();
    newParams.set("page", "1");
    newParams.set("pageSize", searchParams.get("pageSize") || "50");
    setSearchParams(newParams);
  };

  const activeFilters = Array.from(searchParams.entries()).filter(([k, v]) => !['page', 'pageSize', 'search'].includes(k) && !!v);
  const activeFiltersCount = activeFilters.length;

  const currentFilters: LogFilterState = {
    admin_email: searchParams.getAll("admin_email"),
    log_category: searchParams.getAll("log_category"),
    method: searchParams.getAll("method"),
    status_group: searchParams.getAll("status_group"),
  };

  return (
    <Stack gap="lg" p="lg">
      <Paper p="md" withBorder shadow="sm" radius="md" bg="var(--mantine-color-gray-0)">
        <Stack gap="md">
          <Flex justify="space-between" align="center">
            <Group gap="xs">
              <IconFilter size={20} color="var(--mantine-color-blue-6)" />
              <Text fw={700} size="sm">Filters & Search</Text>
              {activeFiltersCount > 0 && (
              <Badge variant="filled" color="blue" size="xs">
                  {activeFiltersCount} Active
                </Badge>
              )}
            </Group>

            <Group gap="xs">
              {user?.is_super_admin && (
                <>
                  {selectedIds.length > 0 && (
                    <Button
                      variant="filled"
                      color="red"
                      size="sm"
                      leftSection={<IconTrash size={14} />}
                      onClick={handleDeleteSelected}
                    >
                      Delete Selected ({selectedIds.length})
                    </Button>
                  )}
                  <Button
                    variant="light"
                    color="red"
                    size="sm"
                    leftSection={<IconTrash size={14} />}
                    onClick={handleClearAll}
                  >
                    Clear All Logs
                  </Button>
                </>
              )}

              {activeFiltersCount > 0 && (
                <Button
                  variant="subtle"
                  color="red"
                  size="sm"
                  onClick={clearFilters}
                  leftSection={<IconX size={14} />}
                  px={8}
                >
                  Reset All Filters
                </Button>
              )}
            </Group>
          </Flex>

          <Group align="flex-end" gap="md" justify="space-between">
            <Group align="flex-end" gap="md">

              <LogFilters
                onApply={handleApplyFilters}
                initialFilters={currentFilters}
                adminOptions={Array.from(new Set(data.map((log) => log.admin_email)))}
              />

              <DatePickerInput
                label="Date Range"
                type="range"
                placeholder="Pick date range"
                value={[
                  searchParams.get("from_date") ? new Date(searchParams.get("from_date")!) : null,
                  searchParams.get("to_date") ? new Date(searchParams.get("to_date")!) : null
                ]}
                onChange={handleDateChange}
                size="sm"
                w={240}
                clearable
                leftSection={<IconCalendar size={14} style={{ opacity: 0.7 }} />}
                valueFormat="DD MMM YY"
              />
            </Group>

            <Box style={{ flex: "0 0 25%", minWidth: "25%" }}>
              <Text size="sm" fw={500} mb={4}>Search Action</Text>
              <TextInput
                placeholder="Search action or URL..."
                size="sm"
                value={searchParams.get("search") || ""}
                onChange={(e: React.ChangeEvent<HTMLInputElement>) => handleFilterChange("search", e.currentTarget.value)}
                leftSection={<IconSearch size={14} style={{ opacity: 0.7 }} />}
                rightSection={searchParams.get("search") ? (
                  <IconX
                    size={14}
                    style={{ cursor: "pointer", opacity: 0.5 }}
                    onClick={() => handleFilterChange("search", null)}
                  />
                ) : null}
              />
            </Box>
          </Group>
        </Stack>
      </Paper>

      <BuildTable
        data={data}
        columns={columns}
        totalRows={totalCount}
        onRowClick={handleRowClick}
        enableSearch={false}
        rowSelection={rowSelection}
        onRowSelectionChange={setRowSelection}
      />
    </Stack>
  );
};

export default LogsClientPage;
