import React, { FormEventHandler, useState } from 'react';
import FocusTrap from 'focus-trap-react';
import {
  Box,
  Button,
  Dialog,
  Header,
  Icon,
  IconButton,
  Icons,
  Input,
  Overlay,
  OverlayBackdrop,
  OverlayCenter,
  Spinner,
  Text,
  color,
  config,
} from 'folds';
import { Room } from 'matrix-js-sdk';
import { useMatrixClient } from '../../hooks/useMatrixClient';
import { stopPropagation } from '../../utils/keyboard';
import { useModalStyle } from '../../hooks/useModalStyle';

interface PollCreatorProps {
  roomId: string;
  room: Room;
  onClose: () => void;
}

export function PollCreator({ roomId, onClose }: PollCreatorProps) {
  const mx = useMatrixClient();
  const modalStyle = useModalStyle(440);
  const [question, setQuestion] = useState('');
  const [options, setOptions] = useState<string[]>(['', '']);
  const [isMultiple, setIsMultiple] = useState(false);
  // For multiple-choice polls: the most options a voter may pick. Defaults high
  // so an untouched multiple poll means "select all that apply" (the previous
  // behavior); the effective value is clamped to the current option count.
  const [maxSelections, setMaxSelections] = useState(10);
  // Results visibility: disclosed (live results, default) vs undisclosed (hidden
  // until the poll is ended).
  const [disclosed, setDisclosed] = useState(true);
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const handleOptionChange = (index: number, value: string) => {
    setOptions((prev) => {
      const next = [...prev];
      next[index] = value;
      return next;
    });
  };

  const handleAddOption = () => {
    if (options.length >= 10) return;
    setOptions((prev) => [...prev, '']);
  };

  const handleRemoveOption = (index: number) => {
    if (options.length <= 2) return;
    setOptions((prev) => prev.filter((_, i) => i !== index));
  };

  const handleSubmit: FormEventHandler<HTMLFormElement> = async (e) => {
    e.preventDefault();
    if (submitting) return;

    const trimmedQuestion = question.trim();
    if (!trimmedQuestion) {
      setError('Please enter a question.');
      return;
    }
    const filledOptions = options.map((o) => o.trim()).filter((o) => o.length > 0);
    if (filledOptions.length < 2) {
      setError('Please provide at least 2 answer options.');
      return;
    }

    setError(null);
    setSubmitting(true);
    try {
      // Text fallback for clients that don't understand polls: the question + a
      // numbered list of the options.
      const fallbackBody = [trimmedQuestion, ...filledOptions.map((o, i) => `${i + 1}. ${o}`)].join(
        '\n',
      );
      await mx.sendEvent(roomId, 'm.poll.start' as any, {
        'm.poll': {
          question: { 'm.text': trimmedQuestion },
          answers: filledOptions.map((o, i) => ({ 'm.id': `${i}`, 'm.text': o })),
          max_selections: isMultiple
            ? Math.min(Math.max(2, maxSelections), filledOptions.length)
            : 1,
          kind: disclosed ? 'm.poll.disclosed' : 'm.poll.undisclosed',
        },
        body: fallbackBody,
        msgtype: 'm.text',
      });
      onClose();
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to send poll.');
      setSubmitting(false);
    }
  };

  return (
    <Overlay open backdrop={<OverlayBackdrop />}>
      <OverlayCenter>
        <FocusTrap
          focusTrapOptions={{
            initialFocus: false,
            onDeactivate: onClose,
            clickOutsideDeactivates: true,
            escapeDeactivates: stopPropagation,
          }}
        >
          <Dialog
            as="form"
            variant="Surface"
            role="dialog"
            aria-modal="true"
            aria-labelledby="poll-creator-title"
            onSubmit={handleSubmit}
            style={modalStyle}
          >
            {/* Header */}
            <Header
              variant="Surface"
              size="500"
              style={{
                padding: `0 ${config.space.S200} 0 ${config.space.S400}`,
                borderBottomWidth: config.borderWidth.B300,
              }}
            >
              <Box grow="Yes">
                <Text id="poll-creator-title" size="H4">
                  Create Poll
                </Text>
              </Box>
              <IconButton size="300" radii="300" onClick={onClose} aria-label="Close">
                <Icon src={Icons.Cross} />
              </IconButton>
            </Header>

            {/* Body */}
            <Box direction="Column" gap="400" style={{ padding: config.space.S400 }}>
              {/* Question */}
              <Box direction="Column" gap="100">
                <Text as="label" htmlFor="poll-question" size="L400">
                  Question
                </Text>
                <Input
                  id="poll-question"
                  variant="Background"
                  placeholder="Ask a question…"
                  value={question}
                  onChange={(e: React.ChangeEvent<HTMLInputElement>) => setQuestion(e.target.value)}
                  autoFocus
                />
              </Box>

              {/* Options */}
              <Box direction="Column" gap="200">
                <Text size="L400">Options</Text>
                {options.map((opt, index) => (
                  <Box key={index} alignItems="Center" gap="200">
                    <Input
                      style={{ flex: 1 }}
                      variant="Background"
                      placeholder={`Option ${index + 1}`}
                      value={opt}
                      onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
                        handleOptionChange(index, e.target.value)
                      }
                      aria-label={`Option ${index + 1}`}
                    />
                    <IconButton
                      size="300"
                      radii="300"
                      variant="SurfaceVariant"
                      type="button"
                      onClick={() => handleRemoveOption(index)}
                      disabled={options.length <= 2}
                      aria-label={`Remove option ${index + 1}`}
                    >
                      <Icon src={Icons.Cross} size="100" />
                    </IconButton>
                  </Box>
                ))}
                {options.length < 10 && (
                  <Box>
                    <Button
                      type="button"
                      size="300"
                      variant="Secondary"
                      fill="None"
                      radii="300"
                      before={<Icon src={Icons.Plus} size="100" />}
                      onClick={handleAddOption}
                    >
                      <Text size="B300">Add Option</Text>
                    </Button>
                  </Box>
                )}
              </Box>

              {/* Selection type */}
              <Box direction="Column" gap="100">
                <Text size="L400">Selection Type</Text>
                <Box gap="200">
                  {(['single', 'multiple'] as const).map((type) => {
                    const active = type === 'multiple' ? isMultiple : !isMultiple;
                    return (
                      <Button
                        key={type}
                        type="button"
                        size="300"
                        variant="Primary"
                        fill={active ? 'Solid' : 'None'}
                        radii="300"
                        onClick={() => setIsMultiple(type === 'multiple')}
                      >
                        <Text size="B300">
                          {type === 'single' ? 'Single choice' : 'Multiple choice'}
                        </Text>
                      </Button>
                    );
                  })}
                </Box>
                {isMultiple && (
                  <Box alignItems="Center" gap="200" style={{ marginTop: config.space.S200 }}>
                    <Text as="label" htmlFor="poll-max-select" size="T200" priority="400">
                      Voters can pick up to
                    </Text>
                    <Input
                      id="poll-max-select"
                      variant="Background"
                      size="300"
                      type="number"
                      min={2}
                      max={options.length}
                      value={Math.min(maxSelections, options.length)}
                      onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
                        setMaxSelections(
                          Math.min(options.length, Math.max(2, parseInt(e.target.value, 10) || 2)),
                        )
                      }
                      style={{ width: '4rem' }}
                    />
                    <Text size="T200" priority="300">
                      of {options.length} options
                    </Text>
                  </Box>
                )}
              </Box>

              {/* Results visibility */}
              <Box direction="Column" gap="100">
                <Text size="L400">Results</Text>
                <Box gap="200">
                  {(['live', 'hidden'] as const).map((mode) => {
                    const active = mode === 'live' ? disclosed : !disclosed;
                    return (
                      <Button
                        key={mode}
                        type="button"
                        size="300"
                        variant="Primary"
                        fill={active ? 'Solid' : 'None'}
                        radii="300"
                        onClick={() => setDisclosed(mode === 'live')}
                      >
                        <Text size="B300">
                          {mode === 'live' ? 'Show live results' : 'Hidden until ended'}
                        </Text>
                      </Button>
                    );
                  })}
                </Box>
              </Box>

              {/* Error */}
              {error && (
                <Text size="T300" style={{ color: color.Critical.Main }}>
                  {error}
                </Text>
              )}

              {/* Footer actions */}
              <Box gap="200" justifyContent="End">
                <Button
                  type="button"
                  size="400"
                  variant="Secondary"
                  fill="None"
                  radii="300"
                  onClick={onClose}
                >
                  <Text size="B400">Cancel</Text>
                </Button>
                <Button
                  type="submit"
                  size="400"
                  variant="Primary"
                  fill="Solid"
                  radii="300"
                  aria-disabled={submitting}
                  before={
                    submitting ? <Spinner variant="Primary" fill="Solid" size="200" /> : undefined
                  }
                >
                  <Text size="B400">{submitting ? 'Creating…' : 'Create Poll'}</Text>
                </Button>
              </Box>
            </Box>
          </Dialog>
        </FocusTrap>
      </OverlayCenter>
    </Overlay>
  );
}
