// resources\assets\ts\ContactsPage\components\MitarbeiterTab\MitarbeiterTab.tsx

import React, { useState, useEffect, useMemo } from "react";
import {
  DataGrid,
  GridColDef,
  GridRowsProp,
  GridRowModesModel,
  GridRowModes,
  GridActionsCellItem,
  GridEventListener,
  GridRowId,
  GridRowModel,
  GridRowEditStopReasons,
} from "@mui/x-data-grid";
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import IconButton from '@mui/material/IconButton';
import Link from '@mui/material/Link';
import TextField from '@mui/material/TextField';
import Typography from '@mui/material/Typography';
import Checkbox from '@mui/material/Checkbox';
import {
  Edit as EditIcon,
  Delete as DeleteIcon,
  Save as SaveIcon,
  Cancel as CancelIcon,
  Add as AddIcon,
  Visibility as VisibilityIcon,
  Download as DownloadIcon,
} from "@mui/icons-material";
import { MitarbeiterTabProps, Employer } from "../types";
import { Trans, msg } from '@lingui/macro';
import { useLingui } from '@lingui/react';
import { getEmployeeCsvKeys, getEmployeeCsvHeaders, employeeExportFilename } from '../../utils/employeeCsvImportUtils';

interface MitarbeiterRow extends Employer {
  isNew?: boolean;
}

const MitarbeiterTab: React.FC<MitarbeiterTabProps> = ({
  adresses,
  adrId,
  csrfToken,
}) => {
  const { i18n } = useLingui();
  const employers = useMemo(() => {
    const current = adresses.find((adr) => adr.id === adrId);
    return current?.employer || [];
  }, [adresses, adrId]);

  const [rows, setRows] = useState<MitarbeiterRow[]>([]);
  const [rowModesModel, setRowModesModel] = useState<GridRowModesModel>({});
  const [selectedRows, setSelectedRows] = useState<GridRowId[]>([]);

  //loading states when delete/save mitarbeiter
  const [loading, setLoading] = useState(false);

  // Track how many phone fields to show per row in edit mode
  const [phoneFieldCounts, setPhoneFieldCounts] = useState<{
    [key: number]: number;
  }>({});

  useEffect(() => {
    setRows(employers.map((emp) => ({ ...emp, isNew: false })));

    // Initialize phone field counts based on existing data
    const counts: { [key: number]: number } = {};
    employers.forEach((emp) => {
      const phoneCount = ["dw1", "dw2", "dw3", "dw4"].filter(
        (field) => emp[field as keyof Employer]
      ).length;
      counts[emp.ma_id] = Math.max(phoneCount, 1);
    });
    setPhoneFieldCounts(counts);
  }, [employers]);

  const fetchEmployers = () => {
    if (!adrId) return;
    fetch(`/contacts/getadr/${adrId}`, {
      headers: {
        Accept: "application/json",
      },
    })
      .then((res) => {
        if (!res.ok) throw new Error("Nicht OK");
        return res.json();
      })
      .then((data) => {
        setRows(data.employer?.map((emp: Employer) => ({ ...emp, isNew: false })) || []);
      })
      .catch((err) =>
        console.error("Fehler beim Laden der Mitarbeiter:", err)
      );
  };

  const validatePhoneNumbers = (input: string): boolean => {
    const numbers = input.split(/[;,]/);
    const phoneRegex = /^\+?[0-9\s\-\(\)\/\.]{5,20}$/;
    return numbers.every((num) => phoneRegex.test(num.trim()));
  };

  const validateEmployer = (employer: MitarbeiterRow): boolean => {
    if (
      employer.email &&
      !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(employer.email)
    ) {
      alert(i18n._(msg`Please enter a valid email address.`));
      return false;
    }

    const phoneFields: (keyof Employer)[] = ["dw1", "dw2", "dw3", "dw4"];
    for (const field of phoneFields) {
      if (
        employer[field] &&
        !validatePhoneNumbers(employer[field] as string)
      ) {
        alert(i18n._(msg`Please enter a valid phone number for ${field}.`));
        return false;
      }
    }

    if (employer.fax && !validatePhoneNumbers(employer.fax)) {
      alert(i18n._(msg`Please enter a valid fax number.`));
      return false;
    }

    return true;
  };

  const handleAddMitarbeiter = () => {
    const newId = Date.now(); // Temporary ID for new row
    const newEmployer: MitarbeiterRow = {
      ma_id: newId,
      MW: "",
      Name: "",
      vorname: "",
      bemerkung: "",
      dw1: "",
      dw2: "",
      dw3: "",
      dw4: "",
      email: "",
      fax: "",
      kma_brf: false,
      isNew: true,
    };

    setRows((oldRows) => [newEmployer, ...oldRows]);
    setRowModesModel((oldModel) => ({
      ...oldModel,
      [newId]: { mode: GridRowModes.Edit, fieldToFocus: "MW" },
    }));
    setPhoneFieldCounts((prev) => ({ ...prev, [newId]: 1 }));
  };

  const handleDeleteSelected = () => {
    if (selectedRows.length === 0) {
      alert(i18n._(msg`Please select at least one employee to delete.`));
      return;
    }

    if (!window.confirm(i18n._(msg`Delete ${selectedRows.length} employees?`))) {
      return;
    }

    setLoading(true);

    const deletePromises = selectedRows.map((id) => {
      const row = rows.find((r) => r.ma_id === id);
      if (row && !row.isNew) {
        const formData = new FormData();
        formData.append("maid", row.ma_id.toString());
        formData.append("delMA", "1");
        formData.append("_token", csrfToken);

        return fetch("/contacts/saveEmp", {
          method: "POST",
          body: formData,
        });
      }
      return Promise.resolve();
    });

    Promise.all(deletePromises)
      .then(() => {
        setTimeout(() => {
          setRows((oldRows) => oldRows.filter((row) => !selectedRows.includes(row.ma_id)));
          setSelectedRows([]);
          setLoading(false);
        }, 800);
      })
      .catch((err) => {
        console.error("Fehler beim Löschen:", err);
        setLoading(false);
      });
  };

  const handleExportCSV = () => {
    if (rows.length === 0) {
      alert(i18n._(msg`No employees to export.`));
      return;
    }

  // Localized CSV headers — identical to the employee import template, so the
  // exported file can be re-imported in any language.
  const headers = getEmployeeCsvHeaders(true);
  const keys = getEmployeeCsvKeys(true);

  // Convert rows to CSV format (mapped onto the canonical column keys)
  const csvRows = rows.map(row => {
    const valueByKey: Record<string, any> = {
      adressid: adrId || '', // Company ID
      MW: row.MW || '',
      Name: row.Name || '',
      vorname: row.vorname || '',
      email: row.email || '',
      dw1: row.dw1 || '',
      dw2: row.dw2 || '',
      dw3: row.dw3 || '',
      dw4: row.dw4 || '',
      fax: row.fax || '',
      bemerkung: row.bemerkung || '',
    };
    return keys.map(k => valueByKey[k]);
  });

  // Combine headers and data
  const csvContent = [
    headers.join(';'),
    ...csvRows.map(row => row.join(';'))
  ].join('\n');

  // Create blob and download
  const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
  const link = document.createElement('a');
  const url = URL.createObjectURL(blob);
  
  link.setAttribute('href', url);
  link.setAttribute('download', employeeExportFilename());
  link.style.visibility = 'hidden';
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
};

    const handleEditClick = (id: GridRowId) => () => {
      setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.Edit } });
    };

    const handleSaveClick = (id: GridRowId) => () => {
      //setLoading(true);
      setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.View } });
    };

    const handleDeleteClick = (id: GridRowId) => () => {
      if (!window.confirm(i18n._(msg`Delete this employee?`))) return;

      const row = rows.find((r) => r.ma_id === id);
      if (row && !row.isNew) {
        setLoading(true);
        const formData = new FormData();
        formData.append("maid", row.ma_id.toString());
        formData.append("delMA", "1");
        formData.append("_token", csrfToken);

        fetch("/contacts/saveEmp", {
          method: "POST",
          body: formData,
        })
          .then((res) => {
            if (!res.ok) throw new Error("Löschen fehlgeschlagen");
            setTimeout(() => {
              setRows(rows.filter((row) => row.ma_id !== id));
              setLoading(false);
            }, 800);
          })
          .catch((err) => {
            console.error("Fehler beim Löschen:", err);
            setLoading(false);
          });
      } else {
        setRows(rows.filter((row) => row.ma_id !== id));
      }
    };

    const handleCancelClick = (id: GridRowId) => () => {
      setRowModesModel({
        ...rowModesModel,
        [id]: { mode: GridRowModes.View, ignoreModifications: true },
      });

      const editedRow = rows.find((row) => row.ma_id === id);
      if (editedRow?.isNew) {
        setRows(rows.filter((row) => row.ma_id !== id));
      }
    };

    const processRowUpdate = (newRow: GridRowModel) => {
      const updatedRow = { ...newRow, isNew: false } as MitarbeiterRow;

      if (!validateEmployer(updatedRow)) {
        // ✅ Throw an error instead of setting edit mode manually
        // This prevents the infinite loop
        throw new Error('Validation failed');
      }

      // ✅ Set loading AFTER validation passes
      setLoading(true);

      const formData = new FormData();
      if (newRow.isNew) {
        // Adding new employee
        formData.append("ma_MW", updatedRow.MW);
        formData.append("ma_name", updatedRow.Name);
        formData.append("ma_vorname", updatedRow.vorname);
        formData.append("ma_bemerkung", updatedRow.bemerkung);
        formData.append("ma_dw1", updatedRow.dw1);
        formData.append("ma_dw2", updatedRow.dw2 || "");
        formData.append("ma_dw3", updatedRow.dw3 || "");
        formData.append("ma_dw4", updatedRow.dw4 || "");
        formData.append("ma_email", updatedRow.email);
        formData.append("ma_fax", updatedRow.fax);
        formData.append("_token", csrfToken);
        formData.append("id", adrId?.toString() || "");
      } else {
        // Updating existing employee
        formData.append("maid", updatedRow.ma_id.toString());
        formData.append("id", adrId?.toString() || "");
        formData.append("ma_MW", updatedRow.MW);
        formData.append("ma_name", updatedRow.Name);
        formData.append("ma_vorname", updatedRow.vorname);
        formData.append("ma_bemerkung", updatedRow.bemerkung);
        formData.append("ma_dw1", updatedRow.dw1);
        formData.append("ma_dw2", updatedRow.dw2 || "");
        formData.append("ma_dw3", updatedRow.dw3 || "");
        formData.append("ma_dw4", updatedRow.dw4 || "");
        formData.append("ma_email", updatedRow.email);
        formData.append("ma_fax", updatedRow.fax);
        formData.append("_token", csrfToken);
      }

      fetch("/contacts/saveEmp", {
        method: "POST",
        body: formData,
      })
        .then((res) => {
          if (!res.ok) throw new Error("Speichern fehlgeschlagen");
          return res.json();
        })
        .then(() => {
          console.log("Mitarbeiter gespeichert");
          setTimeout(() => {
            fetchEmployers();
            setLoading(false);
          }, 800);
        })
        .catch((err) => {
          console.error("Fehler beim Speichern:", err);
          setLoading(false);
        });

      setRows(
        rows.map((row) => (row.ma_id === newRow.ma_id ? updatedRow : row))
      );
      return updatedRow;
    };

    const handleRowModesModelChange = (newRowModesModel: GridRowModesModel) => {
      setRowModesModel(newRowModesModel);
    };

    const handleRowEditStop: GridEventListener<"rowEditStop"> = (
      params,
      event
    ) => {
      if (params.reason === GridRowEditStopReasons.rowFocusOut) {
        event.defaultMuiPrevented = true;
      }
    };

    const handleShowUser = (maId: number) => {
      window.location.href = `/contacts/getusr/${maId}`;
    };

    const columns: GridColDef[] = [

      {
        field: "checkbox",
        headerName: "",
        width: 70,
        sortable: false,
        filterable: false,
        disableColumnMenu: true,
        renderHeader: () => (
          <Checkbox
            checked={
              selectedRows.length > 0 && selectedRows.length === rows.length
            }
            indeterminate={
              selectedRows.length > 0 && selectedRows.length < rows.length
            }
            onChange={(e) => {
              if (e.target.checked) {
                setSelectedRows(rows.map((r) => r.ma_id));
              } else {
                setSelectedRows([]);
              }
            }}
          />
        ),
        renderCell: (params) => (
          <Checkbox
            checked={selectedRows.includes(params.row.ma_id)}
            onChange={(e) => {
              if (e.target.checked) {
                setSelectedRows([...selectedRows, params.row.ma_id]);
              } else {
                setSelectedRows(
                  selectedRows.filter((id) => id !== params.row.ma_id)
                );
              }
            }}
          />
        ),
      },
      {
        field: "MW",
        headerName: i18n._(msg`Salutation`),
        width: 100,
        editable: true,
        type: 'singleSelect',              // changetoselectdropdown
        valueOptions: ['Herr', 'Frau'],    // follow DB options for
      },
      {
        field: "vorname",
        headerName: i18n._(msg`First name`),
        width: 150,
        editable: true,
      },
      {
        field: "Name",
        headerName: i18n._(msg`Last name`),
        width: 150,
        editable: true,
      },
      {
        field: "bemerkung",
        headerName: i18n._(msg`Note`),
        // width: 200,
        flex: 1,
        editable: true,
      },
      {
        field: "telefon",
        headerName: i18n._(msg`Phone`),
        width: 200,
        editable: true,
        renderCell: (params) => {
          const phones = [
            params.row.dw1,
            params.row.dw2,
            params.row.dw3,
            params.row.dw4,
          ].filter(Boolean);

          return (
            <Box sx={{ display: "flex", flexDirection: "column", py: 1 }}>
              {phones.map((phone, idx) => (
                <Box key={idx} sx={{ fontSize: "0.875rem" }}>
                  {phone}
                </Box>
              ))}
            </Box>
          );
        },
        renderEditCell: (params) => {
          const rowId = params.row.ma_id;
          const count = phoneFieldCounts[rowId] || 1;

          return (
            <Box sx={{ display: "flex", flexDirection: "column", gap: 0.5, py: 1, width: '100%' }}>
              {[...Array(count)].map((_, idx) => {
                const field = `dw${idx + 1}` as keyof Employer;
                return (
                  <TextField
                    key={idx}
                    size="small"
                    value={params.row[field] || ""}
                    onChange={(e) => {
                      const newRow = { ...params.row, [field]: e.target.value };
                      setRows((oldRows) =>
                        oldRows.map((row) =>
                          row.ma_id === rowId ? newRow : row
                        )
                      );
                    }}
                    placeholder={i18n._(msg`Phone ${idx + 1}`)}
                    fullWidth
                  />
                );
              })}
              {count < 4 && (
                <IconButton
                  size="small"
                  onClick={() => {
                    setPhoneFieldCounts((prev) => ({
                      ...prev,
                      [rowId]: Math.min((prev[rowId] || 1) + 1, 4),
                    }));
                  }}
                  sx={{ alignSelf: "flex-start" }}
                >
                  <AddIcon fontSize="small" />
                </IconButton>
              )}
            </Box>
          );
        },
      },
      {
        field: "email",
        headerName: i18n._(msg`Email`),
        width: 200,
        editable: true,
        renderCell: (params) =>
          params.value ? (
            <Link href={`mailto:${params.value}`} underline="hover">
              {params.value}
            </Link>
          ) : null,
      },
      {
        field: "fax",
        headerName: i18n._(msg`Fax`),
        width: 150,
        editable: true,
      },
      {
        field: "actions",
        type: "actions",
        headerName: i18n._(msg`Actions`),
        width: 100,
        cellClassName: "actions",
        getActions: ({ id }) => {
          const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit;

          if (isInEditMode) {
            return [
              <GridActionsCellItem
                icon={<SaveIcon />}
                label={i18n._(msg`Save`)}
                onClick={handleSaveClick(id)}
                color="primary"
              />,
              <GridActionsCellItem
                icon={<CancelIcon />}
                label={i18n._(msg`Cancel`)}
                onClick={handleCancelClick(id)}
                color="inherit"
              />,
            ];
          }

          return [
            <GridActionsCellItem
              icon={<VisibilityIcon />}
              label={i18n._(msg`View`)}
              onClick={() => handleShowUser(id as number)}
              color="inherit"
            />,
            <GridActionsCellItem
              icon={<EditIcon />}
              label={i18n._(msg`Edit`)}
              onClick={handleEditClick(id)}
              color="inherit"
            />,
            <GridActionsCellItem
              icon={<DeleteIcon />}
              label={i18n._(msg`Delete`)}
              onClick={handleDeleteClick(id)}
              color="inherit"
            />,
          ];
        },
      },
    ];

    return (
      <Box sx={{ width: "100%", height: 600 }}>
        {/*  Action Buttons */}
        <Box sx={{ mb: 2, display: "flex", justifyContent: "flex-end", gap: 2 }}>
          <Button
            variant="outlined"
            color="error"
            startIcon={<DeleteIcon />}
            onClick={handleDeleteSelected}
            disabled={selectedRows.length === 0}
            sx={{ textTransform: 'none' }}
          >
            <Trans>Delete employees</Trans>
          </Button>
          <Button
            variant="outlined"
            startIcon={<DownloadIcon/>}
            sx={{ textTransform: 'none' }}
            onClick={handleExportCSV}
          >
            <Trans>Export as .CSV</Trans>
          </Button>
          <Button
            variant="contained"
            startIcon={<AddIcon />}
            onClick={handleAddMitarbeiter}
            sx={{ textTransform: 'none' }}
          >
            <Trans>Add employee</Trans>
          </Button>
        </Box>

        {/* DataGrid */}
        <DataGrid
          rows={rows}
          columns={columns}
          getRowId={(row) => row.ma_id}
          editMode="row"
          rowModesModel={rowModesModel}
          onRowModesModelChange={handleRowModesModelChange}
          onRowEditStop={handleRowEditStop}
          processRowUpdate={processRowUpdate}
          onProcessRowUpdateError={(error) => {
            console.log('Validation error:', error);
          }}
          checkboxSelection={false}
          disableRowSelectionOnClick
          loading={loading}
          getRowHeight={(params) => {
            const rowId = params.id;
            const isInEditMode = rowModesModel[rowId]?.mode === GridRowModes.Edit;

            if (isInEditMode) {
              const phoneCount = phoneFieldCounts[rowId] || 1;
              return Math.max(80, 40 + phoneCount * 56);
            }

            const row = params.model as MitarbeiterRow;
            const phones = [row.dw1, row.dw2, row.dw3, row.dw4].filter(Boolean);
            return Math.max(80, 40 + phones.length * 24);
          }}
          sx={{
            "& .MuiDataGrid-cell": {
              alignItems: "center",
            },
          }}
          // ✅ Add custom empty state overlay
          slots={{
            noRowsOverlay: () => (
              <Box
                sx={{
                  display: 'flex',
                  flexDirection: 'column',
                  alignItems: 'center',
                  justifyContent: 'center',
                  height: '100%',
                  gap: 2,
                }}
              >
                <Typography variant="h6" color="text.secondary">
                  <Trans>No employees</Trans>
                </Typography>
                <Typography variant="body2" color="text.secondary">
                  <Trans>Click "Add employee" to add a new employee</Trans>
                </Typography>
              </Box>
            ),
          }}
        />
      </Box>
    );
  };

  export default MitarbeiterTab;