import { useState, useRef, useEffect } from 'react';
import {
  Stack,
  Paper,
  Text,
  TextInput,
  Textarea,
  Button,
  Group,
  Card,
  Badge,
  Radio,
  Loader,
  ScrollArea,
  Box,
  ThemeIcon,
  Divider,
  Select,
} from '@mantine/core';
import * as TablerIcons from '@tabler/icons-react';

const IconRobot = TablerIcons.IconRobot as React.FC<{ size?: number }>;
const IconUser = TablerIcons.IconUser as React.FC<{ size?: number }>;
const IconSend = TablerIcons.IconSend as React.FC<{ size?: number }>;
const IconEdit = TablerIcons.IconEdit as React.FC<{ size?: number }>;
const IconCheck = TablerIcons.IconCheck as React.FC<{ size?: number }>;

/**
 * Input option for choice type
 */
export interface InputOption {
  label: string;
  value: string;
  description?: string;
}

/**
 * Input field for form type
 */
export interface InputField {
  name: string;
  label: string;
  type: 'text' | 'number' | 'email' | 'textarea';
  required: boolean;
  placeholder?: string;
}

/**
 * Configuration for input requests
 */
export interface InputConfig {
  placeholder?: string;
  multiline?: boolean;
  options?: InputOption[];
  fields?: InputField[];
}

/**
 * A message in the interview conversation
 */
export interface InterviewMessage {
  id: string;
  role: 'assistant' | 'user';
  content: string;
  timestamp: number;
}

/**
 * Pending input request
 */
export interface PendingRequest {
  requestId: string;
  inputType: 'text' | 'choice' | 'form';
  prompt: string;
  config?: InputConfig;
}

/**
 * Generated report from interview
 */
export interface GeneratedReport {
  title: string;
  description: string;
  severity?: 'low' | 'medium' | 'high' | 'critical';
  type?: 'feature_request' | 'change_request' | 'general';
  priority?: 'nice_to_have' | 'important' | 'critical';
  featureArea?: string;
  reproductionSteps?: string[];
}

/**
 * Props for InterviewChat component
 */
export interface InterviewChatProps {
  /** Messages in the conversation */
  messages: InterviewMessage[];
  /** Whether we're waiting for AI response */
  isThinking: boolean;
  /** Whether we're waiting for user input */
  waitingForInput: boolean;
  /** Current pending input request */
  pendingRequest?: PendingRequest;
  /** Whether the interview is complete */
  isComplete: boolean;
  /** Generated report if complete */
  generatedReport?: GeneratedReport;
  /** Report type */
  reportType: 'bug' | 'feedback';
  /** Callback when user submits input */
  onSubmitInput: (response: string) => void;
  /** Callback when user confirms the generated report */
  onConfirmReport: (report: GeneratedReport) => void;
  /** Callback when user wants to edit the report */
  onEditReport?: () => void;
  /** Whether submission is in progress */
  isSubmitting?: boolean;
}

/**
 * Message bubble component
 */
function MessageBubble({ message }: { message: InterviewMessage }) {
  const isAssistant = message.role === 'assistant';
  
  return (
    <Group align="flex-start" gap="sm" wrap="nowrap">
      {isAssistant && (
        <ThemeIcon size="md" radius="xl" color="blue" variant="light">
          <IconRobot size={16} />
        </ThemeIcon>
      )}
      <Paper
        p="sm"
        radius="md"
        style={{
          backgroundColor: isAssistant 
            ? 'var(--mantine-color-blue-light)' 
            : 'var(--mantine-color-gray-light)',
          maxWidth: '85%',
          marginLeft: isAssistant ? 0 : 'auto',
          marginRight: isAssistant ? 'auto' : 0,
        }}
      >
        <Text size="sm" style={{ whiteSpace: 'pre-wrap' }}>
          {message.content}
        </Text>
      </Paper>
      {!isAssistant && (
        <ThemeIcon size="md" radius="xl" color="gray" variant="light">
          <IconUser size={16} />
        </ThemeIcon>
      )}
    </Group>
  );
}

/**
 * Text input form
 */
function TextInputForm({
  config,
  onSubmit,
  isSubmitting,
}: {
  config?: InputConfig;
  onSubmit: (value: string) => void;
  isSubmitting: boolean;
}) {
  const [value, setValue] = useState('');

  const handleSubmit = () => {
    if (value.trim()) {
      onSubmit(value.trim());
      setValue('');
    }
  };

  if (config?.multiline) {
    return (
      <Stack gap="xs">
        <Textarea
          placeholder={config?.placeholder || 'Type your response...'}
          value={value}
          onChange={(e) => setValue(e.target.value)}
          minRows={3}
          autoFocus
          onKeyDown={(e) => {
            if (e.key === 'Enter' && e.metaKey) {
              handleSubmit();
            }
          }}
        />
        <Group justify="flex-end">
          <Text size="xs" c="dimmed">⌘ + Enter to send</Text>
          <Button
            size="sm"
            onClick={handleSubmit}
            disabled={!value.trim() || isSubmitting}
            loading={isSubmitting}
            leftSection={<IconSend size={14} />}
          >
            Send
          </Button>
        </Group>
      </Stack>
    );
  }

  return (
    <Group gap="xs">
      <TextInput
        placeholder={config?.placeholder || 'Type your response...'}
        value={value}
        onChange={(e) => setValue(e.target.value)}
        style={{ flex: 1 }}
        autoFocus
        onKeyDown={(e) => {
          if (e.key === 'Enter') {
            handleSubmit();
          }
        }}
      />
      <Button
        size="sm"
        onClick={handleSubmit}
        disabled={!value.trim() || isSubmitting}
        loading={isSubmitting}
        leftSection={<IconSend size={14} />}
      >
        Send
      </Button>
    </Group>
  );
}

/**
 * Choice input form (radio buttons)
 */
function ChoiceInputForm({
  config,
  onSubmit,
  isSubmitting,
}: {
  config?: InputConfig;
  onSubmit: (value: string) => void;
  isSubmitting: boolean;
}) {
  const [selected, setSelected] = useState<string>('');

  const handleSubmit = () => {
    if (selected) {
      onSubmit(selected);
      setSelected('');
    }
  };

  if (!config?.options || config.options.length === 0) {
    return <Text c="red" size="sm">No options provided</Text>;
  }

  return (
    <Stack gap="sm">
      <Radio.Group value={selected} onChange={setSelected}>
        <Stack gap="xs">
          {config.options.map((option) => (
            <Paper key={option.value} withBorder p="sm" radius="md">
              <Radio
                value={option.value}
                label={
                  <Box>
                    <Text size="sm" fw={500}>{option.label}</Text>
                    {option.description && (
                      <Text size="xs" c="dimmed">{option.description}</Text>
                    )}
                  </Box>
                }
              />
            </Paper>
          ))}
        </Stack>
      </Radio.Group>
      <Group justify="flex-end">
        <Button
          size="sm"
          onClick={handleSubmit}
          disabled={!selected || isSubmitting}
          loading={isSubmitting}
          leftSection={<IconSend size={14} />}
        >
          Send
        </Button>
      </Group>
    </Stack>
  );
}

/**
 * Form input (multiple fields)
 */
function FormInputForm({
  config,
  onSubmit,
  isSubmitting,
}: {
  config?: InputConfig;
  onSubmit: (value: string) => void;
  isSubmitting: boolean;
}) {
  const [values, setValues] = useState<Record<string, string>>({});

  const handleSubmit = () => {
    const result = JSON.stringify(values);
    onSubmit(result);
    setValues({});
  };

  if (!config?.fields || config.fields.length === 0) {
    return <Text c="red" size="sm">No fields provided</Text>;
  }

  const isValid = config.fields
    .filter((f) => f.required)
    .every((f) => values[f.name]?.trim());

  return (
    <Stack gap="sm">
      {config.fields.map((field) => {
        if (field.type === 'textarea') {
          return (
            <Textarea
              key={field.name}
              label={field.label}
              placeholder={field.placeholder}
              required={field.required}
              value={values[field.name] || ''}
              onChange={(e) => setValues({ ...values, [field.name]: e.target.value })}
              minRows={2}
            />
          );
        }
        return (
          <TextInput
            key={field.name}
            label={field.label}
            placeholder={field.placeholder}
            required={field.required}
            type={field.type}
            value={values[field.name] || ''}
            onChange={(e) => setValues({ ...values, [field.name]: e.target.value })}
          />
        );
      })}
      <Group justify="flex-end">
        <Button
          size="sm"
          onClick={handleSubmit}
          disabled={!isValid || isSubmitting}
          loading={isSubmitting}
          leftSection={<IconSend size={14} />}
        >
          Send
        </Button>
      </Group>
    </Stack>
  );
}

/**
 * Report preview component
 */
function ReportPreview({
  report,
  reportType,
  onConfirm,
  onEdit,
  isSubmitting,
}: {
  report: GeneratedReport;
  reportType: 'bug' | 'feedback';
  onConfirm: (report: GeneratedReport) => void;
  onEdit?: () => void;
  isSubmitting: boolean;
}) {
  const [isEditing, setIsEditing] = useState(false);
  const [editedReport, setEditedReport] = useState(report);

  const handleConfirm = () => {
    onConfirm(isEditing ? editedReport : report);
  };

  if (isEditing) {
    return (
      <Card withBorder>
        <Card.Section p="md" style={{ borderBottom: '1px solid var(--mantine-color-gray-3)' }}>
          <Group justify="space-between">
            <Text fw={600}>Edit Your {reportType === 'bug' ? 'Bug Report' : 'Feedback'}</Text>
            <Button variant="subtle" size="xs" onClick={() => setIsEditing(false)}>
              Cancel Edit
            </Button>
          </Group>
        </Card.Section>
        <Card.Section p="md">
          <Stack gap="md">
            <TextInput
              label="Title"
              value={editedReport.title}
              onChange={(e) => setEditedReport({ ...editedReport, title: e.target.value })}
            />
            <Textarea
              label="Description"
              value={editedReport.description}
              onChange={(e) => setEditedReport({ ...editedReport, description: e.target.value })}
              minRows={4}
            />
            {reportType === 'bug' && (
              <Select
                label="Severity"
                value={editedReport.severity}
                onChange={(value) => setEditedReport({ ...editedReport, severity: value as any })}
                data={[
                  { value: 'low', label: 'Low' },
                  { value: 'medium', label: 'Medium' },
                  { value: 'high', label: 'High' },
                  { value: 'critical', label: 'Critical' },
                ]}
              />
            )}
            {reportType === 'feedback' && (
              <>
                <Select
                  label="Type"
                  value={editedReport.type}
                  onChange={(value) => setEditedReport({ ...editedReport, type: value as any })}
                  data={[
                    { value: 'feature_request', label: 'Feature Request' },
                    { value: 'change_request', label: 'Change Request' },
                    { value: 'general', label: 'General Feedback' },
                  ]}
                />
                <Select
                  label="Priority"
                  value={editedReport.priority}
                  onChange={(value) => setEditedReport({ ...editedReport, priority: value as any })}
                  data={[
                    { value: 'nice_to_have', label: 'Nice to Have' },
                    { value: 'important', label: 'Important' },
                    { value: 'critical', label: 'Critical' },
                  ]}
                />
              </>
            )}
          </Stack>
        </Card.Section>
        <Card.Section p="md" style={{ borderTop: '1px solid var(--mantine-color-gray-3)' }}>
          <Group justify="flex-end">
            <Button
              onClick={handleConfirm}
              loading={isSubmitting}
              leftSection={<IconCheck size={16} />}
            >
              Submit {reportType === 'bug' ? 'Bug Report' : 'Feedback'}
            </Button>
          </Group>
        </Card.Section>
      </Card>
    );
  }

  return (
    <Card withBorder>
      <Card.Section p="md" style={{ borderBottom: '1px solid var(--mantine-color-gray-3)', backgroundColor: 'var(--mantine-color-green-light)' }}>
        <Group justify="space-between">
          <Group gap="xs">
            <IconCheck size={16} />
            <Text fw={600}>Generated {reportType === 'bug' ? 'Bug Report' : 'Feedback'}</Text>
          </Group>
          <Badge color="green" variant="light">Ready to Submit</Badge>
        </Group>
      </Card.Section>
      <Card.Section p="md">
        <Stack gap="md">
          <Box>
            <Text size="xs" c="dimmed" tt="uppercase" fw={600}>Title</Text>
            <Text fw={500}>{report.title}</Text>
          </Box>
          <Box>
            <Text size="xs" c="dimmed" tt="uppercase" fw={600}>Description</Text>
            <Text size="sm" style={{ whiteSpace: 'pre-wrap' }}>{report.description}</Text>
          </Box>
          <Group gap="md">
            {reportType === 'bug' && report.severity && (
              <Box>
                <Text size="xs" c="dimmed" tt="uppercase" fw={600}>Severity</Text>
                <Badge color={report.severity === 'critical' ? 'red' : report.severity === 'high' ? 'orange' : report.severity === 'medium' ? 'yellow' : 'blue'}>
                  {report.severity}
                </Badge>
              </Box>
            )}
            {reportType === 'feedback' && report.type && (
              <Box>
                <Text size="xs" c="dimmed" tt="uppercase" fw={600}>Type</Text>
                <Badge color="violet">{report.type.replace('_', ' ')}</Badge>
              </Box>
            )}
            {reportType === 'feedback' && report.priority && (
              <Box>
                <Text size="xs" c="dimmed" tt="uppercase" fw={600}>Priority</Text>
                <Badge color={report.priority === 'critical' ? 'red' : report.priority === 'important' ? 'orange' : 'blue'}>
                  {report.priority.replace('_', ' ')}
                </Badge>
              </Box>
            )}
            {report.featureArea && (
              <Box>
                <Text size="xs" c="dimmed" tt="uppercase" fw={600}>Feature Area</Text>
                <Badge color="gray" variant="outline">{report.featureArea}</Badge>
              </Box>
            )}
          </Group>
          {report.reproductionSteps && report.reproductionSteps.length > 0 && (
            <Box>
              <Text size="xs" c="dimmed" tt="uppercase" fw={600}>Reproduction Steps</Text>
              <Stack gap={4} mt={4}>
                {report.reproductionSteps.map((step, i) => (
                  <Text key={i} size="sm">{i + 1}. {step}</Text>
                ))}
              </Stack>
            </Box>
          )}
        </Stack>
      </Card.Section>
      <Card.Section p="md" style={{ borderTop: '1px solid var(--mantine-color-gray-3)' }}>
        <Group justify="space-between">
          <Button
            variant="subtle"
            size="sm"
            leftSection={<IconEdit size={14} />}
            onClick={() => setIsEditing(true)}
            disabled={isSubmitting}
          >
            Edit
          </Button>
          <Button
            onClick={handleConfirm}
            loading={isSubmitting}
            leftSection={<IconCheck size={16} />}
          >
            Submit {reportType === 'bug' ? 'Bug Report' : 'Feedback'}
          </Button>
        </Group>
      </Card.Section>
    </Card>
  );
}

/**
 * Main InterviewChat component
 */
export function InterviewChat({
  messages,
  isThinking,
  waitingForInput,
  pendingRequest,
  isComplete,
  generatedReport,
  reportType,
  onSubmitInput,
  onConfirmReport,
  onEditReport,
  isSubmitting = false,
}: InterviewChatProps) {
  const scrollRef = useRef<HTMLDivElement>(null);

  // Auto-scroll to bottom when messages change
  useEffect(() => {
    if (scrollRef.current) {
      scrollRef.current.scrollTo({ top: scrollRef.current.scrollHeight, behavior: 'smooth' });
    }
  }, [messages, isThinking, waitingForInput, isComplete]);

  return (
    <Stack gap="md" style={{ height: '100%' }}>
      {/* Messages area */}
      <ScrollArea h={350} viewportRef={scrollRef}>
        <Stack gap="md" p="xs">
          {messages.map((message) => (
            <MessageBubble key={message.id} message={message} />
          ))}
          
          {/* Thinking indicator */}
          {isThinking && (
            <Group gap="sm">
              <ThemeIcon size="md" radius="xl" color="blue" variant="light">
                <IconRobot size={16} />
              </ThemeIcon>
              <Paper p="sm" radius="md" style={{ backgroundColor: 'var(--mantine-color-blue-light)' }}>
                <Group gap="xs">
                  <Loader size="xs" />
                  <Text size="sm" c="dimmed">Thinking...</Text>
                </Group>
              </Paper>
            </Group>
          )}
        </Stack>
      </ScrollArea>

      <Divider />

      {/* Input area */}
      <Box>
        {isComplete && generatedReport ? (
          <ReportPreview
            report={generatedReport}
            reportType={reportType}
            onConfirm={onConfirmReport}
            onEdit={onEditReport}
            isSubmitting={isSubmitting}
          />
        ) : waitingForInput && pendingRequest ? (
          <Stack gap="xs">
            <Text size="sm" fw={500}>{pendingRequest.prompt}</Text>
            {pendingRequest.inputType === 'text' && (
              <TextInputForm
                config={pendingRequest.config}
                onSubmit={onSubmitInput}
                isSubmitting={isSubmitting}
              />
            )}
            {pendingRequest.inputType === 'choice' && (
              <ChoiceInputForm
                config={pendingRequest.config}
                onSubmit={onSubmitInput}
                isSubmitting={isSubmitting}
              />
            )}
            {pendingRequest.inputType === 'form' && (
              <FormInputForm
                config={pendingRequest.config}
                onSubmit={onSubmitInput}
                isSubmitting={isSubmitting}
              />
            )}
          </Stack>
        ) : isThinking ? (
          <Paper p="md" withBorder radius="md" style={{ backgroundColor: 'var(--mantine-color-gray-light)' }}>
            <Group justify="center">
              <Loader size="sm" />
              <Text size="sm" c="dimmed">AI is preparing the next question...</Text>
            </Group>
          </Paper>
        ) : null}
      </Box>
    </Stack>
  );
}
