/* eslint-disable react/no-unstable-nested-components */
import PropTypes from 'prop-types';
import React, { useEffect, useState } from 'react';
import isEmpty from 'lodash/isEmpty';
import CodeBlock from '@arcblock/ux/lib/CodeBlock';
import PendingIcon from '@mui/icons-material/Pending';
import CheckCircleOutlined from '@mui/icons-material/CheckCircleOutlined';
import ErrorOutlined from '@mui/icons-material/ErrorOutlined';
import { Box, Button, CircularProgress, Grid, List, ListItem, ListItemIcon, ListItemText, ListSubheader, Stack, Typography, IconButton, styled, Tooltip, Divider } from '@mui/material';
import { Icon } from '@iconify/react';
import ShareIcon from '@iconify-icons/tabler/external-link';
import RefreshIcon from '@iconify-icons/tabler/refresh';
import { useInfiniteScroll } from 'ahooks';
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import { EVENTS } from '@abtnode/constant';
import UserCard from '@arcblock/ux/lib/UserCard';
import { CardType, InfoType } from '@arcblock/ux/lib/UserCard/types';
import { joinURL, withQuery } from 'ufo';
import { isSuccessAttempt, formatTime } from '../util';
import { useNodeContext } from '../../../contexts/node';
import { useTeamContext } from '../../../contexts/team';
import { useBlockletContext } from '../../../contexts/blocklet';
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
const groupAttemptsByDate = attempts => {
  const groupedAttempts = {};
  attempts.forEach(attempt => {
    const date = new Date(attempt.createdAt).toLocaleDateString();
    if (!groupedAttempts[date]) {
      groupedAttempts[date] = [];
    }
    groupedAttempts[date]?.push(attempt);
  });
  return groupedAttempts;
};
export default function WebhookAttempts({
  eventId = '',
  webhookEndpointId = '',
  event = null
}) {
  const {
    api,
    ws: {
      useSubscription
    }
  } = useNodeContext();
  const {
    t
  } = useLocaleContext();
  const {
    teamDid
  } = useTeamContext();
  const {
    blocklet
  } = useBlockletContext();
  const {
    data,
    loadMore,
    loadingMore,
    loading,
    mutate
  } = useInfiniteScroll(d => {
    const size = 15;
    const page = d ? Math.ceil(d.list.length / size) + 1 : 1;
    return api.getWebhookAttempts({
      input: {
        teamDid,
        input: {
          eventId,
          webhookId: webhookEndpointId
        },
        paging: {
          page,
          pageSize: size
        }
      }
    });
  }, {
    reloadDeps: [eventId, webhookEndpointId]
  });
  const attempts = data?.list || [];
  const [selected, setSelected] = useState(null);
  const [retryAttemptLoading, setRetryAttemptLoading] = useState(false);
  const groupedAttempts = groupAttemptsByDate(attempts);
  useEffect(() => {
    if (!selected && data?.list.length) {
      setSelected(data.list[0]);
    }
  }, [data?.list.length, selected]); // eslint-disable-line

  useSubscription(EVENTS.WEBHOOK_ATTEMPT, attempt => {
    mutate(d => {
      const found = d.list.find(item => item.id === attempt.id);
      if (found) {
        const list = d.list.map(item => {
          if (item.id === attempt.id) {
            return {
              ...item,
              ...attempt
            };
          }
          return item;
        });
        return {
          ...d,
          list
        };
      }
      attempt.endpoint = d.list[0]?.endpoint;
      attempt.event = d.list[0]?.event;
      return {
        ...d,
        list: [attempt, ...d.list]
      };
    });
  }, []);
  if (loading) {
    return /*#__PURE__*/_jsx(CircularProgress, {});
  }
  const hasMore = data && data.list.length < data.paging.total;
  const handleRetry = async () => {
    if (!selected) {
      return;
    }
    setRetryAttemptLoading(true);
    await api.retryWebhookAttempt({
      input: {
        teamDid,
        eventId: selected.event.id,
        webhookId: webhookEndpointId,
        attemptId: selected.id
      }
    }).finally(() => {
      setTimeout(() => {
        setRetryAttemptLoading(false);
      }, 1000);
    });
  };
  const renderLog = attempt => {
    if (attempt.responseBody && attempt.responseBody?.sessionId && attempt.responseBody?.projectId && attempt.responseBody?.agentId) {
      const site = blocklet?.site?.domainAliases[0]?.value;
      const mountPoint = (blocklet.children || []).find(item => item?.meta?.name === 'ai-studio');
      const logUrl = withQuery(joinURL(`https://${site}`, mountPoint?.mountPoint || '', 'projects', attempt.responseBody.projectId, 'logs/main'), {
        sessionId: attempt.responseBody.sessionId,
        agentId: attempt.responseBody.agentId
      });
      return /*#__PURE__*/_jsx(IconButton, {
        sx: {
          fontSize: 20
        },
        onClick: () => window.open(logUrl, '_blank'),
        children: /*#__PURE__*/_jsx(Box, {
          component: Icon,
          icon: ShareIcon
        })
      });
    }
    return null;
  };
  const renderIcon = attempt => {
    if (attempt.status === 'pending') {
      return /*#__PURE__*/_jsx(PendingIcon, {
        color: "warning"
      });
    }
    if (isSuccessAttempt(attempt.responseStatus)) {
      return /*#__PURE__*/_jsx(CheckCircleOutlined, {
        color: "success"
      });
    }
    return /*#__PURE__*/_jsx(ErrorOutlined, {
      color: "error"
    });
  };
  const foundTriggeredFrom = selected?.triggeredFrom && (data?.list || []).find(item => item.id === selected.triggeredFrom);
  return /*#__PURE__*/_jsxs(Container, {
    container: true,
    spacing: {
      xs: 0,
      md: 1
    },
    sx: {
      height: 1
    },
    children: [/*#__PURE__*/_jsx(Grid, {
      size: {
        xs: 12,
        md: 4
      },
      sx: {
        height: 1
      },
      children: isEmpty(Object.keys(groupedAttempts)) ? /*#__PURE__*/_jsx(Typography, {
        sx: {
          color: 'text.secondary'
        },
        children: t('webhookEndpoint.waitingForEvents')
      }) : /*#__PURE__*/_jsxs(_Fragment, {
        children: [/*#__PURE__*/_jsx(List, {
          sx: {
            maxHeight: 'calc(100% - 40px)',
            py: 0,
            overflowY: 'auto'
          },
          children: Object.entries(groupedAttempts).map(([date, items]) => /*#__PURE__*/_jsxs(React.Fragment, {
            children: [/*#__PURE__*/_jsx(ListSubheader, {
              sx: {
                p: 0
              },
              children: date
            }), items.map(attempt => /*#__PURE__*/_jsxs(ListItem, {
              sx: {
                cursor: 'pointer',
                px: 1
              },
              onClick: () => setSelected(attempt),
              selected: selected && selected?.id === attempt?.id,
              secondaryAction: /*#__PURE__*/_jsx(Typography, {
                sx: {
                  color: 'text.secondary'
                },
                children: formatTime(attempt.createdAt, 'HH:mm:ss')
              }),
              children: [/*#__PURE__*/_jsx(ListItemIcon, {
                sx: {
                  minWidth: 0,
                  mr: 1.5
                },
                children: renderIcon(attempt)
              }), /*#__PURE__*/_jsx(ListItemText, {
                primary: /*#__PURE__*/_jsx(Typography, {
                  sx: {
                    color: 'text.primary'
                  },
                  children: attempt.event.type
                })
              })]
            }, attempt.id))]
          }, date))
        }), hasMore && /*#__PURE__*/_jsx(Box, {
          sx: {
            display: 'flex',
            justifyContent: 'center',
            alignItems: 'center',
            width: 1
          },
          children: /*#__PURE__*/_jsx(Button, {
            variant: "text",
            type: "button",
            color: "inherit",
            onClick: loadMore,
            disabled: loadingMore,
            sx: {
              color: theme => theme.palette.text.disabled
            },
            children: loadingMore ? t('webhookEndpoint.loadingMore') : t('webhookEndpoint.loadMore')
          })
        })]
      })
    }), /*#__PURE__*/_jsxs(Grid, {
      size: {
        xs: 12,
        md: 8
      },
      sx: {
        height: 1
      },
      children: [selected && /*#__PURE__*/_jsxs(Stack, {
        direction: "column",
        spacing: 2,
        sx: {
          height: 1,
          overflow: 'auto',
          pl: {
            xs: 0,
            md: 1
          },
          mt: {
            xs: 2,
            md: 0
          },
          borderLeft: {
            xs: 'none'
          }
        },
        children: [/*#__PURE__*/_jsxs(Box, {
          sx: {
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'space-between'
          },
          children: [/*#__PURE__*/_jsxs(Box, {
            sx: {
              display: 'flex',
              alignItems: 'center',
              gap: 1
            },
            children: [/*#__PURE__*/_jsx(Typography, {
              variant: "h4",
              children: t(`common.${selected.status}`)
            }), /*#__PURE__*/_jsx(Box, {
              children: renderLog(selected)
            })]
          }), /*#__PURE__*/_jsxs(Box, {
            sx: {
              display: 'flex',
              alignItems: 'center',
              gap: 1
            },
            children: [foundTriggeredFrom && /*#__PURE__*/_jsx(Tooltip, {
              placement: "left",
              title: /*#__PURE__*/_jsxs(Stack, {
                onClick: () => setSelected(foundTriggeredFrom),
                sx: {
                  gap: 1,
                  cursor: 'pointer',
                  '.did-address-text': {
                    color: 'common.white'
                  }
                },
                children: [/*#__PURE__*/_jsx(UserCard, {
                  showDid: true,
                  did: selected.triggeredBy,
                  cardType: CardType.Detailed,
                  infoType: InfoType.Minimal,
                  sx: {
                    border: 0,
                    padding: 0,
                    minWidth: 0,
                    '.MuiTypography-root': {
                      color: 'common.white',
                      fontWeight: 400
                    }
                  }
                }), /*#__PURE__*/_jsx(Divider, {}), /*#__PURE__*/_jsxs(Box, {
                  sx: {
                    display: 'flex',
                    flexDirection: 'column'
                  },
                  children: [/*#__PURE__*/_jsx(Typography, {
                    variant: "body2",
                    sx: {
                      color: 'primary.main'
                    },
                    children: t('webhookEndpoint.triggeredFrom')
                  }), /*#__PURE__*/_jsxs(Box, {
                    sx: {
                      display: 'flex',
                      alignItems: 'center',
                      gap: 1
                    },
                    children: [/*#__PURE__*/_jsx(Typography, {
                      variant: "body2",
                      children: selected.id
                    }), /*#__PURE__*/_jsx(IconButton, {
                      onClick: () => setSelected(foundTriggeredFrom),
                      children: /*#__PURE__*/_jsx(Box, {
                        component: Icon,
                        icon: ShareIcon,
                        sx: {
                          fontSize: 16,
                          color: 'common.white'
                        }
                      })
                    })]
                  })]
                })]
              }),
              slotProps: {
                tooltip: {
                  sx: {
                    maxWidth: 400
                  }
                }
              },
              children: /*#__PURE__*/_jsx(IconButton, {
                onClick: () => setSelected(foundTriggeredFrom),
                children: /*#__PURE__*/_jsx(Box, {
                  component: Icon,
                  icon: ShareIcon,
                  sx: {
                    fontSize: 16
                  }
                })
              })
            }), /*#__PURE__*/_jsxs(Button, {
              variant: "outlined",
              color: "primary",
              size: "small",
              onClick: handleRetry,
              disabled: retryAttemptLoading,
              children: [/*#__PURE__*/_jsx(Box, {
                component: Icon,
                icon: RefreshIcon,
                sx: {
                  fontSize: 16,
                  animation: retryAttemptLoading ? 'spin 1s linear infinite' : 'none',
                  mr: 0.5
                }
              }), t('notification.resend')]
            })]
          })]
        }), /*#__PURE__*/_jsxs(Box, {
          children: [/*#__PURE__*/_jsxs(Typography, {
            variant: "h6",
            children: [t('webhookEndpoint.response'), " (", selected.responseStatus, ")"]
          }), /*#__PURE__*/_jsx(CodeBlock, {
            language: "json",
            children: JSON.stringify(selected.responseBody, null, 2)
          })]
        }), /*#__PURE__*/_jsxs(Box, {
          children: [/*#__PURE__*/_jsx(Stack, {
            direction: "row",
            spacing: 1,
            sx: {
              alignItems: 'center'
            },
            children: /*#__PURE__*/_jsx(Typography, {
              variant: "h6",
              children: t('webhookEndpoint.request')
            })
          }), /*#__PURE__*/_jsx(CodeBlock, {
            language: "json",
            sx: {
              margin: 0
            },
            children: JSON.stringify(selected.event, null, 2)
          })]
        })]
      }), data?.list.length === 0 && event && /*#__PURE__*/_jsxs(Box, {
        children: [/*#__PURE__*/_jsx(Stack, {
          direction: "row",
          spacing: 1,
          sx: {
            alignItems: 'center'
          },
          children: /*#__PURE__*/_jsx(Typography, {
            variant: "h6",
            children: t('webhookEndpoint.eventData')
          })
        }), /*#__PURE__*/_jsx(CodeBlock, {
          language: "json",
          sx: {
            margin: 0
          },
          children: JSON.stringify(event.data, null, 2)
        })]
      })]
    })]
  });
}
WebhookAttempts.propTypes = {
  eventId: PropTypes.string,
  webhookEndpointId: PropTypes.string,
  event: PropTypes.shape({
    type: PropTypes.string,
    data: PropTypes.object,
    request: PropTypes.object,
    requestInfo: PropTypes.object
  })
};
const Container = styled(Grid)`
  @keyframes spin {
    to {
      transform: rotate(360deg);
    }
  }
`;