import { mdiArrowLeft, mdiChartTimelineVariant, mdiPencil } from '@mdi/js';
import Head from 'next/head';
import React, { useEffect } from 'react';
import BaseButton from '../BaseButton';
import BaseButtons from '../BaseButtons';
import BaseIcon from '../BaseIcon';
import CardBox from '../CardBox';
import SectionMain from '../SectionMain';
import SectionTitleLineWithButton from '../SectionTitleLineWithButton';
import { getPageTitle } from '../../config';
import { useAppDispatch, useAppSelector } from '../../stores/hooks';
import { useRouter } from 'next/router';
import {
  emptyValue,
  formatPrimitiveValue,
  getChipEntries,
  getCollectionPreview,
  getMetricCards,
  getPrimaryTitle,
  getRecordEntries,
  getRecordSubtitle,
  getRelationLabel,
  getSummaryEntries,
  humanizeLabel,
  isRecordObject,
} from '../EntityPageUtils';

type Props = {
  singularLabel: string;
  pluralLabel: string;
  stateKey: string;
  recordKey: string;
  fetchRecord: any;
  listHref: string;
  editHref: (id: string | string[] | undefined) => string;
};

const getBadgeClassName = (value?: string | null) => {
  switch (String(value || '').toLowerCase()) {
    case 'active':
    case 'approved':
    case 'completed':
    case 'resolved':
    case 'settled':
    case 'paid':
    case 'enabled':
    case 'true':
      return 'border-emerald-200 bg-emerald-50 text-emerald-700';
    case 'submitted':
    case 'under_review':
    case 'in_progress':
    case 'validated':
    case 'partial':
    case 'draft':
      return 'border-blue-200 bg-blue-50 text-blue-700';
    case 'on_hold':
    case 'blocked':
    case 'follow_up_required':
    case 'disputed':
    case 'pending':
      return 'border-amber-200 bg-amber-50 text-amber-700';
    case 'critical':
    case 'high':
    case 'terminated':
    case 'cancelled':
    case 'closed':
    case 'disabled':
    case 'false':
      return 'border-red-200 bg-red-50 text-red-700';
    default:
      return 'border-slate-200 bg-slate-50 text-slate-700 dark:border-dark-700 dark:bg-dark-800 dark:text-slate-200';
  }
};

const StatusBadge = ({ value }: { value: any }) => (
  <span className={`rounded-full border px-2.5 py-1 text-xs font-semibold ${getBadgeClassName(value)}`}>{String(formatPrimitiveValue('status', value))}</span>
);

const DetailItem = ({ label, value }: { label: string; value: React.ReactNode }) => (
  <div className="rounded-xl border border-slate-200/80 bg-slate-50/70 p-4 dark:border-dark-700 dark:bg-dark-800/60">
    <p className="text-xs font-semibold uppercase tracking-[0.18em] text-slate-500 dark:text-slate-400">{label}</p>
    <div className="mt-2 text-sm leading-6 text-slate-900 dark:text-slate-100">{value || emptyValue}</div>
  </div>
);

const MetricCard = ({ label, value, note }: { label: string; value: string; note: string }) => (
  <div className="rounded-xl border border-slate-200/80 bg-slate-50/80 p-4 dark:border-dark-700 dark:bg-dark-800/60">
    <p className="text-xs font-semibold uppercase tracking-[0.18em] text-slate-500 dark:text-slate-400">{label}</p>
    <p className="mt-3 text-2xl font-semibold text-slate-900 dark:text-slate-100">{value}</p>
    <p className="mt-2 text-sm text-slate-600 dark:text-slate-300">{note}</p>
  </div>
);

const EntityRecordViewPage = ({ singularLabel, pluralLabel, stateKey, recordKey, fetchRecord, listHref, editHref }: Props) => {
  const router = useRouter();
  const dispatch = useAppDispatch();
  const { id } = router.query;
  const sliceState = useAppSelector((state) => (state as any)[stateKey]);
  const record = sliceState?.[recordKey];

  useEffect(() => {
    if (id) {
      dispatch(fetchRecord({ id }));
    }
  }, [dispatch, fetchRecord, id]);

  const recordTitle = getPrimaryTitle(record, `View ${singularLabel}`);
  const recordSubtitle = getRecordSubtitle(record, `${singularLabel} details`);
  const summaryEntries = getSummaryEntries(record, 8);
  const metricCards = getMetricCards(record);
  const chipEntries = getChipEntries(record);
  const { scalarEntries, relationEntries, collectionEntries } = getRecordEntries(record);
  const overviewEntries = summaryEntries;
  const detailEntries = scalarEntries.filter(([key]) => !overviewEntries.some(([entryKey]) => entryKey === key));

  return (
    <>
      <Head>
        <title>{getPageTitle(recordTitle)}</title>
      </Head>
      <SectionMain>
        <SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={recordTitle} main>
          <BaseButtons type="justify-start md:justify-end" className="w-full md:w-auto" noWrap>
            <BaseButton color="white" outline icon={mdiArrowLeft} label={`Back to ${pluralLabel.toLowerCase()}`} onClick={() => router.push(listHref)} />
            <BaseButton color="info" icon={mdiPencil} label={`Edit ${singularLabel.toLowerCase()}`} href={editHref(id)} />
          </BaseButtons>
        </SectionTitleLineWithButton>

        <div className="space-y-6">
          <CardBox>
            <div className="space-y-6">
              <div className="flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
                <div className="max-w-3xl">
                  <p className="text-xs font-semibold uppercase tracking-[0.2em] text-slate-500 dark:text-slate-400">{singularLabel} workspace</p>
                  <h2 className="mt-2 text-3xl font-semibold text-slate-900 dark:text-slate-100">{recordTitle}</h2>
                  <p className="mt-3 text-sm text-slate-600 dark:text-slate-300">{recordSubtitle}</p>
                </div>
                {chipEntries.length > 0 && (
                  <div className="flex flex-wrap gap-2">
                    {chipEntries.map(([key, value]) => (
                      <div key={key} className="flex items-center gap-2 rounded-full border border-slate-200 bg-white px-3 py-1 dark:border-dark-700 dark:bg-dark-900">
                        <span className="text-xs font-semibold uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400">{humanizeLabel(key)}</span>
                        <StatusBadge value={value} />
                      </div>
                    ))}
                  </div>
                )}
              </div>

              <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-4">
                {metricCards.map((metric) => (
                  <MetricCard key={metric.label} label={metric.label} value={metric.value} note={metric.note} />
                ))}
              </div>
            </div>
          </CardBox>

          {!isRecordObject(record) ? (
            <CardBox>
              <div className="rounded-xl border border-dashed border-slate-200 bg-slate-50/70 px-4 py-8 text-sm text-slate-600 dark:border-dark-700 dark:bg-dark-800/50 dark:text-slate-300">
                Loading {singularLabel.toLowerCase()} details or waiting for the record to become available.
              </div>
            </CardBox>
          ) : (
            <div className="grid gap-6 xl:grid-cols-[minmax(0,1fr)_360px]">
              <div className="space-y-6">
                <CardBox>
                  <div className="space-y-5">
                    <div>
                      <h3 className="text-lg font-semibold text-slate-900 dark:text-slate-100">Overview</h3>
                      <p className="mt-1 text-sm text-slate-600 dark:text-slate-300">Key information is grouped here for faster review and cleaner scanning.</p>
                    </div>
                    <div className="grid gap-4 md:grid-cols-2">
                      {overviewEntries.map(([key, value]) => (
                        <DetailItem key={key} label={humanizeLabel(key)} value={formatPrimitiveValue(key, value)} />
                      ))}
                    </div>
                  </div>
                </CardBox>

                {detailEntries.length > 0 && (
                  <CardBox>
                    <div className="space-y-5">
                      <div>
                        <h3 className="text-lg font-semibold text-slate-900 dark:text-slate-100">Extended details</h3>
                        <p className="mt-1 text-sm text-slate-600 dark:text-slate-300">Additional record content is still available, but presented in a cleaner structured layout.</p>
                      </div>
                      <div className="grid gap-4 md:grid-cols-2">
                        {detailEntries.map(([key, value]) => (
                          <DetailItem key={key} label={humanizeLabel(key)} value={formatPrimitiveValue(key, value)} />
                        ))}
                      </div>
                    </div>
                  </CardBox>
                )}

                {collectionEntries.map(([key, value]) => {
                  const items = Array.isArray(value) ? value : [];
                  const preview = getCollectionPreview(items);

                  return (
                    <CardBox key={key}>
                      <div className="space-y-5">
                        <div className="flex flex-wrap items-start justify-between gap-3">
                          <div>
                            <h3 className="text-lg font-semibold text-slate-900 dark:text-slate-100">{humanizeLabel(key)}</h3>
                            <p className="mt-1 text-sm text-slate-600 dark:text-slate-300">Related records are presented as compact cards instead of a raw data dump.</p>
                          </div>
                          <span className="rounded-full border border-slate-200 bg-slate-50 px-3 py-1 text-xs font-semibold uppercase tracking-[0.14em] text-slate-600 dark:border-dark-700 dark:bg-dark-800 dark:text-slate-300">
                            {items.length} records
                          </span>
                        </div>

                        {preview.length > 0 ? (
                          <div className="grid gap-4 md:grid-cols-2">
                            {preview.map((item) => (
                              <div key={item.key} className="rounded-xl border border-slate-200/80 bg-slate-50/70 p-4 dark:border-dark-700 dark:bg-dark-800/60">
                                <div className="flex items-start justify-between gap-3">
                                  <p className="font-semibold text-slate-900 dark:text-slate-100">{item.title}</p>
                                  <div className="rounded-lg border border-slate-200 bg-white p-2 text-slate-500 dark:border-dark-700 dark:bg-dark-900 dark:text-slate-300">
                                    <BaseIcon path={mdiChartTimelineVariant} size={18} />
                                  </div>
                                </div>
                                {item.details.length > 0 ? (
                                  <dl className="mt-4 space-y-3">
                                    {item.details.map((detail) => (
                                      <div key={`${item.key}-${detail.label}`}>
                                        <dt className="text-xs font-semibold uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400">{detail.label}</dt>
                                        <dd className="mt-1 text-sm text-slate-700 dark:text-slate-200">{detail.value || emptyValue}</dd>
                                      </div>
                                    ))}
                                  </dl>
                                ) : (
                                  <p className="mt-4 text-sm text-slate-600 dark:text-slate-300">No additional preview fields are available for this related record.</p>
                                )}
                              </div>
                            ))}
                          </div>
                        ) : (
                          <div className="rounded-xl border border-dashed border-slate-200 bg-slate-50/70 px-4 py-6 text-sm text-slate-600 dark:border-dark-700 dark:bg-dark-800/50 dark:text-slate-300">
                            No related records have been attached here yet.
                          </div>
                        )}
                      </div>
                    </CardBox>
                  );
                })}
              </div>

              <div className="space-y-6">
                <CardBox>
                  <div className="space-y-5">
                    <div>
                      <h3 className="text-lg font-semibold text-slate-900 dark:text-slate-100">Connected records</h3>
                      <p className="mt-1 text-sm text-slate-600 dark:text-slate-300">Direct linked records are summarized here so users can see context without parsing nested JSON-like sections.</p>
                    </div>
                    <div className="space-y-4">
                      {relationEntries.length > 0 ? (
                        relationEntries.map(([key, value]) => (
                          <div key={key} className="rounded-xl border border-slate-200/80 bg-slate-50/70 p-4 dark:border-dark-700 dark:bg-dark-800/60">
                            <p className="text-xs font-semibold uppercase tracking-[0.18em] text-slate-500 dark:text-slate-400">{humanizeLabel(key)}</p>
                            <div className="mt-2 text-sm font-medium text-slate-900 dark:text-slate-100">{getRelationLabel(value)}</div>
                          </div>
                        ))
                      ) : (
                        <div className="rounded-xl border border-dashed border-slate-200 bg-slate-50/70 px-4 py-6 text-sm text-slate-600 dark:border-dark-700 dark:bg-dark-800/50 dark:text-slate-300">
                          No linked records are available on this item yet.
                        </div>
                      )}
                    </div>
                  </div>
                </CardBox>
              </div>
            </div>
          )}
        </div>
      </SectionMain>
    </>
  );
};

export default EntityRecordViewPage;
