import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import {
  BarChart3,
  Building2,
  Calendar,
  CalendarDays,
  Download,
  FileText,
  Loader2,
  Plus,
  Printer,
  Save,
  ShieldCheck,
  Trash2,
  Users,
} from 'lucide-react';
import clsx from 'clsx';
import { useToast } from '@/components/ui/Toast';
import {
  useReportTemplates,
  useCreateReportTemplate,
  useUpdateReportTemplate,
  useDeleteReportTemplate,
  useReportPresets,
  useGenerateReport,
  useGeneratePresetReport,
  downloadBlob,
  type ReportTemplate,
  type OutputFormat,
  type PresetReportInfo,
} from '@/api/reports';

// ─── Icon mapping for presets ──────────────────────────────────────────────

const PRESET_ICONS: Record<string, React.ReactNode> = {
  Users: <Users className="w-5 h-5" />,
  Calendar: <Calendar className="w-5 h-5" />,
  CalendarDays: <CalendarDays className="w-5 h-5" />,
  Building2: <Building2 className="w-5 h-5" />,
  ShieldCheck: <ShieldCheck className="w-5 h-5" />,
};

// ─── Download history entry ────────────────────────────────────────────────

interface DownloadEntry {
  id: string;
  name: string;
  format: string;
  timestamp: string;
}

// ─── Component ─────────────────────────────────────────────────────────────

export function ReportsPage() {
  const { t } = useTranslation();
  const toast = useToast();

  // Data hooks
  const { data: templates = [], isLoading: templatesLoading } = useReportTemplates();
  const { data: presets = [] } = useReportPresets();

  // Mutations
  const createTemplate = useCreateReportTemplate();
  const updateTemplate = useUpdateReportTemplate();
  const deleteTemplate = useDeleteReportTemplate();
  const generateReport = useGenerateReport();
  const generatePreset = useGeneratePresetReport();

  // Local state
  const [selectedTemplate, setSelectedTemplate] = useState<ReportTemplate | null>(null);
  const [editorContent, setEditorContent] = useState('');
  const [editorName, setEditorName] = useState('');
  const [editorFormat, setEditorFormat] = useState<OutputFormat>('pdf');
  const [isNewTemplate, setIsNewTemplate] = useState(false);
  const [jsonData, setJsonData] = useState('{}');
  const [downloadHistory, setDownloadHistory] = useState<DownloadEntry[]>([]);
  const [activePresetFormat, setActivePresetFormat] = useState<OutputFormat>('pdf');

  // Select a template for editing
  const selectTemplate = (tpl: ReportTemplate) => {
    setSelectedTemplate(tpl);
    setEditorContent(tpl.content);
    setEditorName(tpl.name);
    setEditorFormat(tpl.output_format);
    setIsNewTemplate(false);
  };

  // Start creating a new template
  const startNewTemplate = () => {
    setSelectedTemplate(null);
    setEditorContent('<html><body>\n  <h1>{{ title }}</h1>\n  <p>{{ message }}</p>\n</body></html>');
    setEditorName('');
    setEditorFormat('pdf');
    setIsNewTemplate(true);
  };

  // Save template (create or update)
  const handleSaveTemplate = async () => {
    if (!editorName.trim()) {
      toast.error(t('reports.errorNameRequired', 'Name is required'));
      return;
    }
    if (!editorContent.trim()) {
      toast.error(t('reports.errorContentRequired', 'Template content is required'));
      return;
    }

    try {
      if (isNewTemplate) {
        await createTemplate.mutateAsync({
          name: editorName,
          content: editorContent,
          output_format: editorFormat,
          template_type: 'jinja2',
        });
        toast.success(t('reports.templateCreated', 'Template created successfully'));
      } else if (selectedTemplate) {
        await updateTemplate.mutateAsync({
          id: selectedTemplate.id,
          name: editorName,
          content: editorContent,
          output_format: editorFormat,
        });
        toast.success(t('reports.templateUpdated', 'Template updated successfully'));
      }
    } catch (err: any) {
      toast.error(err?.message || t('reports.saveFailed', 'Failed to save template'));
    }
  };

  // Delete template
  const handleDeleteTemplate = async (tpl: ReportTemplate) => {
    if (!confirm(t('reports.confirmDelete', 'Delete this template?'))) return;
    try {
      await deleteTemplate.mutateAsync(tpl.id);
      if (selectedTemplate?.id === tpl.id) {
        setSelectedTemplate(null);
        setEditorContent('');
      }
      toast.success(t('reports.templateDeleted', 'Template deleted'));
    } catch (err: any) {
      toast.error(err?.message || t('reports.deleteFailed', 'Failed to delete template'));
    }
  };

  // Generate report from selected template
  const handleGenerate = async () => {
    if (!selectedTemplate) return;
    let parsedData: Record<string, unknown>;
    try {
      parsedData = JSON.parse(jsonData);
    } catch {
      toast.error(t('reports.invalidJson', 'Invalid JSON data'));
      return;
    }

    try {
      const response = await generateReport.mutateAsync({
        template_id: selectedTemplate.id,
        data: parsedData,
        output_format: editorFormat,
      });
      const filename = `report_${selectedTemplate.name}.${editorFormat === 'excel' ? 'xlsx' : editorFormat}`;
      downloadBlob(response.data as Blob, filename);
      setDownloadHistory((prev) => [
        { id: Date.now().toString(), name: selectedTemplate.name, format: editorFormat, timestamp: new Date().toLocaleString() },
        ...prev,
      ]);
      toast.success(t('reports.generated', 'Report generated successfully'));
    } catch (err: any) {
      toast.error(err?.message || t('reports.generateFailed', 'Failed to generate report'));
    }
  };

  // Generate preset report
  const handleGeneratePreset = async (preset: PresetReportInfo) => {
    let parsedParams: Record<string, unknown> = {};
    try {
      parsedParams = JSON.parse(jsonData);
    } catch {
      // Use empty params if JSON is invalid
      parsedParams = {};
    }

    try {
      const response = await generatePreset.mutateAsync({
        preset: preset.key,
        output_format: activePresetFormat,
        parameters: parsedParams,
      });
      const ext = activePresetFormat === 'excel' ? 'xlsx' : activePresetFormat === 'print' ? 'pdf' : activePresetFormat;
      const filename = `${preset.key}_report.${ext}`;
      downloadBlob(response.data as Blob, filename);
      setDownloadHistory((prev) => [
        { id: Date.now().toString(), name: preset.name, format: activePresetFormat, timestamp: new Date().toLocaleString() },
        ...prev,
      ]);
      toast.success(t('reports.generated', 'Report generated successfully'));
    } catch (err: any) {
      toast.error(err?.message || t('reports.generateFailed', 'Failed to generate report'));
    }
  };

  const isGenerating = generateReport.isPending || generatePreset.isPending;
  const isSaving = createTemplate.isPending || updateTemplate.isPending;

  return (
    <div className="flex flex-col h-full gap-4 p-4" data-testid="reports-page">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-3">
          <BarChart3 className="w-6 h-6 text-primary-600" />
          <h1 className="text-2xl font-bold text-secondary-900">{t('reports.title', 'Reports')}</h1>
        </div>
      </div>

      {/* Preset Quick Actions */}
      <div className="bg-white rounded-lg shadow-sm border border-secondary-200 p-4" data-testid="preset-quick-actions">
        <h2 className="text-sm font-semibold text-secondary-700 mb-3">{t('reports.presetReports', 'Preset Reports')}</h2>
        <div className="flex flex-wrap gap-3">
          {presets.map((preset) => (
            <div
              key={preset.key}
              className="flex flex-col gap-2 p-3 border border-secondary-200 rounded-lg hover:border-primary-400 transition-colors min-w-[200px]"
            >
              <div className="flex items-center gap-2">
                {PRESET_ICONS[preset.icon] || <FileText className="w-5 h-5" />}
                <span className="font-medium text-sm text-secondary-800">{preset.name}</span>
              </div>
              <p className="text-xs text-secondary-500">{preset.description}</p>
              <div className="flex gap-1 mt-1">
                {preset.output_formats.map((fmt) => (
                  <button
                    key={fmt}
                    onClick={() => {
                      setActivePresetFormat(fmt);
                      handleGeneratePreset(preset);
                    }}
                    disabled={isGenerating}
                    className={clsx(
                      'px-2 py-1 text-xs rounded font-medium transition-colors',
                      'disabled:opacity-50 disabled:cursor-not-allowed',
                      fmt === 'pdf' && 'bg-red-100 text-red-700 hover:bg-red-200',
                      fmt === 'print' && 'bg-blue-100 text-blue-700 hover:bg-blue-200',
                      fmt === 'csv' && 'bg-green-100 text-green-700 hover:bg-green-200',
                      fmt === 'excel' && 'bg-emerald-100 text-emerald-700 hover:bg-emerald-200',
                    )}
                    data-testid={`preset-${preset.key}-${fmt}`}
                  >
                    {fmt === 'pdf' && <Download className="w-3 h-3 inline mr-1" />}
                    {fmt === 'print' && <Printer className="w-3 h-3 inline mr-1" />}
                    {fmt.toUpperCase()}
                  </button>
                ))}
              </div>
            </div>
          ))}
        </div>
      </div>

      {/* Main 3-column layout */}
      <div className="flex flex-1 gap-4 min-h-0">
        {/* Left: Template List */}
        <div className="w-64 flex-shrink-0 bg-white rounded-lg shadow-sm border border-secondary-200 flex flex-col" data-testid="template-list-panel">
          <div className="flex items-center justify-between p-3 border-b border-secondary-200">
            <h2 className="text-sm font-semibold text-secondary-700">{t('reports.templates', 'Templates')}</h2>
            <button
              onClick={startNewTemplate}
              className="p-1 rounded hover:bg-secondary-100 text-primary-600"
              title={t('reports.newTemplate', 'New Template')}
              data-testid="btn-new-template"
            >
              <Plus className="w-4 h-4" />
            </button>
          </div>
          <div className="flex-1 overflow-y-auto">
            {templatesLoading ? (
              <div className="flex items-center justify-center p-4">
                <Loader2 className="w-5 h-5 animate-spin text-secondary-400" />
              </div>
            ) : templates.length === 0 ? (
              <p className="text-sm text-secondary-400 text-center p-4">{t('reports.noTemplates', 'No templates yet')}</p>
            ) : (
              <ul className="py-1">
                {templates.map((tpl) => (
                  <li key={tpl.id}>
                    <div
                      className={clsx(
                        'flex items-center justify-between px-3 py-2 cursor-pointer hover:bg-secondary-50',
                        selectedTemplate?.id === tpl.id && 'bg-primary-50 border-l-2 border-primary-500',
                      )}
                      onClick={() => selectTemplate(tpl)}
                    >
                      <div className="flex-1 min-w-0">
                        <p className="text-sm font-medium text-secondary-800 truncate">{tpl.name}</p>
                        <p className="text-xs text-secondary-400">{tpl.output_format}</p>
                      </div>
                      <button
                        onClick={(e) => { e.stopPropagation(); handleDeleteTemplate(tpl); }}
                        className="p-1 rounded hover:bg-red-100 text-red-500"
                        title={t('common.delete', 'Delete')}
                      >
                        <Trash2 className="w-3.5 h-3.5" />
                      </button>
                    </div>
                  </li>
                ))}
              </ul>
            )}
          </div>
        </div>

        {/* Center: Template Editor */}
        <div className="flex-1 bg-white rounded-lg shadow-sm border border-secondary-200 flex flex-col" data-testid="template-editor-panel">
          <div className="flex items-center justify-between p-3 border-b border-secondary-200">
            <h2 className="text-sm font-semibold text-secondary-700">
              {isNewTemplate ? t('reports.newTemplate', 'New Template') : selectedTemplate ? t('reports.editTemplate', 'Edit Template') : t('reports.selectTemplate', 'Select a template')}
            </h2>
            <div className="flex items-center gap-2">
              <select
                value={editorFormat}
                onChange={(e) => setEditorFormat(e.target.value as OutputFormat)}
                className="text-sm border border-secondary-300 rounded px-2 py-1"
                data-testid="select-output-format"
              >
                <option value="pdf">PDF</option>
                <option value="print">Print</option>
                <option value="csv">CSV</option>
                <option value="excel">Excel</option>
                <option value="json">JSON</option>
              </select>
              <button
                onClick={handleSaveTemplate}
                disabled={isSaving || (!editorName.trim() && !isNewTemplate && !selectedTemplate)}
                className="flex items-center gap-1 px-3 py-1 text-sm bg-primary-600 text-white rounded hover:bg-primary-700 disabled:opacity-50"
                data-testid="btn-save-template"
              >
                {isSaving ? <Loader2 className="w-3.5 h-3.5 animate-spin" /> : <Save className="w-3.5 h-3.5" />}
                {t('common.save', 'Save')}
              </button>
            </div>
          </div>
          <div className="p-3 flex-1 flex flex-col gap-2 min-h-0">
            <input
              type="text"
              value={editorName}
              onChange={(e) => setEditorName(e.target.value)}
              placeholder={t('reports.templateName', 'Template name')}
              className="w-full text-sm border border-secondary-300 rounded px-3 py-2"
              data-testid="input-template-name"
            />
            <textarea
              value={editorContent}
              onChange={(e) => setEditorContent(e.target.value)}
              placeholder={t('reports.templateContent', 'Jinja2 template content (HTML for PDF)')}
              className="flex-1 w-full text-sm font-mono border border-secondary-300 rounded px-3 py-2 resize-none"
              spellCheck={false}
              data-testid="textarea-template-content"
            />
          </div>
        </div>

        {/* Right: Preview / Generate */}
        <div className="w-72 flex-shrink-0 bg-white rounded-lg shadow-sm border border-secondary-200 flex flex-col" data-testid="generate-panel">
          <div className="p-3 border-b border-secondary-200">
            <h2 className="text-sm font-semibold text-secondary-700">{t('reports.generate', 'Generate')}</h2>
          </div>
          <div className="p-3 flex-1 flex flex-col gap-3 overflow-y-auto">
            <div>
              <label className="text-xs font-medium text-secondary-600 mb-1 block">
                {t('reports.jsonData', 'Data (JSON)')}
              </label>
              <textarea
                value={jsonData}
                onChange={(e) => setJsonData(e.target.value)}
                placeholder='{"key": "value"}'
                className="w-full text-xs font-mono border border-secondary-300 rounded px-2 py-1.5 h-40 resize-none"
                spellCheck={false}
                data-testid="textarea-json-data"
              />
            </div>
            <button
              onClick={handleGenerate}
              disabled={isGenerating || !selectedTemplate}
              className="flex items-center justify-center gap-2 px-4 py-2 text-sm bg-primary-600 text-white rounded hover:bg-primary-700 disabled:opacity-50"
              data-testid="btn-generate-report"
            >
              {isGenerating ? <Loader2 className="w-4 h-4 animate-spin" /> : <Download className="w-4 h-4" />}
              {t('reports.generateReport', 'Generate Report')}
            </button>
            {!selectedTemplate && (
              <p className="text-xs text-secondary-400 text-center">{t('reports.selectTemplateHint', 'Select a template from the list')}</p>
            )}
          </div>
        </div>
      </div>

      {/* Download History */}
      <div className="bg-white rounded-lg shadow-sm border border-secondary-200 p-4" data-testid="download-history">
        <h2 className="text-sm font-semibold text-secondary-700 mb-2">{t('reports.downloadHistory', 'Download History')}</h2>
        {downloadHistory.length === 0 ? (
          <p className="text-sm text-secondary-400">{t('reports.noDownloads', 'No downloads yet')}</p>
        ) : (
          <ul className="divide-y divide-secondary-100">
            {downloadHistory.map((entry) => (
              <li key={entry.id} className="flex items-center justify-between py-2 text-sm">
                <div className="flex items-center gap-2">
                  <FileText className="w-4 h-4 text-secondary-400" />
                  <span className="font-medium text-secondary-700">{entry.name}</span>
                  <span className="text-xs px-1.5 py-0.5 rounded bg-secondary-100 text-secondary-600 uppercase">{entry.format}</span>
                </div>
                <span className="text-xs text-secondary-400">{entry.timestamp}</span>
              </li>
            ))}
          </ul>
        )}
      </div>
    </div>
  );
}
