'use client';

import { useState } from 'react';
import { Box, Text, Title, Stack, Group, Badge, Button } from '@tidbcloud/uikit';
import { isPreparedSourceType, useWorkspace, SOURCE_TYPE_META, SourceType } from '@/lib/workspace';
import { fetchWithAuth } from '@/lib/auth';
import { useTranslation } from '@/lib/i18n';

const API = process.env.NEXT_PUBLIC_API_URL ?? '';

interface AddSourceModalProps {
  opened: boolean;
  onClose: () => void;
}

const ADDABLE_SOURCE_TYPES: SourceType[] = ['jira_issue', 'alertstore_alert'];

// Per-type id validation. Jira ids are PROJECT-NUMBER; alertstore ids are ALT-<week>-<seq>.
const ID_REGEX: Partial<Record<SourceType, RegExp>> = {
  jira_issue: /^[A-Z][A-Z0-9]*-\d+$/,
  alertstore_alert: /^ALT-\d+-\d+$/,
};
const idRegexFor = (type: SourceType | null): RegExp | undefined =>
  type ? ID_REGEX[type] : undefined;

export default function AddSourceModal({ opened, onClose }: AddSourceModalProps) {
  const { t } = useTranslation();
  const { addSource, workspaceId, sources } = useWorkspace();
  const [selectedType, setSelectedType] = useState<SourceType | null>('jira_issue');
  const [name, setName] = useState('');
  const [description, setDescription] = useState('');
  const [issueIdError, setIssueIdError] = useState('');
  const [isSubmitting, setIsSubmitting] = useState(false);

  if (!opened) return null;

  const handleAdd = async () => {
    if (!selectedType || !name.trim()) return;

    const finalName = isPreparedSourceType(selectedType) ? name.trim().toUpperCase() : name.trim();

    const regex = idRegexFor(selectedType);
    if (regex && !regex.test(finalName)) {
      setIssueIdError(
        t(selectedType === 'alertstore_alert' ? 'sources.add.errorInvalidAlertstore' : 'sources.add.errorInvalidJira'),
      );
      return;
    }

    if (isPreparedSourceType(selectedType) && sources.some(s => s.issueId === finalName)) {
      setIssueIdError(t('sources.add.errorAlreadyAdded', { id: finalName }));
      return;
    }

    if (isPreparedSourceType(selectedType) && workspaceId) {
      setIsSubmitting(true);
      try {
        const res = await fetchWithAuth(`${API}/api/sources/prepare`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ issue_id: finalName, workspace_id: workspaceId }),
        });
        const data = await res.json();
        const taskId = data.task_id as string | undefined;

        addSource({
          type: selectedType,
          name: finalName,
          description: description.trim() || undefined,
          issueId: finalName,
          status: 'loading',
          statusMessage: t('sources.add.preparing'),
          taskId,
        });
      } catch {
        addSource({
          type: selectedType,
          name: finalName,
          description: description.trim() || undefined,
          issueId: finalName,
          status: 'error',
          statusMessage: t('sources.add.startFailed'),
        });
      } finally {
        setIsSubmitting(false);
      }
    } else {
      addSource({
        type: selectedType,
        name: finalName,
        description: description.trim() || undefined,
        issueId: isPreparedSourceType(selectedType) ? finalName : undefined,
      });
    }

    setSelectedType('jira_issue');
    setName('');
    setDescription('');
    setIssueIdError('');
    onClose();
  };

  const handleClose = () => {
    setSelectedType('jira_issue');
    setName('');
    setDescription('');
    setIssueIdError('');
    onClose();
  };

  return (
    <>
      {/* Backdrop */}
      <div
        onClick={handleClose}
        style={{
          position: 'fixed',
          inset: 0,
          backgroundColor: 'rgba(0, 0, 0, 0.3)',
          zIndex: 1000,
        }}
      />

      {/* Modal */}
      <Box
        p="lg"
        style={{
          position: 'fixed',
          top: '50%',
          left: '50%',
          transform: 'translate(-50%, -50%)',
          width: '440px',
          maxWidth: '90vw',
          backgroundColor: '#fff',
          borderRadius: '12px',
          boxShadow: '0 20px 60px rgba(0, 0, 0, 0.15)',
          zIndex: 1001,
        }}
      >
        <Stack gap="md">
          <Group justify="space-between" align="center">
            <Title order={5}>{t('sources.add.title')}</Title>
            <button
              onClick={handleClose}
              style={{
                background: 'none',
                border: 'none',
                cursor: 'pointer',
                fontSize: '18px',
                color: '#6b7280',
                padding: '4px',
              }}
            >
              ✕
            </button>
          </Group>

          {/* Source type selection */}
          <Text size="sm" fw={500} c="carbon.7">{t('sources.add.selectType')}</Text>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '8px' }}>
            {ADDABLE_SOURCE_TYPES.map(type => {
              const meta = SOURCE_TYPE_META[type];
              const isActive = selectedType === type;
              const isDisabled = type === 'git_repo';
              return (
                <Box
                  key={type}
                  p="sm"
                  onClick={() => {
                    if (isDisabled) return;
                    setSelectedType(type);
                    setName('');
                    setIssueIdError('');
                  }}
                  style={{
                    borderRadius: '8px',
                    border: isActive ? `2px solid ${meta.color}` : '1px solid #e5e7eb',
                    backgroundColor: isDisabled ? '#f3f4f6' : isActive ? `${meta.color}10` : '#fff',
                    cursor: isDisabled ? 'not-allowed' : 'pointer',
                    opacity: isDisabled ? 0.6 : 1,
                    transition: 'all 0.15s ease',
                  }}
                >
                  <Stack gap={6}>
                    <span style={{ fontSize: '22px' }}>{meta.icon}</span>
                    <div>
                      <Text size="sm" fw={600}>{meta.label}</Text>
                      <Text size="xs" c={isDisabled ? 'orange' : 'carbon.5'}>{isDisabled ? t('sources.add.comingSoon') : meta.description}</Text>
                    </div>
                  </Stack>
                </Box>
              );
            })}
          </div>

          {/* Name input */}
          {selectedType && (
            <>
              <Stack gap={4}>
                <Text size="sm" fw={500} c="carbon.7">
                  {isPreparedSourceType(selectedType) ? t('sources.add.alertId') : t('sources.add.name')}
                </Text>
                <input
                  type="text"
                  value={name}
                  onChange={(e) => {
                    const val = isPreparedSourceType(selectedType) ? e.target.value.toUpperCase() : e.target.value;
                    setName(val);
                    const regex = idRegexFor(selectedType);
                    if (regex) {
                      setIssueIdError(
                        val && !regex.test(val.trim())
                          ? t(selectedType === 'alertstore_alert' ? 'sources.add.errorFormatAlertstore' : 'sources.add.errorFormat')
                          : '',
                      );
                    }
                  }}
                  placeholder={
                    selectedType === 'jira_issue'
                      ? t('sources.add.placeholderJira')
                      : selectedType === 'alertstore_alert'
                      ? t('sources.add.placeholderAlertstore')
                      : selectedType === 'git_repo'
                      ? t('sources.add.placeholderGit')
                      : t('sources.add.placeholderName')
                  }
                  style={{
                    padding: '8px 12px',
                    border: `1px solid ${issueIdError ? '#f87171' : '#d1d5db'}`,
                    borderRadius: '6px',
                    fontSize: '14px',
                    outline: 'none',
                    width: '100%',
                    boxSizing: 'border-box',
                    fontFamily: isPreparedSourceType(selectedType) ? 'monospace' : undefined,
                    textTransform: isPreparedSourceType(selectedType) ? 'uppercase' : undefined,
                  }}
                />
                {issueIdError && (
                  <Text size="xs" c="red">{issueIdError}</Text>
                )}
              </Stack>

              <Stack gap={4}>
                <Text size="sm" fw={500} c="carbon.5">{t('sources.add.descriptionLabel')}</Text>
                <input
                  type="text"
                  value={description}
                  onChange={(e) => setDescription(e.target.value)}
                  placeholder={t('sources.add.descriptionPlaceholder')}
                  style={{
                    padding: '8px 12px',
                    border: '1px solid #d1d5db',
                    borderRadius: '6px',
                    fontSize: '14px',
                    outline: 'none',
                    width: '100%',
                    boxSizing: 'border-box',
                  }}
                />
              </Stack>

              <Group justify="flex-end" mt="sm">
                <Button
                  variant="outline"
                  color="gray"
                  size="sm"
                  onClick={handleClose}
                >
                  {t('sources.add.cancel')}
                </Button>
                <Button
                  size="sm"
                  disabled={!name.trim() || !!issueIdError || (!!idRegexFor(selectedType) && !idRegexFor(selectedType)!.test(name.trim())) || isSubmitting}
                  loading={isSubmitting}
                  onClick={handleAdd}
                >
                  {t('sources.add.add')}
                </Button>
              </Group>
            </>
          )}
        </Stack>
      </Box>
    </>
  );
}
