'use client';

import React, { useState, useRef } from 'react';
import * as Prism from 'prismjs';
import 'prismjs/components/prism-python';
import 'prismjs/components/prism-typescript';
import 'prismjs/components/prism-javascript';
import 'prismjs/components/prism-jsx';
import 'prismjs/components/prism-tsx';
import 'prismjs/components/prism-docker';
import 'prismjs/components/prism-yaml';
import 'prismjs/components/prism-json';
import 'prismjs/components/prism-markup';
import 'prismjs/components/prism-css';
import 'prismjs/components/prism-sql';
import 'prismjs/components/prism-bash';
import 'prismjs/components/prism-markdown';

interface FileExampleProps {
  filename: string;
  content: string;
  language: string;
  description?: string;
  tags?: string[];
  id: string;
}

const prismLanguageMap: Record<string, string> = {
  py: 'python',
  ts: 'typescript',
  tsx: 'tsx',
  js: 'javascript',
  jsx: 'jsx',
  dockerfile: 'docker',
  docker: 'docker',
  yml: 'yaml',
  yaml: 'yaml',
  json: 'json',
  html: 'markup',
  css: 'css',
  sql: 'sql',
  sh: 'bash',
  bash: 'bash',
  md: 'markdown',
};

export const FileExample: React.FC<FileExampleProps> = ({
  filename,
  content,
  language,
  id
}) => {
  const [isExpanded, setIsExpanded] = useState(false);
  const [isCopied, setIsCopied] = useState(false);
  const contentRef = useRef<HTMLDivElement>(null);

  const safeId = String(id).replace(/[^a-zA-Z0-9_-]/g, '');
  const headerId = `file-example-header-${safeId}`;
  const contentId = `file-example-content-${safeId}`;

  const fileExtension = filename.split('.').pop() || language;
  const prismLanguage = prismLanguageMap[fileExtension] || 'markup';

  const highlightedCode = Prism.highlight(
    content,
    Prism.languages[prismLanguage] || Prism.languages.markup,
    prismLanguage,
  );

  const toggleExpand = () => {
    setIsExpanded(!isExpanded);
    if (!isExpanded) {
      setTimeout(() => {
        contentRef.current?.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
      }, 120);
    }
  };

  const handleCopy = async (e: React.MouseEvent) => {
    e.stopPropagation();
    try {
      await navigator.clipboard.writeText(content);
      setIsCopied(true);
      setTimeout(() => setIsCopied(false), 900);
    } catch (err) {
      console.error('Failed to copy:', err);
    }
  };

  const handleDownload = (e: React.MouseEvent) => {
    e.stopPropagation();
    const blob = new Blob([content], { type: 'text/plain' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = filename;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  };

  return (
    <div
      className="file-example w-full bg-white border border-slate-200 rounded-2xl overflow-hidden transition-all duration-300"
      data-file-example
      data-expanded={isExpanded}
    >
      <div
        className="px-4 py-3 flex items-center justify-between gap-3 cursor-pointer select-none bg-white hover:bg-slate-50 transition-colors"
        onClick={toggleExpand}
        role="button"
        tabIndex={0}
        onKeyDown={(e) => {
          if (e.key === 'Enter' || e.key === ' ') {
            e.preventDefault();
            toggleExpand();
          }
        }}
        aria-expanded={isExpanded}
        aria-controls={contentId}
        id={headerId}
      >
        <div className="flex items-center gap-2 min-w-0">
          <svg
            className={`w-3 h-3 text-slate-400 flex-shrink-0 transition-transform ${isExpanded ? 'rotate-0' : '-rotate-90'}`}
            fill="none"
            stroke="currentColor"
            viewBox="0 0 24 24"
            aria-hidden="true"
          >
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M19 9l-7 7-7-7" />
          </svg>

          <span className="text-xs font-mono text-slate-900 truncate" title={filename}>{filename}</span>
        </div>

        <div className="flex items-center gap-1 flex-shrink-0">
          <button
            type="button"
            className={`copy-btn h-7 w-7 inline-flex items-center justify-center rounded-md border border-transparent hover:border-slate-200 hover:bg-white transition-colors ${isCopied ? 'copied' : ''}`}
            onClick={handleCopy}
            title="Copy to clipboard"
            aria-label={`Copy ${filename} to clipboard`}
            data-copied={isCopied}
          >
            <svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth="2"
                d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"
              />
            </svg>
          </button>

          <button
            type="button"
            className="download-btn h-7 w-7 inline-flex items-center justify-center rounded-md border border-transparent hover:border-slate-200 hover:bg-white transition-colors"
            onClick={handleDownload}
            title="Download file"
            aria-label={`Download ${filename}`}
          >
            <svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth="2"
                d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"
              />
            </svg>
          </button>
        </div>
      </div>

      <div
        ref={contentRef}
        className={`file-example__content overflow-hidden transition-[max-height,opacity] duration-200 ease-out bg-white ${isExpanded ? 'max-h-[22rem] opacity-100' : 'max-h-0 opacity-0'}`}
        id={contentId}
        role="region"
        aria-labelledby={headerId}
      >
        <pre
          className="m-0 p-6 overflow-x-auto overflow-y-auto text-[13px] leading-[1.65] font-mono text-slate-800 hide-scrollbar border-t border-slate-200"
          style={{ fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace", maxHeight: "22rem" }}
        >
          <code className={`language-${prismLanguage}`} dangerouslySetInnerHTML={{ __html: highlightedCode }}></code>
        </pre>
      </div>
    </div>
  );
};
