import { Button, Tabs, Typography } from 'antd';
import type { ErrorLogItem } from '../errorLogApi';
import { PreviewerUI } from '../../../components/previewer';
import type { ErrorReferenceCandidate, ErrorReferenceResource, ErrorReferenceSummary } from './errorLogUtils.types';

const { Text } = Typography;
const URL_PATTERN = /https?:\/\/[^\s)]+/gi;
const IMAGE_URL_PATTERN = /\.(?:png|jpe?g|gif|webp|svg|bmp)(?:[?#].*)?$/i;
const PREVIEW_KEY_PATTERN = /(preview|deploy|vercel|netlify|storybook|localhost|127\.0\.0\.1|pageUrl)/i;

export function formatErrorLogTime(value: string) {
  const parsed = new Date(value);

  if (Number.isNaN(parsed.getTime())) {
    return value;
  }

  return new Intl.DateTimeFormat('ko-KR', {
    dateStyle: 'short',
    timeStyle: 'medium',
  }).format(parsed);
}

export function getErrorSourceColor(source: string) {
  if (source === 'automation') {
    return 'volcano';
  }

  if (source === 'server') {
    return 'blue';
  }

  return 'gold';
}

export function getErrorSourceLabel(item: ErrorLogItem) {
  return item.sourceLabel || item.source;
}

export function formatErrorSummary(item: ErrorLogItem) {
  const label = item.errorName || item.errorType;
  const planLabel =
    item.relatedPlanId || item.relatedWorkId
      ? [item.relatedPlanId ? `#${item.relatedPlanId}` : null, item.relatedWorkId].filter(Boolean).join(' ')
      : null;

  return planLabel ? `${label} · ${planLabel}` : label;
}

export function formatCompactPath(value: string | null | undefined) {
  if (!value) {
    return '';
  }

  if (value.length <= 42) {
    return value;
  }

  return `...${value.slice(-39)}`;
}

export function stringifyErrorDetail(value: unknown) {
  if (value == null) {
    return '';
  }

  if (typeof value === 'string') {
    return value;
  }

  try {
    return JSON.stringify(value, null, 2);
  } catch {
    return String(value);
  }
}

export function buildErrorMetaRows(item: ErrorLogItem) {
  return [
    { label: '발생 시각', value: formatErrorLogTime(item.createdAt) },
    { label: '출처', value: getErrorSourceLabel(item) },
    { label: '유형', value: item.errorType },
    item.errorName ? { label: '이름', value: item.errorName } : null,
    item.statusCode ? { label: '상태 코드', value: String(item.statusCode) } : null,
    item.requestMethod || item.requestPath
      ? { label: '요청', value: [item.requestMethod, item.requestPath].filter(Boolean).join(' ') }
      : null,
    item.relatedPlanId ? { label: '작업', value: `#${item.relatedPlanId}` } : null,
    item.relatedWorkId ? { label: '작업 ID', value: item.relatedWorkId } : null,
  ].filter(Boolean) as Array<{ label: string; value: string }>;
}

function collectReferenceCandidates(value: unknown, path = 'context'): ErrorReferenceCandidate[] {
  if (value == null) {
    return [];
  }

  if (typeof value === 'string') {
    const trimmed = value.trim();
    return trimmed ? [{ path, value: trimmed }] : [];
  }

  if (typeof value === 'number' || typeof value === 'boolean') {
    return [{ path, value: String(value) }];
  }

  if (Array.isArray(value)) {
    return value.flatMap((entry, index) => collectReferenceCandidates(entry, `${path}[${index}]`));
  }

  if (typeof value === 'object') {
    return Object.entries(value).flatMap(([key, entry]) => collectReferenceCandidates(entry, `${path}.${key}`));
  }

  return [];
}

function formatReferenceLabel(path: string, kind: ErrorReferenceResource['kind'], index: number) {
  const pathLabel = path.split('.').pop()?.replace(/\[\d+\]/g, '') || '참조';

  if (kind === 'preview') {
    return `${pathLabel} preview ${index}`;
  }

  if (kind === 'image') {
    return `${pathLabel} image ${index}`;
  }

  return `${pathLabel} link ${index}`;
}

function buildReferenceSourcePreview(sourceText: string, url: string) {
  const normalized = sourceText.replace(/\s+/g, ' ').trim();

  if (!normalized) {
    return url;
  }

  const matchIndex = normalized.indexOf(url);

  if (matchIndex < 0) {
    return normalized.length > 220 ? `${normalized.slice(0, 220)}...` : normalized;
  }

  const start = Math.max(0, matchIndex - 96);
  const end = Math.min(normalized.length, matchIndex + url.length + 96);
  const prefix = start > 0 ? '... ' : '';
  const suffix = end < normalized.length ? ' ...' : '';

  return `${prefix}${normalized.slice(start, end)}${suffix}`;
}

function buildErrorReferenceResources(item: ErrorLogItem): ErrorReferenceResource[] {
  const sourceTexts: ErrorReferenceCandidate[] = [
    { path: 'errorMessage', value: item.errorMessage },
    item.detail ? { path: 'detail', value: item.detail } : null,
    item.stackTrace ? { path: 'stackTrace', value: item.stackTrace } : null,
    item.requestPath ? { path: 'requestPath', value: item.requestPath } : null,
    ...(item.context ? collectReferenceCandidates(item.context) : []),
  ].filter(Boolean) as ErrorReferenceCandidate[];

  const seen = new Set<string>();
  const resources: ErrorReferenceResource[] = [];

  sourceTexts.forEach(({ path, value }) => {
    const matches = value.match(URL_PATTERN) ?? [];

    matches.forEach((rawUrl) => {
      const url = rawUrl.replace(/[),.;]+$/g, '');

      if (!url || seen.has(url)) {
        return;
      }

      const kind = IMAGE_URL_PATTERN.test(url)
        ? 'image'
        : PREVIEW_KEY_PATTERN.test(path) || PREVIEW_KEY_PATTERN.test(url)
          ? 'preview'
          : 'link';

      seen.add(url);
      resources.push({
        url,
        label: formatReferenceLabel(path, kind, resources.length + 1),
        kind,
        sourcePath: path,
        sourcePreview: buildReferenceSourcePreview(value, url),
      });
    });

    if (!matches.length && /^https?:\/\//i.test(value.trim()) && !seen.has(value.trim())) {
      const url = value.trim();
      const kind = IMAGE_URL_PATTERN.test(url)
        ? 'image'
        : PREVIEW_KEY_PATTERN.test(path) || PREVIEW_KEY_PATTERN.test(url)
          ? 'preview'
          : 'link';

      seen.add(url);
      resources.push({
        url,
        label: formatReferenceLabel(path, kind, resources.length + 1),
        kind,
        sourcePath: path,
        sourcePreview: buildReferenceSourcePreview(value, url),
      });
    }
  });

  return resources;
}

export function buildErrorReferenceSummary(item: ErrorLogItem): ErrorReferenceSummary {
  const resources = buildErrorReferenceResources(item);
  const previewCount = resources.filter((resource) => resource.kind === 'preview').length;
  const imageCount = resources.filter((resource) => resource.kind === 'image').length;
  const linkCount = resources.filter((resource) => resource.kind === 'link').length;
  return { resources, previewCount, imageCount, linkCount };
}

export function getDefaultErrorResource(resources: ErrorReferenceResource[]) {
  return resources.find((resource) => resource.kind === 'preview')
    ?? resources.find((resource) => resource.kind === 'image')
    ?? resources[0]
    ?? null;
}

export function getErrorResourceKindLabel(kind: ErrorReferenceResource['kind']) {
  if (kind === 'preview') {
    return 'preview';
  }

  if (kind === 'image') {
    return 'image';
  }

  return 'link';
}

export function buildErrorListPreviewLine(item: ErrorLogItem, summary: ErrorReferenceSummary) {
  const compactMessage = item.errorMessage.replace(/\s+/g, ' ').trim();
  const focusLabel = item.requestPath || compactMessage;
  const referenceTotal = summary.resources.length;

  return [formatCompactPath(focusLabel), referenceTotal ? `참조 ${referenceTotal}` : null].filter(Boolean).join(' · ');
}

function buildErrorOverviewText(item: ErrorLogItem) {
  return [
    `에러: ${item.errorMessage}`,
    ...buildErrorMetaRows(item).map((row) => `${row.label}: ${row.value}`),
  ].join('\n');
}

export function buildErrorDetailTabs(item: ErrorLogItem) {
  const resources = buildErrorReferenceSummary(item).resources;
  const imageResources = resources.filter((resource) => resource.kind === 'image');
  const previewResources = resources.filter((resource) => resource.kind === 'preview');
  const linkResources = resources.filter((resource) => resource.kind === 'link');
  const tabs = [
    {
      key: 'overview',
      label: '개요',
      children: (
        <div className="app-chat-panel__error-tab-stack">
          {previewResources.length ? (
            <div className="app-chat-panel__error-reference-list">
              {previewResources.map((resource) => (
                <Button
                  key={resource.url}
                  type="link"
                  href={resource.url}
                  target="_blank"
                  rel="noreferrer"
                  style={{ paddingInline: 0, justifyContent: 'flex-start' }}
                >
                  {resource.label}: {resource.url}
                </Button>
              ))}
            </div>
          ) : null}
          <PreviewerUI
            type="text"
            title={formatErrorSummary(item)}
            description="선택한 로그의 핵심 정보"
            value={buildErrorOverviewText(item)}
            height="auto"
          />
          {linkResources.length || imageResources.length ? (
            <div className="app-chat-panel__error-reference-list">
              {linkResources.map((resource) => (
                <Button
                  key={resource.url}
                  type="link"
                  href={resource.url}
                  target="_blank"
                  rel="noreferrer"
                  style={{ paddingInline: 0, justifyContent: 'flex-start' }}
                >
                  {resource.label}: {resource.url}
                </Button>
              ))}
            </div>
          ) : null}
        </div>
      ),
    },
  ];

  if (item.detail) {
    tabs.push({
      key: 'detail',
      label: '상세',
      children: (
        <PreviewerUI
          type="code"
          title="Error Detail"
          description="상세 에러 데이터"
          value={stringifyErrorDetail(item.detail)}
          language="json"
          height="auto"
        />
      ),
    });
  }

  if (item.context) {
    tabs.push({
      key: 'context',
      label: '컨텍스트',
      children: (
        <PreviewerUI
          type="json"
          title="Error Context"
          description="추가 컨텍스트 데이터"
          value={item.context}
          height="auto"
        />
      ),
    });
  }

  if (item.stackTrace) {
    tabs.push({
      key: 'stack',
      label: '스택',
      children: (
        <PreviewerUI
          type="code"
          title="Stack Trace"
          description="에러 스택"
          value={item.stackTrace}
          language="bash"
          height="auto"
        />
      ),
    });
  }

  if (imageResources.length || linkResources.length) {
    tabs.push({
      key: 'references',
      label: '참조',
      children: (
        <div className="app-chat-panel__error-tab-stack">
          {imageResources.length ? (
            <div className="app-chat-panel__error-image-grid">
              {imageResources.map((resource) => (
                <PreviewerUI
                  key={resource.url}
                  type="image"
                  title={resource.label}
                  description={`${resource.sourcePath} · ${resource.url}`}
                  value={resource.url}
                  imageAlt={resource.label}
                  height={320}
                />
              ))}
            </div>
          ) : null}
          {previewResources.length ? (
            <div className="app-chat-panel__error-reference-list">
              {previewResources.map((resource) => (
                <Button
                  key={resource.url}
                  type="link"
                  href={resource.url}
                  target="_blank"
                  rel="noreferrer"
                  style={{ paddingInline: 0, justifyContent: 'flex-start' }}
                >
                  {resource.label}: {resource.url}
                </Button>
              ))}
            </div>
          ) : null}
          {linkResources.length ? (
            <div className="app-chat-panel__error-reference-list">
              {linkResources.map((resource) => (
                <Button
                  key={resource.url}
                  type="link"
                  href={resource.url}
                  target="_blank"
                  rel="noreferrer"
                  style={{ paddingInline: 0, justifyContent: 'flex-start' }}
                >
                  {resource.label}: {resource.url}
                </Button>
              ))}
            </div>
          ) : null}
        </div>
      ),
    });
  }

  if (previewResources.length) {
    tabs.push({
      key: 'preview',
      label: '미리보기',
      children: (
        <div className="app-chat-panel__error-preview-grid">
          {previewResources.map((resource) => (
            <section key={resource.url} className="app-chat-panel__error-preview-card">
              <div className="app-chat-panel__error-preview-card-top">
                <div>
                  <Text strong>{resource.label}</Text>
                  <br />
                  <Text type="secondary">{resource.sourcePath}</Text>
                </div>
                <Button size="small" type="primary" href={resource.url} target="_blank" rel="noreferrer">
                  열기
                </Button>
              </div>
              <div className="app-chat-panel__error-preview-frame-wrap">
                <iframe
                  className="app-chat-panel__error-preview-frame"
                  src={resource.url}
                  title={resource.label}
                  loading="lazy"
                  referrerPolicy="no-referrer"
                />
              </div>
              <Text type="secondary" className="app-chat-panel__error-preview-url">
                {resource.url}
              </Text>
            </section>
          ))}
        </div>
      ),
    });
  }

  return tabs;
}

export function buildErrorSourceSummary(errorLogs: ErrorLogItem[]) {
  return errorLogs.reduce<Record<string, number>>((acc, item) => {
    const key = getErrorSourceLabel(item);
    acc[key] = (acc[key] ?? 0) + 1;
    return acc;
  }, {});
}

export function renderErrorTabs(item: ErrorLogItem) {
  return <Tabs className="app-chat-panel__error-tabs" items={buildErrorDetailTabs(item)} />;
}
