import React, { createContext, useCallback, useEffect, useState } from 'react';
import axios from 'B/axios';

type AvailableDashboardTypes = 'dash' | 'iframe' | 'news';

type AvailableDashboard = {
  id: number;
  name: string;
  ber_name: string;
  ber_barcode: string;
  listen_typ: string;
};

type Response = {
  [key in AvailableDashboardTypes]: AvailableDashboard[];
};

type SourceDescriptor = { idShort: string; type: string; text: string };

export type CreateListArgs = {
  name: string;
  type: string;
  folderId: number | string;
  sources?: SourceDescriptor[];
};

type CreateListResult = { newId: number | string };

type AvailableDashboardsContextValue = {
  dashList: AvailableDashboard[];
  iframeList: AvailableDashboard[];
  taskoNews: AvailableDashboard[];
  createList: (args: CreateListArgs) => Promise<CreateListResult>;
};

export const AvailableDashboardsContext = createContext<AvailableDashboardsContextValue | null>(null);

async function fetchAvailableDashboards() {
  const res = await axios.get<Response>('/dashcontents');
  return res.data;
}

const GROUP_PERMISSION_MASK = 63488;
const GROUP_CREATION_TYPE = 'LST';
const DEFAULT_LIST_TYPE = 'events';
const DEFAULT_REP_FORMAT = 'pdf';
const DEFAULT_NFC_VALUE = '0,0';
const DEFAULT_POSITION = '01';

const normalizeFolderId = (value: number | string): string => {
  const str = String(value ?? '').trim();
  if (!str) return '';
  const match = str.match(/^([A-Za-z]{3})(\d+)$/);
  if (match) {
    return `${match[1].toUpperCase()}${match[2]}`;
  }
  const digits = str.replace(/\D+/g, '');
  return digits ? `${GROUP_CREATION_TYPE}${digits}` : '';
};

const buildFormBody = (data: Record<string, any>) => {
  const form = new URLSearchParams();
  Object.entries(data).forEach(([key, value]) => {
    if (value === undefined || value === null) return;
    if (typeof value === 'object' && !(value instanceof Blob)) {
      form.append(key, JSON.stringify(value));
    } else {
      form.append(key, String(value));
    }
  });
  return form;
};

const buildQagVars = (grpId: number, sources: SourceDescriptor[] = []) => {
  if (!Array.isArray(sources) || sources.length === 0) {
    return '[]';
  }
  const rows = sources.map((src, index) => {
    const order = String(index + 1).padStart(2, '0');
    const qagId = `i${grpId * 1000 + index + 1}`;
    return [
      src.idShort,
      DEFAULT_POSITION,
      '1',
      src.text ?? '',
      '',
      order,
      qagId,
    ];
  });
  return JSON.stringify(rows);
};

const saveRepConfiguration = async (
  grpId: number,
  name: string,
  listType: string,
  sources: SourceDescriptor[] = [],
) => {
  const payload = {
    grp_id: grpId,
    grp_name: name,
    grp_global: 0,
    grp_bemerkung: '',
    grp_barcode: listType || DEFAULT_LIST_TYPE,
    grp_nfc: DEFAULT_NFC_VALUE,
    grp_kostenstelle: DEFAULT_REP_FORMAT,
    grp_berechtigung: GROUP_PERMISSION_MASK,
    grp_sendmail: 0,
    grp_rechte_usg: '0',
    grp_rechte_usr: '0',
    grp_activfunc: 0,
    grp_mail: '',
    grp_mailids: '',
    grp_htmlinfos: '',
    grp_strcnt: 0,
    grp_RepSendHour: 0,
    maxCount: 0,
    disabledConfig: 0,
    qag_vars: buildQagVars(grpId, sources),
  };

  const body = buildFormBody(payload).toString();
  await axios.post(`/konfig/saverep/GRP${grpId}`, body, {
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    responseType: 'text',
  });
};

export const AvailableDashboardsProvider: React.FC<{}> = (props) => {
  const [dashList, setDashList] = useState([]);
  const [iframeList, setiframeList] = useState([]);
  const [taskoNews, setTaskoNews] = useState([]);

  const refreshLists = useCallback(async () => {
    try {
      const dash = await fetchAvailableDashboards();
      setDashList(dash.dash ?? []);
      setiframeList(dash.iframe ?? []);
      setTaskoNews(dash.news ?? []);
    } catch (error) {
      console.error('dashcontents fetch failed', error);
      setDashList([]);
      setiframeList([]);
      setTaskoNews([]);
    }
  }, []);

  useEffect(() => {
    refreshLists();
  }, [refreshLists]);

  const parseMaybeJson = (payload: any) => {
    if (payload == null) return null;
    if (typeof payload === 'string') {
      try {
        return JSON.parse(payload);
      } catch (err) {
        console.warn('createList response is not valid JSON', err);
        return null;
      }
    }
    return payload;
  };

  const createList = useCallback(async ({ name, type, folderId, sources }: CreateListArgs): Promise<CreateListResult> => {
    if (!name?.trim()) {
      throw new Error('Name der Liste fehlt');
    }
    if (!folderId && folderId !== 0) {
      throw new Error('Zielordner fehlt');
    }
    const normalizedFolderId = normalizeFolderId(folderId);
    if (!normalizedFolderId) {
      throw new Error('Ungültiger Speicherort.');
    }
    const basePayload = {
      id: normalizedFolderId,
      mentyp: GROUP_CREATION_TYPE,
      name: name.trim(),
    };

    const creationResponse = await axios.post(
      '/config/leftmenueADD',
      buildFormBody(basePayload).toString(),
      {
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        responseType: 'text',
      }
    );
    const parsed = parseMaybeJson(creationResponse.data);
    const newIdRaw = parsed?.id ?? parsed?.newId ?? parsed?.ID ?? parsed?.grp_id;
    const newId = Number(newIdRaw);

    if (!Number.isFinite(newId)) {
      throw new Error('Server lieferte keine neue Listen-ID.');
    }

    try {
      await saveRepConfiguration(newId, name.trim(), type, sources ?? []);
    } catch (err) {
      console.error('SaveREP failed for new list', err);
      throw err;
    }

    await refreshLists();

    return { newId };
  }, [refreshLists]);

  return (
    <AvailableDashboardsContext.Provider
      value={{ dashList, iframeList, taskoNews, createList }}
    >
      {props.children}
    </AvailableDashboardsContext.Provider>
  );
};
