import { GET_JOB_NOTES } from "@/graphql/jobs.queries";
import { useQuery } from "@apollo/client";
import { AntDesign } from "@expo/vector-icons";
import { useGlobalSearchParams } from "expo-router";
import { DateTime } from "luxon";
import React, { memo, useCallback, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { FlatList, RefreshControl, View } from "react-native";
import {
  ActivityIndicator,
  Button,
  Card,
  Divider,
  Text,
} from "react-native-paper";
import ErrorDisplay from "../error/error-display";
import NewNoteModal from "./new-note-modal";

export default function JobNotes() {
  const { jobId } = useGlobalSearchParams();
  const [noteModalVisible, setNoteModalVisible] = useState(false);
  const showNoteModal = () => setNoteModalVisible(true);
  const hideNoteModal = () => setNoteModalVisible(false);

  const { loading, error, data, refetch } = useQuery(GET_JOB_NOTES, {
    variables: {
      id: jobId,
    },
    skip: !jobId,
  });

  const handleNoteCreated = useCallback(() => {
    hideNoteModal();
    refetch();
  }, [refetch]);

  const { t } = useTranslation();
  const onRefresh = async () => {
    return refetch();
  };

  const job = data?.jobs_by_pk;

  // Memoized list data (only when job & notes exist)
  const listData = useMemo(() => {
    if (!job?.notes) return [];
    const notes = job.notes;
    const pinnedNotes = [];
    const otherNotes = [];
    for (const n of notes) {
      (n.pinned ? pinnedNotes : otherNotes).push(n);
    }
    pinnedNotes.sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
    otherNotes.sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
    const DIVIDER_ID = "__divider__";
    return pinnedNotes.length > 0 && otherNotes.length > 0
      ? [...pinnedNotes, { id: DIVIDER_ID, type: "divider" }, ...otherNotes]
      : [...pinnedNotes, ...otherNotes];
  }, [job?.notes]);

  const keyExtractor = useCallback((item) => item.id, []);
  const renderItem = useCallback(
    ({ item }) =>
      item.type === "divider" ? <DividerItem /> : <NoteListItem item={item} />,
    []
  );

  if (loading) {
    return <ActivityIndicator size="large" style={{ flex: 1 }} />;
  }
  if (error) {
    return <ErrorDisplay message={JSON.stringify(error?.message)} />;
  }
  if (!job) {
    return <ErrorDisplay errorMessage={"Job is not defined."} />;
  }

  return (
    <View style={{ flex: 1, display: "flex" }}>
      <Button
        icon="plus"
        mode="outlined"
        onPress={showNoteModal}
        style={{ margin: 8 }}
      >
        {t("jobdetail.actions.addnote")}
      </Button>
      {listData.length === 0 ? (
        <Card>
          <Card.Content>
            <Text>{t("jobdetail.labels.nojobnotes")}</Text>
          </Card.Content>
        </Card>
      ) : (
        <FlatList
          refreshControl={
            <RefreshControl refreshing={loading} onRefresh={onRefresh} />
          }
          style={{ flex: 1 }}
          data={listData}
          keyExtractor={keyExtractor}
          renderItem={renderItem}
          removeClippedSubviews
          initialNumToRender={12}
          maxToRenderPerBatch={8}
          windowSize={7}
        />
      )}
      <NewNoteModal
        jobId={jobId}
        visible={noteModalVisible}
        onDismiss={hideNoteModal}
        onCreated={handleNoteCreated}
        relatedRos={[]} // TODO: supply relatedRos list
      />
    </View>
  );
}

const NoteListItem = memo(function NoteListItem({ item }) {
  const { t } = useTranslation();
  return (
    <Card mode="outlined" style={{ margin: 8 }}>
      <Card.Content>
        <View style={{ display: "flex", flex: 1 }}>
          <Text>{item.text}</Text>
          <View
            style={{
              flexDirection: "row",
              alignSelf: "flex-end",
              alignItems: "center",
              gap: 8,
            }}
          >
            {item.pinned && (
              <AntDesign name="pushpin" size={24} color="dodgerblue" />
            )}
            {item.private && (
              <AntDesign name="eye-invisible" size={24} color="black" />
            )}
            {item.critical && (
              <AntDesign name="warning" size={24} color="tomato" />
            )}
            <Text style={{ fontSize: 12 }}>
              {t(`notes.labels.type.${item.type}`)}
            </Text>
            <Text style={{ fontSize: 12 }}>{item.created_by}</Text>
            <Text style={{ fontSize: 12 }}>
              {DateTime.fromISO(item.created_at).toLocaleString(
                DateTime.DATETIME_SHORT
              )}
            </Text>
          </View>
        </View>
      </Card.Content>
    </Card>
  );
});

const DividerItem = memo(function DividerItem() {
  return <Divider bold style={{ margin: 12 }} />;
});
