import { useState, useCallback } from 'react';
import {
  Button,
  Modal,
  TextInput,
  Textarea,
  Select,
  Stack,
  Text,
  Group,
  Paper,
  Badge,
  LoadingOverlay,
} from '@mantine/core';
import { useForm } from '@mantine/form';
import { useDisclosure } from '@mantine/hooks';
import { notifications } from '@mantine/notifications';
import * as TablerIcons from '@tabler/icons-react';
import { useMutation } from 'convex/react';
import type { FunctionReference } from 'convex/server';

const IconBug = TablerIcons.IconBug as React.FC<{ size?: number }>;
const IconCheck = TablerIcons.IconCheck as React.FC<{ size?: number }>;

/**
 * Props for the ErrorBugReportButton component
 */
export interface ErrorBugReportButtonProps {
  /** The error to report */
  error: Error;
  /** Reporter type: 'staff' for internal users, 'customer' for external users */
  reporterType?: 'staff' | 'customer';
  /** Unique identifier for the reporter (defaults to 'error-page') */
  reporterId?: string;
  /** Reporter's email address (defaults to 'unknown@example.com') */
  reporterEmail?: string;
  /** Reporter's display name (defaults to 'Error Page Reporter') */
  reporterName?: string;
  /** Convex API reference for bug reports */
  bugReportApi: {
    create: FunctionReference<'mutation'>;
  };
  /** Button variant (default: 'outline') */
  variant?: 'filled' | 'outline' | 'light' | 'subtle';
  /** Button color (default: 'red') */
  color?: string;
  /** Callback when submission succeeds */
  onSuccess?: () => void;
  /** Callback when submission fails */
  onError?: (error: Error) => void;
}

interface BrowserInfo {
  userAgent: string;
  platform: string;
  language: string;
  cookiesEnabled: boolean;
  onLine: boolean;
  screenWidth: number;
  screenHeight: number;
  colorDepth: number;
  pixelRatio: number;
}

/**
 * A self-contained bug report button designed for error pages.
 * Pre-fills the error details and allows users to submit bug reports
 * directly from error pages.
 *
 * @example
 * ```tsx
 * import { ErrorBugReportButton } from '@fatagnus/convex-feedback/react';
 * import { api } from './convex/_generated/api';
 *
 * function ErrorPage({ error }: { error: Error }) {
 *   return (
 *     <div>
 *       <h1>Something went wrong</h1>
 *       <ErrorBugReportButton
 *         error={error}
 *         reporterType="staff"
 *         bugReportApi={{
 *           create: api.feedback.bugReports.create,
 *         }}
 *       />
 *     </div>
 *   );
 * }
 * ```
 */
export function ErrorBugReportButton({
  error,
  reporterType = 'staff',
  reporterId = 'error-page',
  reporterEmail = 'unknown@example.com',
  reporterName = 'Error Page Reporter',
  bugReportApi,
  variant = 'outline',
  color = 'red',
  onSuccess,
  onError,
}: ErrorBugReportButtonProps) {
  const [opened, { open, close }] = useDisclosure(false);
  const [isSubmitting, setIsSubmitting] = useState(false);

  const createReport = useMutation(bugReportApi.create);

  const form = useForm({
    initialValues: {
      title: `Error: ${error?.message?.slice(0, 50) || 'Unknown error'}${(error?.message?.length || 0) > 50 ? '...' : ''}`,
      description: '',
      severity: 'high' as 'low' | 'medium' | 'high' | 'critical',
    },
    validate: {
      title: (value) =>
        value.trim().length < 5 ? 'Title must be at least 5 characters' : null,
      description: (value) =>
        value.trim().length < 10
          ? 'Please provide more details (at least 10 characters)'
          : null,
    },
  });

  const getBrowserInfo = useCallback((): BrowserInfo => {
    return {
      userAgent: navigator.userAgent,
      platform: navigator.platform,
      language: navigator.language,
      cookiesEnabled: navigator.cookieEnabled,
      onLine: navigator.onLine,
      screenWidth: window.screen.width,
      screenHeight: window.screen.height,
      colorDepth: window.screen.colorDepth,
      pixelRatio: window.devicePixelRatio,
    };
  }, []);

  const getErrorDetails = useCallback((): string => {
    const parts = [
      '--- Error Details ---',
      `Message: ${error?.message || 'Unknown error'}`,
    ];

    if (error?.stack) {
      parts.push('', 'Stack Trace:', error.stack);
    }

    return parts.join('\n');
  }, [error]);

  const handleSubmit = async (values: typeof form.values) => {
    setIsSubmitting(true);
    try {
      // Build the full description with error details
      const fullDescription = [
        values.description,
        '',
        getErrorDetails(),
      ].join('\n');

      // Create the report
      await createReport({
        title: values.title,
        description: fullDescription,
        severity: values.severity,
        reporterType,
        reporterId,
        reporterEmail,
        reporterName,
        url: window.location.href,
        route: window.location.pathname,
        browserInfo: JSON.stringify(getBrowserInfo()),
        viewportWidth: window.innerWidth,
        viewportHeight: window.innerHeight,
        networkState: navigator.onLine ? 'online' : 'offline',
      });

      notifications.show({
        title: 'Bug report submitted',
        message: 'Thank you for reporting this error! We will investigate.',
        color: 'green',
        icon: <IconCheck size={16} />,
      });

      onSuccess?.();

      form.reset();
      close();
    } catch (submitError) {
      console.error('Failed to submit bug report:', submitError);
      notifications.show({
        title: 'Submission failed',
        message: 'Could not submit bug report. Please try again.',
        color: 'red',
      });
      onError?.(submitError instanceof Error ? submitError : new Error(String(submitError)));
    } finally {
      setIsSubmitting(false);
    }
  };

  const handleOpen = () => {
    // Reset form with current error info
    form.setValues({
      title: `Error: ${error?.message?.slice(0, 50) || 'Unknown error'}${(error?.message?.length || 0) > 50 ? '...' : ''}`,
      description: '',
      severity: 'high',
    });
    open();
  };

  return (
    <>
      <Button
        data-testid="error-report-bug-button"
        leftSection={<IconBug size={16} />}
        onClick={handleOpen}
        variant={variant}
        color={color}
      >
        Report Bug
      </Button>

      <Modal
        opened={opened}
        onClose={close}
        title={
          <Group gap="xs">
            <IconBug size={20} />
            <Text fw={600}>Report This Error</Text>
          </Group>
        }
        size="md"
      >
        <LoadingOverlay visible={isSubmitting} />
        <form onSubmit={form.onSubmit(handleSubmit)}>
          <Stack gap="md">
            <TextInput
              label="Title"
              placeholder="Brief summary of the issue"
              required
              {...form.getInputProps('title')}
            />

            <Textarea
              label="What were you doing when this error occurred?"
              placeholder="Please describe what you were trying to do, what you expected to happen, and any other relevant context."
              required
              minRows={3}
              {...form.getInputProps('description')}
            />

            <Select
              label="Severity"
              placeholder="How severe is this issue?"
              data={[
                { value: 'low', label: 'Low - Minor inconvenience' },
                { value: 'medium', label: 'Medium - Affects workflow' },
                { value: 'high', label: 'High - Major functionality broken' },
                { value: 'critical', label: 'Critical - System unusable' },
              ]}
              {...form.getInputProps('severity')}
            />

            {/* Error Details Preview */}
            <Paper withBorder p="xs" radius="md" bg="var(--mantine-color-red-light)">
              <Stack gap="xs">
                <Group gap="xs">
                  <Badge size="xs" color="red">
                    Error Details (auto-included)
                  </Badge>
                </Group>
                <Text
                  size="xs"
                  c="dimmed"
                  style={{ fontFamily: 'monospace', whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}
                >
                  {error?.message || 'Unknown error'}
                </Text>
              </Stack>
            </Paper>

            {/* Auto-captured Info Badge */}
            <Paper withBorder p="xs" radius="md">
              <Group gap="xs">
                <Badge size="xs" variant="outline" color="gray">
                  Auto-captured
                </Badge>
                <Text size="xs" c="dimmed">
                  Browser info, URL, viewport size, and full stack trace will be included.
                </Text>
              </Group>
            </Paper>

            {/* Submit Buttons */}
            <Group justify="flex-end" mt="md">
              <Button variant="subtle" onClick={close} disabled={isSubmitting}>
                Cancel
              </Button>
              <Button type="submit" color="red" loading={isSubmitting}>
                Submit Report
              </Button>
            </Group>
          </Stack>
        </form>
      </Modal>
    </>
  );
}

export default ErrorBugReportButton;
