import { useEffect, useMemo, useState } from "react";
import {
  AppShell,
  Badge,
  Box,
  Burger,
  Button,
  Center,
  Code,
  Group,
  Loader,
  Modal,
  ScrollArea,
  Stack,
  Text,
  Title,
} from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import { notifications } from "@mantine/notifications";
import {
  IconBug,
  IconLock,
  IconLogout,
  IconStethoscope,
  IconUserCircle,
} from "@tabler/icons-react";
import {
  GetDiagnostics,
  GetLogPath,
  GetLogTail,
  Logout,
  SendMarkdown,
  SendText,
  Start,
  Stop,
} from "../wailsjs/go/main/MatrixService";
import { EventsOn } from "../wailsjs/runtime/runtime";
import RoomList from "./components/RoomList";
import Timeline from "./components/Timeline";
import Composer from "./components/Composer";
import { useMatrixRooms } from "./hooks/useMatrixRooms";
import { useMatrixTimeline } from "./hooks/useMatrixTimeline";

const NAVBAR_WIDTH = 300;

function HealthRow({ label, value, ok }: { label: string; value: string; ok: boolean }) {
  return (
    <Group gap="sm" justify="space-between">
      <Text size="sm" c="dimmed">{label}</Text>
      <Group gap="xs">
        <Box
          w={8}
          h={8}
          style={{
            borderRadius: "50%",
            background: ok ? "var(--mantine-color-green-6)" : "var(--mantine-color-red-6)",
          }}
        />
        <Code>{value}</Code>
      </Group>
    </Group>
  );
}

export default function HomeScreen({
  userID,
  onLogout,
}: {
  userID: string;
  onLogout: () => void;
}) {
  const [navOpen, navHandlers] = useDisclosure(true);
  const [activeRoomID, setActiveRoomID] = useState<string | null>(null);
  const [started, setStarted] = useState(false);
  const [startError, setStartError] = useState<string | null>(null);
  const [diagOpen, { open: openDiagnostics, close: closeDiagnostics }] = useDisclosure(false);
  const [healthOpen, { open: openHealth, close: closeHealth }] = useDisclosure(false);
  const [logLines, setLogLines] = useState<string[]>([]);
  const [logPath, setLogPath] = useState<string>("");
  const [health, setHealth] = useState<any | null>(null);
  const [healthLoading, setHealthLoading] = useState(false);

  useEffect(() => {
    if (!diagOpen) return;
    GetLogTail(200).then(setLogLines).catch(() => {});
    GetLogPath().then(setLogPath).catch(() => {});
  }, [diagOpen]);

  async function refreshHealth() {
    setHealthLoading(true);
    try {
      const h = await GetDiagnostics();
      setHealth(h);
    } catch (e) {
      setHealth({ error: String(e) });
    } finally {
      setHealthLoading(false);
    }
  }

  useEffect(() => {
    if (!healthOpen) return;
    refreshHealth();
  }, [healthOpen]);

  const { rooms } = useMatrixRooms(started);
  const { events, loading: timelineLoading, error: timelineError } = useMatrixTimeline(
    activeRoomID,
    50,
  );

  // Boot sync on mount; tear down on unmount.
  useEffect(() => {
    let cancelled = false;
    (async () => {
      try {
        await Start(userID);
        if (!cancelled) setStarted(true);
      } catch (e: any) {
        if (!cancelled) {
          const msg = String(e?.message ?? e);
          setStartError(msg);
          const stale = msg.includes("token rejected") || msg.includes("M_UNKNOWN_TOKEN");
          notifications.show({
            title: stale ? "Token expired — re-login required" : "Sync error",
            message: msg,
            color: "red",
            autoClose: false,
          });
          // Auto-logout on stale token so user lands back on LoginScreen.
          if (stale) {
            try { await Logout(userID); } catch {}
            onLogout();
          }
        }
      }
    })();
    return () => {
      cancelled = true;
      Stop().catch(() => {});
    };
  }, [userID]);

  // Show transient Matrix errors as toast notifications.
  useEffect(() => {
    const off = EventsOn("matrix:error", (msg: string) => {
      notifications.show({
        title: "Matrix",
        message: String(msg),
        color: "orange",
        autoClose: 6000,
      });
    });
    return () => {
      if (typeof off === "function") off();
    };
  }, []);

  const activeRoom = useMemo(
    () => rooms.find((r) => r.room_id === activeRoomID) || null,
    [rooms, activeRoomID],
  );

  async function handleLogout() {
    try {
      await Logout(userID);
    } finally {
      onLogout();
    }
  }

  async function handleSendText(body: string) {
    if (!activeRoomID) return;
    await SendText(activeRoomID, body);
  }

  async function handleSendMarkdown(md: string) {
    if (!activeRoomID) return;
    await SendMarkdown(activeRoomID, md);
  }

  return (
    <AppShell
      header={{ height: 56 }}
      navbar={{
        width: NAVBAR_WIDTH,
        breakpoint: 0,
        collapsed: { mobile: !navOpen, desktop: !navOpen },
      }}
      padding={0}
    >
      <AppShell.Header>
        <Group h="100%" px="md" justify="space-between" wrap="nowrap">
          <Group gap="xs" wrap="nowrap">
            <Burger
              opened={navOpen}
              onClick={navHandlers.toggle}
              size="sm"
              aria-label="Toggle rooms"
            />
            <IconUserCircle size={22} />
            <Text fw={600}>matrix_client_pc</Text>
            <Badge size="sm" variant="light" color="violet">
              v0.2.0
            </Badge>
            <Text size="xs" c="dimmed" visibleFrom="sm">
              {userID}
            </Text>
          </Group>
          <Group gap="xs">
            <Button
              variant="subtle"
              color="green"
              size="xs"
              leftSection={<IconStethoscope size={14} />}
              onClick={openHealth}
            >
              Health
            </Button>
            <Button
              variant="subtle"
              color="gray"
              size="xs"
              leftSection={<IconBug size={14} />}
              onClick={openDiagnostics}
            >
              Logs
            </Button>
            <Button
              variant="subtle"
              color="gray"
              leftSection={<IconLogout size={16} />}
              onClick={handleLogout}
            >
              Logout
            </Button>
          </Group>
        </Group>
      </AppShell.Header>

      <AppShell.Navbar>
        <RoomList
          rooms={rooms}
          activeRoomID={activeRoomID}
          onSelect={setActiveRoomID}
        />
      </AppShell.Navbar>

      <AppShell.Main
        style={{
          display: "flex",
          flexDirection: "column",
          height: "calc(100vh - 56px)",
        }}
      >
        {!started && !startError && (
          <Center style={{ flex: 1 }}>
            <Stack align="center" gap="xs">
              <Loader />
              <Text size="sm" c="dimmed">
                Starting sync and crypto (up to 60s on first run)...
              </Text>
            </Stack>
          </Center>
        )}

        {startError && (
          <Center style={{ flex: 1 }}>
            <Stack align="center" gap="xs" maw={520} ta="center">
              <Title order={4} c="red">
                Could not start sync
              </Title>
              <Text size="sm" c="dimmed">
                {startError}
              </Text>
            </Stack>
          </Center>
        )}

        {started && !activeRoom && (
          <Center style={{ flex: 1 }}>
            <Text size="sm" c="dimmed">
              Pick a room from the sidebar to view messages
            </Text>
          </Center>
        )}

        {started && activeRoom && (
          <>
            <Box p="md" bg="dark.7" style={{ borderBottom: "1px solid var(--mantine-color-dark-5)" }}>
              <Group gap="xs">
                <Title order={5}>{activeRoom.name || activeRoom.room_id}</Title>
                {activeRoom.is_encrypted && (
                  <Badge size="xs" color="green" variant="light" leftSection={<IconLock size={10} />}>
                    E2EE
                  </Badge>
                )}
                <Text size="xs" c="dimmed">
                  {activeRoom.member_count} member{activeRoom.member_count === 1 ? "" : "s"}
                </Text>
              </Group>
              {activeRoom.topic && (
                <Text size="xs" c="dimmed" mt={4} lineClamp={1}>
                  {activeRoom.topic}
                </Text>
              )}
            </Box>

            <Box style={{ flex: 1, minHeight: 0 }}>
              <Timeline
                events={events}
                loading={timelineLoading}
                error={timelineError}
                selfUserID={userID}
              />
            </Box>

            <Composer
              disabled={!activeRoomID}
              onSendText={handleSendText}
              onSendMarkdown={handleSendMarkdown}
            />
          </>
        )}
      </AppShell.Main>

      <Modal
        opened={healthOpen}
        onClose={closeHealth}
        title="Health — comprobar chats"
        size="lg"
      >
        <Stack gap="md">
          <Group justify="space-between">
            <Text size="xs" c="dimmed">
              Snapshot del estado del MatrixService backend.
            </Text>
            <Button size="xs" variant="light" onClick={refreshHealth} loading={healthLoading}>
              Refresh
            </Button>
          </Group>
          {!health && <Text c="dimmed">No data yet.</Text>}
          {health?.error && (
            <Text c="red" size="sm">
              {health.error}
            </Text>
          )}
          {health && !health.error && (
            <Stack gap={4}>
              <HealthRow label="Started" value={String(health.started)} ok={health.started} />
              <HealthRow label="Client ready" value={String(health.client_ready)} ok={health.client_ready} />
              <HealthRow label="Crypto initialized" value={String(health.crypto_initialized)} ok={health.crypto_initialized} />
              <HealthRow label="Sync active" value={String(health.sync_active)} ok={health.sync_active} />
              <HealthRow label="User ID" value={health.user_id || "—"} ok={!!health.user_id} />
              <HealthRow label="Homeserver" value={health.homeserver_url || "—"} ok />
              <HealthRow label="Rooms total" value={String(health.rooms_count)} ok={health.rooms_count > 0} />
              <HealthRow label="Encrypted rooms" value={String(health.encrypted_rooms)} ok />
              <HealthRow label="Direct messages" value={String(health.dms_count)} ok />
              {health.last_error && (
                <Text c="red" size="xs" mt="sm">
                  Last error: {health.last_error}
                </Text>
              )}
            </Stack>
          )}
        </Stack>
      </Modal>

      <Modal
        opened={diagOpen}
        onClose={closeDiagnostics}
        title="Diagnostics — last 200 log lines"
        size="xl"
      >
        <Stack gap="xs">
          <Text size="xs" c="dimmed">
            Log file: <Code>{logPath || "(unknown)"}</Code>
          </Text>
          <ScrollArea h={500} type="auto">
            <pre style={{ fontSize: 11, lineHeight: 1.4, margin: 0, whiteSpace: "pre-wrap", wordBreak: "break-all" }}>
              {logLines.length === 0 ? "(empty)" : logLines.join("\n")}
            </pre>
          </ScrollArea>
        </Stack>
      </Modal>
    </AppShell>
  );
}
