/**
 * useDoctypeFields.ts  — v6 (server-side field resolution)
 *
 * ROOT CAUSE OF ALL PREVIOUS VERSIONS:
 * ─────────────────────────────────────
 * Frappe's meta APIs (/api/resource/DocType and /api/resource/Custom Field)
 * are ROLE-FILTERED by design.  Frappe strips fields the current user's role
 * cannot read BEFORE returning the response.  No client-side cache strategy
 * can fix this because the *source data* is already wrong.
 *
 * Example:
 *   Contractor Engineer  →  /api/resource/DocType/Work_Order  →  6 fields
 *   Administrator        →  /api/resource/DocType/Work_Order  →  45 fields
 *
 * THE REAL FIX:
 * ─────────────
 * Call a whitelisted Python function (`asset_lite.api.doctype_fields.get_export_fields`)
 * that uses `frappe.get_meta()` and `frappe.get_all(..., ignore_permissions=True)`.
 * These bypass field-level role filtering and always return the complete list.
 *
 * The in-memory cache below is fine to key by doctype only (no user suffix
 * needed) because the server now returns the same field list for everyone.
 * sessionStorage is intentionally NOT used — a hard refresh always gets fresh
 * data, avoiding the "need Ctrl+Shift+R" problem entirely.
 */

import { useState, useEffect, useRef } from 'react';

export interface DoctypeField {
  key: string;
  label: string;
  fieldtype: string;
  default: boolean;
}

// ── Default fields per DocType ────────────────────────────────────────────────
const DEFAULT_FIELDS: Record<string, Set<string>> = {
  Work_Order: new Set([
    'name', 'asset', 'asset_name', 'work_order_type', 'company',
    'department', 'repair_status', 'workflow_state', 'custom_priority_',
    'creation', 'modified',
  ]),
  Asset: new Set([
    'name', 'asset_name', 'custom_serial_number', 'company',
    'location', 'custom_device_status', 'modified',
  ]),
};

// ── In-memory cache (tab lifetime only, keyed by doctype) ────────────────────
// Safe to key by doctype only now because the server returns role-independent
// results.  Clears automatically on page refresh — no stale data ever.
const memCache = new Map<string, DoctypeField[]>();

// ── Hook ──────────────────────────────────────────────────────────────────────

export function useDoctypeFields(doctype: string) {
  const [fields, setFields]   = useState<DoctypeField[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError]     = useState<string | null>(null);
  const fetchingRef           = useRef(false);

  useEffect(() => {
    if (!doctype) return;
    let cancelled = false;

    const run = async () => {
      if (fetchingRef.current) return;
      fetchingRef.current = true;

      // ── In-memory cache hit ───────────────────────────────────────────────
      if (memCache.has(doctype)) {
        if (!cancelled) setFields(memCache.get(doctype)!);
        fetchingRef.current = false;
        return;
      }

      if (!cancelled) { setLoading(true); setError(null); }

      try {
        // ── Call the server-side whitelisted function ─────────────────────
        // This uses frappe.get_meta() + ignore_permissions=True internally,
        // so it returns ALL fields regardless of the current user's role.
        const res = await fetch(
          '/api/method/asset_lite.api.doctype_fields.get_export_fields',
          {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            credentials: 'include',
            body: JSON.stringify({ doctype }),
          }
        );

        if (!res.ok) {
          throw new Error(`Server returned ${res.status}`);
        }

        const data = await res.json();

        if (data.exc) {
          throw new Error(data.exc);
        }

        // Server returns: [{ fieldname, label, fieldtype }, ...]
        const raw: { fieldname: string; label: string; fieldtype: string }[] =
          data.message || [];

        const defaultSet = DEFAULT_FIELDS[doctype];

        const normalized: DoctypeField[] = raw.map((f, idx) => ({
          key:       f.fieldname,
          label:     f.label || f.fieldname,
          fieldtype: f.fieldtype || 'Data',
          default:   defaultSet ? defaultSet.has(f.fieldname) : idx < 8,
        }));

        console.log(
          `[useDoctypeFields] ✅ "${doctype}": ${normalized.length} fields from server`
        );

        memCache.set(doctype, normalized);
        if (!cancelled) setFields(normalized);

      } catch (err) {
        console.error('[useDoctypeFields] ❌', err);
        if (!cancelled) {
          setError(err instanceof Error ? err.message : 'Failed to fetch fields');
          // Minimal fallback so the export modal isn't completely broken
          setFields([
            { key: 'name',     label: 'ID',          fieldtype: 'Data',     default: true  },
            { key: 'creation', label: 'Created On',  fieldtype: 'Datetime', default: false },
            { key: 'modified', label: 'Modified On', fieldtype: 'Datetime', default: true  },
          ]);
        }
      } finally {
        fetchingRef.current = false;
        if (!cancelled) setLoading(false);
      }
    };

    run();
    return () => { cancelled = true; };
  }, [doctype]);

  /** Force a re-fetch from the server (e.g. after DocType schema changes). */
  const refetchFields = () => {
    memCache.delete(doctype);
    fetchingRef.current = false;
    setFields([]);
    setError(null);
  };

  return { fields, loading, error, refetchFields };
}