/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import {
  HStack,
  Input,
  Table,
  Thead,
  Tbody,
  Tr,
  Th,
  Td,
  TableContainer,
  useToast,
  Box,
  Button,
  Modal,
  ModalBody,
  ModalCloseButton,
  ModalContent,
  ModalFooter,
  ModalHeader,
  ModalOverlay,
  useDisclosure,
  Select,
  VStack,
  Textarea,
} from '@chakra-ui/react';
import axios from 'axios';
import { useContext, useEffect, useState } from 'react';
import { CloudEvent } from 'cloudevents';
import { AppContext } from '../../context/context';

interface Topic {
  name: string,
  messageCount: number,
}

interface EventProps {
  event: CloudEvent<string>,
}

interface CreateEventRequest {
  event: CloudEvent<string>,
}

const CreateEventModal = () => {
  const { state } = useContext(AppContext);

  const { isOpen, onOpen, onClose } = useDisclosure();

  const [id, setId] = useState('');
  const handleIdChange = (event: React.FormEvent<HTMLInputElement>) => {
    setId(event.currentTarget.value);
  };

  const [source, setSource] = useState('');
  const handleSourceChange = (event: React.FormEvent<HTMLInputElement>) => {
    setSource(event.currentTarget.value);
  };

  const [subject, setSubject] = useState('');
  const handleSubjectChange = (event: React.FormEvent<HTMLInputElement>) => {
    setSubject(event.currentTarget.value);
  };

  const [type, setType] = useState('');
  const handleTypeChange = (event: React.FormEvent<HTMLInputElement>) => {
    setType(event.currentTarget.value);
  };

  const [data, setData] = useState('');
  const handleDataChange = (event: React.FormEvent<HTMLInputElement>) => {
    setData(event.currentTarget.value);
  };

  const toast = useToast();
  const [loading, setLoading] = useState(false);
  const onCreateClick = async () => {
    try {
      setLoading(true);
      await axios.post<CreateEventRequest>(`${state.endpoint}/event`, new CloudEvent({
        source,
        subject,
        type,
        data,
        specversion: '1.0',
      }));
      onClose();
    } catch (error) {
      if (axios.isAxiosError(error)) {
        toast({
          title: 'Failed to publish the event',
          description: error.message,
          status: 'error',
          duration: 3000,
          isClosable: true,
        });
      }
    } finally {
      setLoading(false);
    }
  };

  return (
    <>
      <Button
        w="25%"
        colorScheme="blue"
        onClick={onOpen}
      >
        Create Event
      </Button>
      <Modal isOpen={isOpen} onClose={onClose}>
        <ModalOverlay />
        <ModalContent>
          <ModalHeader>Create Event</ModalHeader>
          <ModalCloseButton />
          <ModalBody>
            <VStack>
              <Input
                placeholder="Event ID"
                value={id}
                onChange={handleIdChange}
              />
              <Input
                placeholder="Event Source"
                value={source}
                onChange={handleSourceChange}
              />
              <Input
                placeholder="Event Subject"
                value={subject}
                onChange={handleSubjectChange}
              />
              <Input
                placeholder="Event Type"
                value={type}
                onChange={handleTypeChange}
              />
              <Input
                placeholder="Event Data"
                value={data}
                onChange={handleDataChange}
              />
            </VStack>
          </ModalBody>

          <ModalFooter>
            <Button
              mr={2}
              onClick={onClose}
            >
              Close
            </Button>
            <Button
              colorScheme="blue"
              onClick={onCreateClick}
              isLoading={loading}
              isDisabled={
                id.length === 0 || subject.length === 0 || source.length === 0 || type.length === 0
              }
            >
              Create
            </Button>
          </ModalFooter>
        </ModalContent>
      </Modal>
    </>
  );
};

const EventRow = ({
  event,
}: EventProps) => {
  const { isOpen, onOpen, onClose } = useDisclosure();
  const eventDataBase64 = event.data_base64 || '';
  const eventData = Buffer.from(eventDataBase64, 'base64').toString('utf-8');

  return (
    <>
      <Modal isOpen={isOpen} onClose={onClose}>
        <ModalOverlay />
        <ModalContent>
          <ModalHeader>Event Data</ModalHeader>
          <ModalCloseButton />
          <ModalBody>
            <Box>
              <Textarea isDisabled value={eventData} />
            </Box>
          </ModalBody>

          <ModalFooter>
            <Button
              mr={2}
              onClick={onClose}
            >
              Close
            </Button>
          </ModalFooter>
        </ModalContent>
      </Modal>

      <Tr>
        <Td>{event.id}</Td>
        <Td>{event.subject}</Td>
        <Td>{new Date(Number(event.reqc2eventmeshtimestamp)).toLocaleString()}</Td>
        <Td>
          <HStack>
            <Button
              colorScheme="blue"
              onClick={onOpen}
            >
              View Data
            </Button>
          </HStack>

        </Td>
      </Tr>
    </>
  );
};

const EventTable = () => {
  const { state } = useContext(AppContext);

  const [searchInput, setSearchInput] = useState<string>('');
  const handleSearchInputChange = (event: React.FormEvent<HTMLInputElement>) => {
    setSearchInput(event.currentTarget.value);
  };

  const [eventList, setEventList] = useState<CloudEvent<string>[]>([]);
  const [topicList, setTopicList] = useState<Topic[]>([]);
  const [topic, setTopic] = useState<Topic>({
    name: '',
    messageCount: 0,
  });
  const handleTopicChange = (event: React.FormEvent<HTMLSelectElement>) => {
    setTopic({
      name: event.currentTarget.value,
      messageCount: 0,
    });
  };

  const toast = useToast();

  useEffect(() => {
    const fetch = async () => {
      try {
        const { data } = await axios.get<Topic[]>(`${state.endpoint}/topic`);
        setTopicList(data);
        if (data.length !== 0) {
          setTopic(data[0]);
        }
      } catch (error) {
        if (axios.isAxiosError(error)) {
          toast({
            title: 'Failed to fetch the list of events',
            description: 'unable to connect to the EventMesh daemon',
            status: 'error',
            duration: 3000,
            isClosable: true,
          });
          setEventList([]);
        }
      }
    };

    fetch();
  }, []);

  useEffect(() => {
    const fetch = async () => {
      try {
        if (topic.name !== '') {
          const eventResponse = await axios.get<string[]>(`${state.endpoint}/event`, {
            params: {
              topicName: topic.name,
              offset: 0,
              length: 15,
            },
          });
          setEventList(eventResponse.data.map((rawEvent) => JSON.parse(rawEvent)));
        }
      } catch (error) {
        if (axios.isAxiosError(error)) {
          toast({
            title: 'Failed to fetch the list of events',
            description: 'Unable to connect to the EventMesh daemon',
            status: 'error',
            duration: 3000,
            isClosable: true,
          });
          setEventList([]);
        }
      }
    };

    fetch();
  }, [topic]);

  return (
    <Box
      maxW="full"
      bg="white"
      borderWidth="1px"
      borderRadius="md"
      overflow="hidden"
      p="4"
    >
      <HStack
        spacing="2"
      >
        <Input
          w="100%"
          placeholder="Search"
          value={searchInput}
          onChange={handleSearchInputChange}
        />
        <Select
          w="100%"
          onChange={handleTopicChange}
        >
          {topicList.map(({ name }) => (
            <option value={name} key={name} selected={topic.name === name}>{name}</option>
          ))}
        </Select>
        <CreateEventModal />
      </HStack>

      <TableContainer>
        <Table variant="simple">
          <Thead>
            <Tr>
              <Th>Event Id</Th>
              <Th>Event Subject</Th>
              <Th>Event Time</Th>
              <Th>Action</Th>
            </Tr>
          </Thead>
          <Tbody>
            {eventList.filter(() => true).map((event) => (
              <EventRow
                key={event.id}
                event={event}
              />
            ))}
          </Tbody>
        </Table>
      </TableContainer>
    </Box>
  );
};

export default EventTable;
