// Shared API client + state machine for SurveyForge.
// Wired against the live API at https://surveyforge-j2jz.onrender.com.

const SF_API_BASE = 'https://surveyforge-j2jz.onrender.com';

// — Survey types & templates fetched once, cached on window —
const SF_FALLBACK_SURVEY_TYPES = [
  { slug: 'reptile', label: 'Reptile (ARG UK AIA)' },
  { slug: 'dormouse', label: 'Hazel dormouse' },
  { slug: 'badger', label: 'Badger' },
  { slug: 'gcn', label: 'Great crested newt' },
  { slug: 'otters', label: 'Otter' },
  { slug: 'water_voles', label: 'Water vole' },
  { slug: 'phase1', label: 'Phase 1 habitat survey' },
  { slug: 'arb', label: 'Arboricultural (BS5837)' },
  { slug: 'pra', label: 'Preliminary roost assessment (bats)' },
];
const SF_FALLBACK_TEMPLATES = {
  default: 'surveyforge_professional',
  templates: [
    { slug: 'surveyforge_professional', name: 'Professional', tagline: 'Clean serif body, conservative spacing — the default' },
    { slug: 'surveyforge_classic', name: 'Classic', tagline: 'Times-style headings, formal report register' },
    { slug: 'surveyforge_modern', name: 'Modern', tagline: 'Sans-serif throughout, lighter feel' },
    { slug: 'surveyforge_consultancy', name: 'Consultancy', tagline: 'Two-column cover, detailed methodology blocks' },
    { slug: 'surveyforge_minimal', name: 'Minimal', tagline: 'Stripped back — body text only, no decorative elements' },
  ],
};

function useSurveyForgeMeta() {
  const [data, setData] = React.useState({ surveyTypes: null, templates: null, error: null });
  React.useEffect(() => {
    let cancelled = false;
    async function load() {
      const out = { surveyTypes: SF_FALLBACK_SURVEY_TYPES, templates: SF_FALLBACK_TEMPLATES, error: null };
      try {
        const [stRes, tRes] = await Promise.all([
          fetch(`${SF_API_BASE}/api/survey-types`).then(r => r.ok ? r.json() : null).catch(() => null),
          fetch(`${SF_API_BASE}/api/templates`).then(r => r.ok ? r.json() : null).catch(() => null),
        ]);
        if (stRes && Array.isArray(stRes.survey_types)) out.surveyTypes = stRes.survey_types;
        if (tRes && Array.isArray(tRes.templates)) out.templates = tRes;
      } catch (e) {
        out.error = e.message;
      }
      if (!cancelled) setData(out);
    }
    load();
    return () => { cancelled = true; };
  }, []);
  return data;
}

// — The form-state machine. Status drives the UI for each direction. —
// status: 'idle' | 'ready' | 'generating' | 'success' | 'error'
function useSurveyForgeForm({ initialStatus = 'idle' } = {}) {
  const [state, setState] = React.useState({
    surveyType: '',
    templateSlug: '',
    customTemplateFile: null,   // .docx — overrides templateSlug if set
    siteName: '',
    clientName: '',
    surveyorName: '',
    projectNumber: '',
    reportTitle: '',
    reportStatus: '',           // Draft / For Review / Final / etc.
    reportDate: '',             // free text
    photos: [],                 // array of { file, caption }
    file: null,
    status: initialStatus,
    progress: 0,
    error: null,
    errorKind: null, // 'columns' | 'server' | 'network' | 'validation'
    downloadUrl: null,
    downloadName: null,
  });

  const set = React.useCallback((patch) => {
    setState((s) => ({ ...s, ...(typeof patch === 'function' ? patch(s) : patch) }));
  }, []);

  const setFile = React.useCallback((f) => {
    set({
      file: f,
      status: f ? 'ready' : 'idle',
      error: null,
      errorKind: null,
      downloadUrl: null,
      downloadName: null,
    });
  }, [set]);

  const reset = React.useCallback(() => {
    setState((s) => ({
      ...s,
      file: null,
      status: 'idle',
      progress: 0,
      error: null,
      errorKind: null,
      downloadUrl: null,
      downloadName: null,
    }));
  }, []);

  const generate = React.useCallback(async () => {
    if (!state.file || !state.surveyType) {
      set({ status: 'error', error: 'Pick a survey type and upload a data file first.', errorKind: 'validation' });
      return;
    }
    set({ status: 'generating', progress: 0, error: null, errorKind: null, downloadUrl: null });

    // Fake-progress while we wait — this is honest because the API takes 2–10s.
    let progress = 0;
    const tick = setInterval(() => {
      progress = Math.min(92, progress + Math.random() * 9 + 2);
      setState((s) => s.status === 'generating' ? { ...s, progress } : s);
    }, 380);

    const fd = new FormData();
    fd.append('survey_type', state.surveyType);
    fd.append('data_file', state.file);
    // Template: custom file overrides slug if both are set
    if (state.customTemplateFile) {
      fd.append('template_file', state.customTemplateFile);
    } else if (state.templateSlug) {
      fd.append('template_slug', state.templateSlug);
    }
    // Cover-page metadata
    if (state.siteName) fd.append('site_name', state.siteName);
    if (state.clientName) fd.append('client_name', state.clientName);
    if (state.surveyorName) fd.append('surveyor_name', state.surveyorName);
    if (state.projectNumber) fd.append('project_number', state.projectNumber);
    if (state.reportTitle) fd.append('report_title', state.reportTitle);
    if (state.reportStatus) fd.append('status', state.reportStatus);
    if (state.reportDate) fd.append('report_date', state.reportDate);
    // Photo attachments — multiple files + parallel JSON captions
    if (state.photos && state.photos.length) {
      const captions = [];
      for (const p of state.photos) {
        if (!p.file) continue;
        fd.append('photo_files', p.file);
        captions.push(p.caption || '');
      }
      fd.append('photo_captions', JSON.stringify(captions));
    }

    try {
      const res = await fetch(`${SF_API_BASE}/api/generate`, { method: 'POST', body: fd });
      clearInterval(tick);
      if (!res.ok) {
        let detail = `Request failed (${res.status})`;
        let kind = res.status >= 500 ? 'server' : 'validation';
        try {
          const j = await res.json();
          if (j && j.detail) {
            detail = j.detail;
            if (/column|header|recognis|recogniz/i.test(j.detail)) kind = 'columns';
          }
        } catch {}
        set({ status: 'error', error: detail, errorKind: kind, progress: 0 });
        return;
      }
      const blob = await res.blob();
      const url = URL.createObjectURL(blob);
      const cd = res.headers.get('Content-Disposition') || '';
      const m = cd.match(/filename\*?=(?:UTF-8'')?"?([^";]+)"?/i);
      const name = (m && decodeURIComponent(m[1])) || `surveyforge_${state.surveyType}.docx`;
      set({ status: 'success', progress: 100, downloadUrl: url, downloadName: name });
    } catch (e) {
      clearInterval(tick);
      set({ status: 'error', error: 'Couldn\'t reach the report service. Check your connection and try again.', errorKind: 'network', progress: 0 });
    }
  }, [state, set]);

  // For the prototype: jump to a state without an actual API call.
  const simulate = React.useCallback((status) => {
    if (status === 'idle') {
      setState((s) => ({ ...s, status: 'idle', file: null, error: null, errorKind: null, downloadUrl: null, progress: 0 }));
    } else if (status === 'ready') {
      setState((s) => ({
        ...s,
        status: 'ready',
        file: s.file || new File(['site,date\nA1,2026-04-01'], 'reptile_standard.csv', { type: 'text/csv' }),
        error: null, errorKind: null, downloadUrl: null, progress: 0,
      }));
    } else if (status === 'generating') {
      setState((s) => ({ ...s, status: 'generating', progress: 42, error: null, errorKind: null }));
    } else if (status === 'success') {
      setState((s) => ({
        ...s,
        status: 'success',
        progress: 100,
        downloadUrl: '#',
        downloadName: `surveyforge_${s.surveyType || 'reptile'}.docx`,
        error: null, errorKind: null,
      }));
    } else if (status === 'error_columns') {
      setState((s) => ({
        ...s,
        status: 'error',
        error: 'Data file has unrecognised columns: "transect_id", "weather_code". Expected: site, date, observer, species, count, location.',
        errorKind: 'columns',
        progress: 0,
      }));
    } else if (status === 'error_server') {
      setState((s) => ({
        ...s,
        status: 'error',
        error: 'The report service had a problem on its end. Please try again — if it keeps failing, contact support.',
        errorKind: 'server',
        progress: 0,
      }));
    }
  }, []);

  return { state, set, setFile, reset, generate, simulate };
}

// — Tiny shared bits —
function fileSize(f) {
  if (!f) return '';
  const n = f.size;
  if (n < 1024) return `${n} B`;
  if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;
  return `${(n / 1024 / 1024).toFixed(1)} MB`;
}

const SF_ACCEPT_FILES = '.csv,.xlsx,.xlsm,.xls,text/csv,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';

Object.assign(window, {
  SF_API_BASE,
  SF_FALLBACK_SURVEY_TYPES,
  SF_FALLBACK_TEMPLATES,
  SF_ACCEPT_FILES,
  useSurveyForgeMeta,
  useSurveyForgeForm,
  fileSize,
});
