'use client';

import { useState, useEffect, useRef } from 'react';
import { useMediaQuery } from 'react-responsive';
import Image from 'next/image';

import { updateAmpelkarteEWS } from '@/redux/ampelkarteEWSSlice';
import { updateResourcesEWS } from '@/redux/resourcesEWSSlice';
import { updateCadastralData } from '@/redux/cadastreSlice';
import { updateComputationResultEWS } from '@/redux/computationsEWSSlice';
import { useAppSelector, useAppDispatch } from '@/redux/hooks';

import { initializeInfoPanelHandlers } from './potenzialkarte';
import { TableAmpelkarteEWS } from '@/app/ews/table-ampelkarte-ews';
import Collapsible from '@/app/components/collapsible';
import Footer from '@/app/components/footer';
import Warning from '@/app/components/warning';
import Success from '@/app/components/success';

import { textTemplates } from '@/app/config/config';

import print from '@/app/utils/print';

const tableDataCSS = 'w-full break-words border-b border-solid border-gray-300';

export default function Panel() {
  const image = useRef<HTMLImageElement>(null);
  const image_bal = useRef<HTMLImageElement>(null);
  const image_borefield = useRef<HTMLImageElement>(null);

  const innerRef = useRef<HTMLDivElement | null>(null);

  const [address, setAddress] = useState<string[]>([]);
  const [closenessWarning, setClosenessWarning] = useState<boolean>(false);
  const [outsideWarning, setOutsideWarning] = useState<boolean>(false);
  const [scaleWarning, setScaleWarning] = useState<boolean>(true);
  const [opened, setOpened] = useState<boolean>(true);

  const ampelkarte: any = useAppSelector((store) => store.ampelkarteEWS.value);
  const resources: any = useAppSelector((store) => store.resourcesEWS.value);
  const cadastralData: any = useAppSelector((store) => store.cadastre.value);
  const computationResult: any = useAppSelector((store) => store.computationsEWS.value);
  const screenshot: any = useAppSelector((store) => store.screenshot.value);

  const dispatch = useAppDispatch();

  const isTablet = useMediaQuery({ maxWidth: 1180 });

  // initialize query handlers
  useEffect(() => {
    dispatch(updateAmpelkarteEWS([]));
    dispatch(updateResourcesEWS([]));
    dispatch(updateCadastralData({}));
    dispatch(updateComputationResultEWS({}));
    initializeInfoPanelHandlers(setAddress, setClosenessWarning, setOutsideWarning, setScaleWarning);

    return () => {
      setAddress([]);
      dispatch(updateAmpelkarteEWS([]));
      dispatch(updateResourcesEWS([]));
      dispatch(updateCadastralData({}));
      dispatch(updateComputationResultEWS({}));
    };
  }, [dispatch, isTablet]);

  // print pdf report
  const clickHandler = () => {
    print(
      true,
      true,
      Object.keys(computationResult).length > 0,
      screenshot,
      image_bal,
      image,
      Object.keys(cadastralData).length > 0,
      closenessWarning || outsideWarning ? true : false,
      image_borefield,
      computationResult.calculationMode,
      'EWS',
      Object.keys(resources).length > 0
    );
  };

  // format values
  const formatEWS = (layerId: number, layerName: string, value: string) => {
    if (value !== 'NoData') {
      if ([0, 1, 2, 4, 5, 6].includes(layerId)) {
        value = parseFloat(value).toFixed(1);
      } else {
        value = parseFloat(value).toFixed(0);
      }
      return (textTemplates as any)[layerId][0] + value + (textTemplates as any)[layerId][1];
    } else {
      return layerName + ': keine Daten';
    }
  };

  const handleClick = () => {
    setOpened(!opened);
    if (innerRef && innerRef.current) {
      innerRef.current.classList.toggle('hidden');
    }
  };

  return (
    <div
      className={`absolute top-4 right-4 w-full md:w-1/3 xl:w-1/4 pl-8 md:pl-0 ${
        opened && isTablet ? 'bottom-4' : ''
      } ${opened && Object.keys(computationResult).length > 1 ? 'bottom-4' : ''}`}
    >
      <div
        onClick={handleClick}
        className="bg-gray-700 text-white cursor-pointer p-4 w-full border-0 hover:bg-gray-500 h-12 items-center justify-between text-sm xl:text-base"
      >
        Berechnungsergebnis <span className="float-right">{opened ? '-' : '+'}</span>
      </div>
      <div
        className={`relative h-[calc(100%-3rem)] px-2 xl:px-4 py-4 overflow-y-auto bg-white text-sm z-20 ${
          opened ? '' : 'hidden'
        }`}
        ref={innerRef}
      >
        <div className="flex justify-end">
          <button
            className={
              ampelkarte && ampelkarte.length > 0
                ? 'text-white bg-red-700 p-2 border-0 outline-none cursor-pointer hover:bg-red-400 transition-colors mb-2 w-1/2 text-sm xl:text-base'
                : 'text-white bg-red-500 p-2 border-0 outline-none cursor-not-allowed hover:bg-red-200 transition-colors mb-2 w-1/2 text-sm xl:text-base'
            }
            onClick={clickHandler}
          >
            PDF erstellen
          </button>
        </div>
        {Object.keys(cadastralData).length > 0 ? (
          <table id="cadastral-data-table" className="table-fixed w-full p-2">
            <tbody>
              <tr>
                <td>
                  Katastralgemeinde: {cadastralData.KG}
                  <br></br>
                  Grundstücksnummer: {cadastralData.GNR}
                </td>
              </tr>
            </tbody>
          </table>
        ) : null}
        {address && address.length > 0 ? (
          <table id="address-table" className="table-fixed w-full p-2">
            <tbody>
              <tr>
                <td>{address[0]}</td>
              </tr>
              <tr>
                <td>
                  {address[1]} {address[3]}
                </td>
              </tr>
            </tbody>
          </table>
        ) : null}
        {Object.keys(cadastralData).length > 0 ? (
          <div className="grid grid-cols-3 p-2">
            <span className="border border-solid border-blue-700 my-auto mr-2"></span>
            <span className="col-span-2">Grundstücksgrenze</span>
            <span className="border border-solid border-teal-600 my-auto mr-2"></span>
            <span className="col-span-2">2,5-Meter-Abstand zur Grundstücksgrenze</span>
          </div>
        ) : null}
        {scaleWarning ? (
          Object.keys(cadastralData).length === 0 ? (
            <div className="py-2">
              <Warning>Bitte zoomen Sie hinein um Ihr gewünschtes Grundstück durch Mausklick auszuwählen.</Warning>
            </div>
          ) : (
            <div className="py-2">
              <Warning>Bitte zoomen Sie hinein, wenn Sie ein anderes Grundstück auswählen möchten.</Warning>
            </div>
          )
        ) : Object.keys(cadastralData).length === 0 ? (
          <div className="py-2">
            <Success>Sie können jetzt Ihr Grundstück auswählen.</Success>
          </div>
        ) : (
          <div className="py-2">
            <Success>Sie können jetzt die Berechnungen starten oder ein anderes Grundstück auswählen.</Success>
          </div>
        )}
        {closenessWarning || outsideWarning ? (
          <table id="warnings-table" className="table-fixed w-full mb-2">
            <tbody>
              <tr>
                <td>
                  {closenessWarning ? (
                    <Warning>Achtung: Mindestens ein Punkt liegt näher als fünf Meter zu einem anderen Punkt!</Warning>
                  ) : null}
                </td>
              </tr>
              <tr>
                <td>
                  {outsideWarning ? (
                    <Warning>Achtung: Mindestens ein Punkt liegt außerhalb der zugelassenen Grenzen!</Warning>
                  ) : null}
                </td>
              </tr>
            </tbody>
          </table>
        ) : null}
        {ampelkarte && ampelkarte.length > 0 ? <TableAmpelkarteEWS results={ampelkarte}></TableAmpelkarteEWS> : null}
        {Object.keys(computationResult).includes('error') ? (
          <Collapsible title="Berechnungsergebnisse" open={true}>
            <table id="calculations-output-table" className="table-fixed w-full p-2">
              <thead>
                <tr>
                  <td></td>
                </tr>
              </thead>
              <tbody>
                <tr>
                  <th>{computationResult.error}</th>
                </tr>
              </tbody>
            </table>
            <div></div>
          </Collapsible>
        ) : null}
        {resources && resources.length > 0 ? (
          <div className="hidden">
            <Collapsible title="Ressourcen" open={false}>
              <table id="resources-table" className="table-fixed w-full p-2">
                <thead>
                  <tr>
                    <td></td>
                  </tr>
                </thead>
                <tbody>
                  <tr>
                    <th>Ressourcen für vordefinierte Erdwärmesondenanlage</th>
                  </tr>
                  {resources.slice(3, 7).map((result: any) => {
                    return (
                      <tr key={result.layerId}>
                        <td className={tableDataCSS}>
                          {formatEWS(
                            result.layerId,
                            result.layerName,
                            result.feature.attributes['Classify.Pixel Value']
                          )}
                        </td>
                      </tr>
                    );
                  })}
                  <tr>
                    <th>Standortabhängige Parameter</th>
                  </tr>
                  {resources.slice(0, 3).map((result: any) => {
                    return (
                      <tr key={result.layerId}>
                        <td className={tableDataCSS}>
                          {formatEWS(
                            result.layerId,
                            result.layerName,
                            result.feature.attributes['Classify.Pixel Value']
                          )}
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </Collapsible>
          </div>
        ) : null}
        {Object.keys(computationResult).length > 1 ? (
          <Collapsible title="Berechnungsergebnisse" open={true}>
            <table id="calculations-input-table" className="table-fixed w-full p-2">
              <thead>
                <tr>
                  <td></td>
                </tr>
              </thead>
              <tbody>
                <tr>
                  <th>Berechnungsvorgaben</th>
                </tr>
                <tr>
                  {computationResult.calculationMode === 'norm' ? (
                    <td>
                      Es wurde keine Betriebsfunktion vom Benutzer vorgeben. Die Berechnung der möglichen Leistung des
                      gewählten Sondenfelds erfolgt mit Norm-Jahresbetriebsstunden für Heizen und Kühlen am Standort
                      eines typischen Wohngebäudes. Die Berechnung berücksichtigt zudem Untergrunddaten, fixe
                      Sondenparameter und Temperaturgrenzen für die Fluidtemperatur in der Sonde. Ergebnisse sind die
                      maximal erzielbare Leistung (kW) und Energiemenge (MWh/a) bei einem Betrieb von 20 Jahren.
                    </td>
                  ) : (
                    <td>
                      Die Berechnung erfolgt für das gewählte Sondenfeld mit der benutzerdefinierten Betriebsfunktion,
                      bestehend aus den Jahresbetriebsstunden und dem Leistungsverhältnis zwischen Heizen und Kühlen.
                      Die Berechnung berücksichtigt zudem Untergrunddaten, fixe Sondenparameter und Temperaturgrenzen
                      für die Fluidtemperatur in der Sonde. Ergebnisse sind die maximal erzielbare Leistung (kW) und
                      Energiemenge (MWh/a) bei einem Betrieb von 20 Jahren.
                    </td>
                  )}
                </tr>
                <tr>
                  <th>Benutzereingabe</th>
                </tr>
                <tr>
                  <td>Sondenanzahl: {computationResult.points}</td>
                </tr>
                {computationResult.meanBoreholeSpacing > 0 && (
                  <tr>
                    <td>Durchschnittlicher Sondenabstand: {computationResult.meanBoreholeSpacing} m</td>
                  </tr>
                )}
                <tr>
                  <td>Sondentiefe: {computationResult.boreDepth} m</td>
                </tr>
                {computationResult.calculationMode === 'user' && (
                  <>
                    <tr>
                      <td>Jahresbetriebsstunden Heizen: {computationResult.BS_HZ} h</td>
                    </tr>
                    <tr>
                      <td>Jahresbetriebsstunden Kühlen: {computationResult.BS_KL} h</td>
                    </tr>
                    <tr>
                      <td>Heizleistung Gebäude: {computationResult.P_HZ} kW</td>
                    </tr>
                    <tr>
                      <td>Kühlleistung Gebäude: {computationResult.P_KL} kW</td>
                    </tr>
                  </>
                )}
                <tr>
                  <td>Vorlauftemperatur Heizung: {computationResult.T_radiator} °C</td>
                </tr>
                <tr>
                  <th>Standortabhängige Parameter</th>
                </tr>
                {computationResult.calculationMode === 'norm' && (
                  <>
                    <tr>
                      <td>Norm-Jahresbetriebsstunden Heizen: {computationResult.BS_HZ_Norm} h</td>
                    </tr>
                    <tr>
                      <td>Norm-Jahresbetriebsstunden Kühlen: {computationResult.BS_KL_Norm} h</td>
                    </tr>
                  </>
                )}
                {resources && resources.length > 0 && computationResult && computationResult.GTcalc && (
                  <>
                    <tr>
                      <td>
                        Wärmeleitfähigkeit:{' '}
                        {parseFloat(resources[2].feature.attributes['Classify.Pixel Value']).toFixed(1)} W/m/K
                      </td>
                    </tr>
                    <tr>
                      <td>Untergrundtemperatur: {computationResult.GTcalc.toFixed(1)} °C</td>
                    </tr>
                  </>
                )}
                {computationResult.points >= 10 &&
                  (computationResult.Efactor_user > 1.1 || computationResult.Efactor_user < 0.9) && (
                    <tr>
                      <td>
                        Hinweis: Größere Sondenfelder sollten mit einer möglichst ausgeglichenen Jahresenergiebilanz
                        zwischen Heizen und Kühlen betrieben werden. Dadurch beeinflussen sich die Sonden gegenseitig
                        kaum und der Sondenabstand kann auf ungefähr 5 Meter reduziert werden. Dies ermöglicht eine
                        optimale thermische Nutzung des Untergrunds und es können höhere Leistungen erreicht werden.
                        Überlegen Sie eine Verbesserung der Energiebilanz zwischen Heizen und Kühlen!
                      </td>
                    </tr>
                  )}
              </tbody>
            </table>
            <div></div>
            <Image
              src={computationResult.imagehashSondenfeld}
              alt="Grafik mit Sondenfeld"
              width={384}
              height={288}
              ref={image_borefield}
              className="mx-auto"
            ></Image>
            <table id="calculations-output-table" className="table-fixed w-full p-2">
              <tbody>
                <tr>
                  <th>
                    {computationResult.calculationMode === 'norm'
                      ? 'Berechnungsergebnisse für den Normbetrieb'
                      : 'Berechnungsergebnisse für den benutzerdefinierten Betrieb '}
                  </th>
                </tr>
                <tr>
                  <th>
                    Heizbetrieb mit{' '}
                    {computationResult.BS_HZ > 0 ? computationResult.BS_HZ : computationResult.BS_HZ_Norm} h/a
                  </th>
                </tr>
                <tr>
                  <td>Wärmeentzugsleistung aus Erdwärmesonden: {computationResult.P_HZ_user.toFixed(1)} kW</td>
                </tr>
                <tr>
                  <td>
                    + Elektrische Leistung Wärmepumpe (bei COP {computationResult.COP.toFixed(1)}):{' '}
                    {computationResult.Pel_heatpump_user.toFixed(1)} kW
                  </td>
                </tr>
                <tr>
                  <td>= Heizleistung Erdwärmeanlage: {computationResult.heizleistung.toFixed(1)} kW</td>
                </tr>
                <tr>
                  <td>Jährlicher Wärmeentzug aus Erdwärmesonden: {computationResult.E_HZ_user.toFixed(1)} MWh/a</td>
                </tr>
                <tr>
                  <td>
                    + Strombedarf Wärmepumpe (bei JAZ {computationResult.SCOP.toFixed(1)}):{' '}
                    {computationResult.Eel_heatpump_user.toFixed(1)} MWh/a
                  </td>
                </tr>
                <tr>
                  <td>= Heizarbeit Erdwärmeanlage: {computationResult.heizarbeit.toFixed(1)} MWh/a</td>
                </tr>
                <tr>
                  <th>
                    Kühlbetrieb mit{' '}
                    {computationResult.BS_KL > 0 ? computationResult.BS_KL : computationResult.BS_KL_Norm} h/a
                  </th>
                </tr>
                <tr>
                  <td>Wärmeeintragsleistung in Erdwärmesonden: {computationResult.P_KL_user.toFixed(1)} kW</td>
                </tr>
                <tr>
                  <td>
                    - Elektrische Leistung Wärmepumpe (bei EER {computationResult.EER.toFixed(1)}):{' '}
                    {computationResult.Pel_chiller_user.toFixed(1)} kW
                  </td>
                </tr>
                <tr>
                  <td>= Kühlleistung Erdwärmeanlage: {computationResult.kuehlleistung.toFixed(1)} kW</td>
                </tr>
                <tr>
                  <td>Jährlicher Wärmeeintrag in Erdwärmesonde: {computationResult.E_KL_user.toFixed(1)} MWh/a</td>
                </tr>
                <tr>
                  <td>
                    - Strombedarf Wärmepumpe (bei SEER {computationResult.SEER.toFixed(1)}
                    ): {computationResult.Eel_chiller_user.toFixed(1)} MWh/a
                  </td>
                </tr>
                <tr>
                  <td>= Kühlarbeit Erdwärmeanlage: {computationResult.kuehlarbeit.toFixed(1)} MWh/a</td>
                </tr>
                {computationResult.cover > 0 && (
                  <tr>
                    <td>Deckungsgrad gesamt: {computationResult.cover} %</td>
                  </tr>
                )}
                {computationResult.balanced === 0 && (
                  <tr>
                    <td>
                      Ihre Energie- und Leistungsvorgaben des Gebäudes für Heizen und Kühlen bewirken eine ausgeglichene
                      Betriebsweise im Erdsondenfeld. Die Auslegung ist optimal für den saisonalen Speicherbetrieb
                      geeignet.
                    </td>
                  </tr>
                )}
              </tbody>
            </table>
            <div></div>
            <Image
              src={computationResult.imagehash}
              alt="Grafik mit Berechnungsergebnissen"
              ref={image}
              width={384}
              height={288}
              className="mx-auto"
            ></Image>
            <div></div>
          </Collapsible>
        ) : null}
        {Object.keys(computationResult).length > 1 && computationResult.balanced === 1 ? (
          <Collapsible title="Berechnungsergebnisse für den saisonalen Speicherbetrieb" open={true}>
            <table id="calculations-bal-output-table" className="table-fixed w-full p-2">
              <thead>
                <tr>
                  <td></td>
                </tr>
              </thead>
              <tbody>
                <tr>
                  <td>
                    Die Berechnung erfolgt für das gewählte Sondenfeld im saisonalen Speicherbetrieb. Die folgenden
                    Ergebnisse beziehen sich auf eine automatisch angepasste Betriebsweise, wobei das Sondenfeld über
                    das Jahr gesehen gleich stark be- und entladen wird.{' '}
                    {computationResult.Efactor_user >= 1 &&
                      `Um eine ausgeglichene Betriebsweise zu erreichen ist eine zusätzliche Wärmequelle notwendig. Die Zusatzquelle (Solar, Luft, Abwärme, etc.) kann außerhalb der Heizsaison betrieben werden und gleicht die Jahresenergiebilanz der Erdwärmesonden aus. Alternativ zur Zusatzquelle kann auch eine Reduktion der vorgegebenen Heizleistung mit klassischen Wärmequellen (Fernwärme, Biomasse, etc.) in Betracht gezogen werden. Versuchen Sie auch eine manuelle Anpassung der Leistungsvorgabe!`}
                    {computationResult.Efactor_user < 1 &&
                      `Um eine ausgeglichene Betriebsweise zu erreichen ist eine zusätzliche Wärmesenke notwendig. Als Zusatzsenke bietet sich eine Wärmeversorgung benachbarter Objekte an, wodurch die Jahresenergiebilanz in den Erdwärmesonden ausgeglichen werden kann.`}
                  </td>
                </tr>
                {computationResult.meanBoreholeSpacing > 5 && (
                  <>
                    <tr>
                      <td>
                        Hinweis: Im saisonalen Speicherbetrieb kann der Sondenabstand auf ungefähr fünf Meter reduziert
                        werden ohne dass sich die einzelnen Erdwärmesonden nennenswert gegenseitig beeinflussen. Somit
                        kann der Flächenbedarf ohne signifikante Einbußen der Sondenleistung reduziert werden. Versuchen
                        Sie eine Reduktion des Sondenabstands!
                      </td>
                    </tr>
                  </>
                )}
              </tbody>
              <tbody>
                <tr>
                  <th>Berechnungsergebnisse</th>
                </tr>
                <tr>
                  <th>
                    Heizbetrieb {computationResult.Efactor_user < 1 && 'und Zusatzsenke'} mit{' '}
                    {computationResult.BS_HZ_bal} h/a
                  </th>
                </tr>
                <tr>
                  <td>Wärmeentzugsleistung aus Erdwärmesonden: {computationResult.P_HZ_bal.toFixed(1)} kW</td>
                </tr>
                <tr>
                  <td>
                    + Elektrische Leistung Wärmepumpe (bei COP {computationResult.COP_bal.toFixed(1)}):{' '}
                    {computationResult.Pel_heatpump_bal.toFixed(1)} kW
                  </td>
                </tr>
                <tr>
                  <td>= Heizleistung Erdwärmeanlage: {computationResult.heizleistungBal.toFixed(1)} kW</td>
                </tr>
                <tr>
                  <td>Jährlicher Wärmeentzug aus Erdwärmesonden: {computationResult.E_HZ_bal.toFixed(1)} MWh/a</td>
                </tr>
                <tr>
                  <td>
                    + Strombedarf Wärmepumpe (bei JAZ {computationResult.SCOP_bal.toFixed(1)}):{' '}
                    {computationResult.Eel_heatpump_bal.toFixed(1)} MWh/a
                  </td>
                </tr>
                <tr>
                  <td>= Heizarbeit Erdwärmeanlage: {computationResult.heizarbeitBal.toFixed(1)} MWh/a</td>
                </tr>
                <tr>
                  <th>
                    Kühlbetrieb {computationResult.Efactor_user >= 1 && 'und Zusatzquelle'} mit{' '}
                    {computationResult.BS_KL_bal} h/a
                  </th>
                </tr>
                <tr>
                  <td>Wärmeeintragsleistung in Erdwärmesonden: {computationResult.P_KL_bal.toFixed(1)} kW</td>
                </tr>
                <tr>
                  <td>
                    - Elektrische Leistung Wärmepumpe (bei EER {computationResult.EER_bal.toFixed(1)}):{' '}
                    {computationResult.Pel_chiller_bal.toFixed(1)} kW
                  </td>
                </tr>
                <tr>
                  <td>= Kühlleistung Erdwärmeanlage: {computationResult.kuehlleistungBal.toFixed(1)} kW</td>
                </tr>
                <tr>
                  <td>Jährlicher Wärmeeintrag in Erdwärmesonden: {computationResult.E_KL_bal.toFixed(1)} MWh/a</td>
                </tr>
                <tr>
                  <td>
                    - Strombedarf Wärmepumpe (bei SEER {computationResult.SEER_bal.toFixed(1)}):{' '}
                    {computationResult.Eel_chiller_bal.toFixed(1)} MWh/a
                  </td>
                </tr>
                <tr>
                  <td>= Kühlarbeit Erdwärmeanlage: {computationResult.kuehlarbeitBal.toFixed(1)} MWh/a</td>
                </tr>
                {computationResult.cover > 0 && (
                  <tr>
                    <td>Deckungsgrad: {computationResult.cover_bal} %</td>
                  </tr>
                )}
                {computationResult.Efactor_user >= 1 ? (
                  <tr>
                    <td>
                      Bei einer ausgeglichenen Betriebsweise mit einer zusätzlichen Wärmequelle kann die Heizarbeit um{' '}
                      {computationResult.cover_rise.toFixed(1)} % gesteigert werden.
                    </td>
                  </tr>
                ) : (
                  <tr>
                    <td>
                      Bei einer ausgeglichenen Betriebsweise mit einer zusätzlichen Wärmesenke kann die Kühlarbeit um{' '}
                      {computationResult.cover_rise.toFixed(1)} % gesteigert werden.
                    </td>
                  </tr>
                )}
              </tbody>
            </table>
            <div></div>
            <Image
              src={computationResult.imagehashBal}
              alt="Grafik mit bilanzierten Berechnungsergebnissen"
              ref={image_bal}
              width={384}
              height={288}
              className="mx-auto"
            ></Image>
            <div></div>
          </Collapsible>
        ) : null}
        <Footer></Footer>
      </div>
    </div>
  );
}
