import { useEffect, useState } from 'react';
import { cn } from '../../lib/cn';
import { formatValue } from '../../lib/format';
import type { ZinoClient } from '../../api/client';
import { APP_ID } from '../../api/config';
import { Card } from '../reusable/Card';
import { Spinner } from '../reusable/Spinner';
import { EmptyState } from '../reusable/EmptyState';

export interface DetailViewProps {
  /** Workflow-bound client (see api/clients.ts). */
  client: ZinoClient;
  /** detailview template uid. */
  dvUid?: string;
  /** Instance to render. */
  instanceId: number | string;
  /** Card header title. */
  title?: string;
  /** Restrict/order visible fields by field_key. Defaults to all. */
  fields?: string[];
  /** Columns in the definition grid. @default 2 */
  columns?: 1 | 2 | 3;
}


/**
 * Generic Zino detail view. Fetches `GET /app/{id}/view/detailview/{dvUid}` and
 * renders the data as a labeled definition grid.
 */
export function DetailView({ client, dvUid, instanceId, title, fields, columns = 2 }: DetailViewProps) {
  const [data, setData] = useState<Record<string, unknown> | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    let live = true;
    async function run() {
      setLoading(true);
      setError(null);
      try {
        if (!dvUid) throw new Error("dvUid is required to fetch detail view data.");
        const r = await client.detailView(dvUid, instanceId);
        if (live) {
          setData(r.data || {});
        }
      } catch (e) {
        if (live) setError((e as { message?: string })?.message ?? 'Failed to load');
      } finally {
        if (live) setLoading(false);
      }
    }
    run();
    return () => {
      live = false;
    };
  }, [client, dvUid, instanceId]);

  const gridCols = { 1: 'grid-cols-1', 2: 'grid-cols-1 sm:grid-cols-2', 3: 'grid-cols-1 sm:grid-cols-3' }[columns];

  if (error) {
    return (
      <Card title={title}>
        <EmptyState title="Couldn’t load record" hint={error} />
      </Card>
    );
  }
  
  if (loading) {
    return (
      <Card title={title}>
        <div className="py-8 flex justify-center">
          <Spinner label="Loading…" />
        </div>
      </Card>
    );
  }
  
  if (!data || Object.keys(data).length === 0) {
    return (
      <Card title={title}>
        <EmptyState title="No details found" />
      </Card>
    );
  }

  return (
    <div className="flex flex-col gap-4">
      <Card 
        title={title || 'Details'} 
        className="border-t-[4px] border-[var(--z-bg-primary)] shadow-md"
        bodyClassName="bg-slate-50/30"
      >
        <dl className={cn('grid gap-x-6 gap-y-6', gridCols)}>
          {Object.entries(data).map(([key, value]) => {
            if (fields && !fields.includes(key)) return null;
            const lowerKey = key.toLowerCase();
            if (lowerKey.includes('uuid') || /^\d+$/.test(key)) return null;
            
                const isGridArray =
                  Array.isArray(value) &&
                  value.length > 0 &&
                  typeof value[0] === 'object' &&
                  value[0] !== null &&
                  !('original_name' in value[0]) &&
                  !('url' in value[0]);

                if (isGridArray) {
                  const rows = value as Record<string, unknown>[];
                  // Use all unique keys found across all rows just in case they differ slightly
                  const headers = Array.from(new Set(rows.flatMap(r => Object.keys(r))));

                  return (
                    <div key={key} className="flex flex-col gap-2 min-w-0 col-span-full mt-2 mb-4">
                      <dt className="text-[11px] font-bold uppercase tracking-[0.08em] text-[var(--z-bg-primary)] opacity-80">
                        {key.replace(/_/g, ' ')}
                      </dt>
                      <dd className="m-0 text-sm text-strong font-medium overflow-x-auto rounded border border-border-subtle shadow-sm">
                        <table className="min-w-full divide-y divide-border-subtle text-left bg-[var(--tiles-card-bg)]">
                          <thead className="bg-slate-50">
                            <tr>
                              {headers.map(h => (
                                <th key={h} className="px-4 py-2 text-[10px] font-bold uppercase text-muted tracking-wide whitespace-nowrap">
                                  {h.replace(/_/g, ' ')}
                                </th>
                              ))}
                            </tr>
                          </thead>
                          <tbody className="divide-y divide-border-subtle">
                            {rows.map((row, idx) => (
                              <tr key={idx} className="hover:bg-slate-50/50">
                                {headers.map(h => (
                                  <td key={h} className="px-4 py-2 whitespace-nowrap text-sm text-strong">
                                    {formatValue(row[h])}
                                  </td>
                                ))}
                              </tr>
                            ))}
                          </tbody>
                        </table>
                      </dd>
                    </div>
                  );
                }

                const isFileArray =
                  Array.isArray(value) &&
                  value.length > 0 &&
                  typeof value[0] === 'object' &&
                  value[0] !== null &&
                  ('original_name' in value[0] || 'uuid' in value[0]);

                if (isFileArray) {
                  return (
                    <div key={key} className="flex flex-col gap-2 min-w-0 col-span-full mt-2 mb-4">
                      <dt className="text-[11px] font-bold uppercase tracking-[0.08em] text-[var(--z-bg-primary)] opacity-80">
                        {key.replace(/_/g, ' ')}
                      </dt>
                      <dd className="m-0 flex flex-wrap gap-4">
                        {(value as any[]).map((file, idx) => {
                          const previewUrl = `${client.baseUrl}/app/${APP_ID}/view/files/${file.uuid}/preview`;
                          return (
                            <div key={file.uuid || idx} className="relative w-32 h-32 rounded-lg border border-border-subtle overflow-hidden bg-slate-100 flex items-center justify-center group shadow-sm">
                              <img 
                                src={previewUrl} 
                                alt={file.original_name || 'Attached File'} 
                                className="w-full h-full object-cover transition-transform group-hover:scale-105"
                                onError={(e) => {
                                  (e.target as HTMLImageElement).style.display = 'none';
                                  (e.target as HTMLImageElement).parentElement!.innerHTML = `<span class="text-[10px] text-faint text-center px-2 break-all font-mono">${file.original_name || 'File'}</span>`;
                                }}
                              />
                              <a 
                                href={previewUrl} 
                                target="_blank" 
                                rel="noopener noreferrer" 
                                className="absolute inset-0 z-10"
                              ></a>
                            </div>
                          );
                        })}
                      </dd>
                    </div>
                  );
                }

                return (
                  <div key={key} className="flex flex-col gap-1.5 min-w-0">
                    <dt className="text-[11px] font-bold uppercase tracking-[0.08em] text-[var(--z-bg-primary)] opacity-80">
                      {key.replace(/_/g, ' ')}
                    </dt>
                    <dd className="m-0 text-sm text-strong font-medium break-words">
                      {formatValue(value)}
                    </dd>
                  </div>
                );
              })}
            </dl>
      </Card>
    </div>
  );
}
