'use client';

import { useEffect, useState } from 'react';
import { Box, Button, Group, Stack, Text, Title } from '@tidbcloud/uikit';
import { fetchWithAuth } from '@/lib/auth';
import { useTranslation } from '@/lib/i18n';

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

export function CodeDiagnosisModal({
  opened,
  workspaceId,
  onClose,
  onPrepare,
}: {
  opened: boolean;
  workspaceId?: string;
  onClose: () => void;
  onPrepare: (request: { repo: string; label: string; commitSha: string; replaceExisting?: boolean }) => Promise<string | null>;
}) {
  const { t } = useTranslation();
  const [inputMode, setInputMode] = useState<'tag' | 'sha'>('tag');
  const [commitRef, setCommitRef] = useState('');
  const [repositories, setRepositories] = useState<{ repo: string; label: string }[]>([]);
  const [releaseTags, setReleaseTags] = useState<string[]>([]);
  const [isReleaseTagsLoading, setIsReleaseTagsLoading] = useState(false);
  const [releaseTagsError, setReleaseTagsError] = useState('');
  const [repo, setRepo] = useState('pingcap/tidb');
  const [error, setError] = useState('');
  const [isSubmitting, setIsSubmitting] = useState(false);

  useEffect(() => {
    if (!opened) return;
    void fetchWithAuth(`${API_BASE_URL}/api/code-context/repositories`)
      .then(response => response.ok ? response.json() : Promise.reject())
      .then((body: { repositories?: { repo: string; label: string }[] }) => {
        if (body.repositories?.length) {
          setRepositories(body.repositories);
          setRepo(body.repositories[0].repo);
        }
      })
      .catch(() => setRepositories([
        { repo: 'pingcap/tidb', label: 'TiDB' },
        { repo: 'pingcap/tikv', label: 'TiKV' },
      ]));
  }, [opened]);

  useEffect(() => {
    if (!opened || !repo) return;
    let active = true;
    setIsReleaseTagsLoading(true);
    setReleaseTagsError('');
    void fetchWithAuth(`${API_BASE_URL}/api/code-context/release-tags?repo=${encodeURIComponent(repo)}`)
      .then(response => response.ok ? response.json() : Promise.reject())
      .then((body: { release_tags?: string[] }) => {
        if (!active) return;
        const tags = body.release_tags ?? [];
        setReleaseTags(tags);
        setCommitRef(current => tags.includes(current) ? current : '');
      })
      .catch(() => {
        if (!active) return;
        setReleaseTags([]);
        setReleaseTagsError(t('chat.codeDiagnosis.releaseTagsUnavailable'));
      })
      .finally(() => {
        if (active) setIsReleaseTagsLoading(false);
      });
    return () => { active = false; };
  }, [opened, repo, t]);

  if (!opened) return null;

  const close = () => {
    if (isSubmitting) return;
    setCommitRef('');
    setError('');
    onClose();
  };

  const submit = async () => {
    const normalized = inputMode === 'sha' ? commitRef.trim().toLowerCase() : commitRef.trim();
    const valid = inputMode === 'sha'
      ? /^[0-9a-f]{7,40}$/.test(normalized)
      : /^v[0-9]+\.[0-9]+\.[0-9]+$/.test(normalized);
    if (!valid) {
      setError(t(inputMode === 'sha' ? 'chat.codeDiagnosis.invalidSha' : 'chat.codeDiagnosis.invalidVersionTag'));
      return;
    }
    if (!workspaceId) {
      setError(t('chat.codeDiagnosis.workspaceRequired'));
      return;
    }
    setError('');
    const repository = repositories.find(item => item.repo === repo);
    setIsSubmitting(true);
    try {
      const preparationError = await onPrepare({ repo, label: repository?.label ?? repo, commitSha: normalized });
      if (!preparationError) {
        setCommitRef('');
        onClose();
      } else {
        setError(preparationError);
      }
    } finally {
      setIsSubmitting(false);
    }
  };

  return (
    <>
      <div onClick={close} style={{ position: 'fixed', inset: 0, backgroundColor: 'rgba(0, 0, 0, 0.3)', zIndex: 1000 }} />
      <Box p="lg" style={{ position: 'fixed', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', width: 440, maxWidth: '90vw', backgroundColor: '#fff', borderRadius: 12, boxShadow: '0 20px 60px rgba(0,0,0,0.15)', zIndex: 1001 }}>
        <Stack gap="md">
          <Group justify="space-between"><Title order={5}>{t('chat.codeDiagnosis.title')}</Title><button type="button" onClick={close} aria-label={t('common.close')} style={{ background: 'none', border: 0, cursor: 'pointer', fontSize: 18 }}>×</button></Group>
          <Text size="sm" c="dimmed">{t('chat.codeDiagnosis.description')}</Text>
          <label style={{ display: 'grid', gap: 6, fontSize: 13, fontWeight: 600 }}>{t('chat.codeDiagnosis.repoLabel')}<select value={repo} onChange={event => setRepo(event.target.value)} style={{ height: 36, border: '1px solid #d1d5db', borderRadius: 6, padding: '0 8px', background: '#f9fafb' }}>{(repositories.length ? repositories : [{ repo: 'pingcap/tidb', label: 'TiDB' }, { repo: 'pingcap/tikv', label: 'TiKV' }]).map(item => <option key={item.repo} value={item.repo}>{item.repo}</option>)}</select></label>
          <Stack gap="xs">
            <Text size="sm" fw={600}>{t('chat.codeDiagnosis.versionInputLabel')}</Text>
            <Group gap="xs">
              <Button size="xs" variant={inputMode === 'tag' ? 'filled' : 'default'} disabled={isSubmitting} onClick={() => { setInputMode('tag'); setCommitRef(''); setError(''); }}>{t('chat.codeDiagnosis.versionTagMode')}</Button>
              <Button size="xs" variant={inputMode === 'sha' ? 'filled' : 'default'} disabled={isSubmitting} onClick={() => { setInputMode('sha'); setCommitRef(''); setError(''); }}>{t('chat.codeDiagnosis.shaMode')}</Button>
            </Group>
            <label style={{ display: 'grid', gap: 6, fontSize: 13, fontWeight: 600 }}>
              {t(inputMode === 'tag' ? 'chat.codeDiagnosis.versionTagLabel' : 'chat.codeDiagnosis.commitLabel')}
              {inputMode === 'tag' ? (
                <select value={commitRef} disabled={isSubmitting || isReleaseTagsLoading || !!releaseTagsError} onChange={(event) => setCommitRef(event.target.value)} style={{ height: 36, border: '1px solid #d1d5db', borderRadius: 6, padding: '0 8px', background: '#f9fafb', fontFamily: 'monospace' }}>
                  <option value="">{isReleaseTagsLoading ? t('common.loading') : t('chat.codeDiagnosis.versionTagPlaceholder')}</option>
                  {releaseTags.map(tag => <option key={tag} value={tag}>{tag}</option>)}
                </select>
              ) : (
                <input value={commitRef} disabled={isSubmitting} onChange={(event) => setCommitRef(event.target.value)} placeholder={t('chat.codeDiagnosis.commitPlaceholder')} autoFocus style={{ height: 36, border: '1px solid #d1d5db', borderRadius: 6, padding: '0 8px', fontFamily: 'monospace' }} />
              )}
            </label>
          </Stack>
          {releaseTagsError && inputMode === 'tag' && <Text size="sm" c="red.6">{releaseTagsError}</Text>}
          {error && <Text size="sm" c="red.6">{error}</Text>}
          <Group justify="flex-end"><Button variant="default" disabled={isSubmitting} onClick={close}>{t('common.cancel')}</Button><Button loading={isSubmitting} disabled={isSubmitting} onClick={submit}>{t('chat.codeDiagnosis.prepare')}</Button></Group>
        </Stack>
      </Box>
    </>
  );
}
