import * as React from 'react';
import { Document, Page, View, Text, Image, StyleSheet, Font } from '@react-pdf/renderer';
import type { DatasheetVoltageTable, KeyValueItem } from '../scripts/pdf/model/types';

// Standard built-in fonts are used.
Font.registerHyphenationCallback((word) => [word]);

const C = {
  navy: '#001a4d',
  navyDeep: '#000d26',
  green: '#4da612',
  greenLight: '#e8f5d8',
  white: '#FFFFFF',
  offWhite: '#f8f9fa',
  gray100: '#f3f4f6',
  gray200: '#e5e7eb',
  gray300: '#d1d5db',
  gray400: '#9ca3af',
  gray600: '#4b5563',
  gray900: '#111827',
};

const MARGIN = 56;

const styles = StyleSheet.create({
  page: {
    paddingHorizontal: MARGIN,
    paddingBottom: 80,
    paddingTop: 40,
    fontFamily: 'Helvetica',
    backgroundColor: C.white,
    color: C.gray900,
  },
  hero: { paddingBottom: 20, marginBottom: 10 },
  header: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    marginBottom: 16,
  },
  logoText: {
    fontSize: 22,
    fontWeight: 700,
    color: C.navyDeep,
    letterSpacing: 2,
    textTransform: 'uppercase',
  },
  docTitle: {
    fontSize: 8,
    fontWeight: 700,
    color: C.green,
    letterSpacing: 2,
    textTransform: 'uppercase',
  },
  productRow: { flexDirection: 'row', alignItems: 'center', gap: 20 },
  productInfoCol: { flex: 1, justifyContent: 'center' },
  productImageCol: {
    flex: 1,
    height: 120,
    justifyContent: 'center',
    alignItems: 'center',
    borderRadius: 4,
    borderWidth: 1,
    borderColor: C.gray200,
    backgroundColor: C.white,
    overflow: 'hidden',
  },
  productName: {
    fontSize: 24,
    fontWeight: 700,
    color: C.navyDeep,
    textTransform: 'uppercase',
    letterSpacing: -0.5,
  },
  productMeta: {
    fontSize: 10,
    color: C.gray600,
    fontWeight: 700,
    textTransform: 'uppercase',
    letterSpacing: 1,
    marginBottom: 2,
  },
  heroImage: { width: '100%', height: '100%', objectFit: 'contain' },
  noImage: { fontSize: 8, color: C.gray400, textAlign: 'center' },

  content: {},
  section: { marginBottom: 20 },
  sectionTitle: {
    fontSize: 8,
    fontWeight: 700,
    color: C.green,
    marginBottom: 6,
    textTransform: 'uppercase',
    letterSpacing: 1.5,
  },
  sectionAccent: {
    width: 30,
    height: 2,
    backgroundColor: C.green,
    marginBottom: 8,
    borderRadius: 1,
  },
  description: { fontSize: 10, lineHeight: 1.7, color: C.gray600 },

  categories: { flexDirection: 'row', flexWrap: 'wrap', gap: 6 },
  categoryTag: {
    backgroundColor: C.offWhite,
    paddingHorizontal: 10,
    paddingVertical: 4,
    borderWidth: 0.5,
    borderColor: C.gray200,
    borderRadius: 3,
  },
  categoryText: {
    fontSize: 7,
    color: C.gray600,
    fontWeight: 700,
    textTransform: 'uppercase',
    letterSpacing: 0.5,
  },

  footer: {
    position: 'absolute',
    bottom: 28,
    left: MARGIN,
    right: MARGIN,
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    paddingTop: 12,
    borderTopWidth: 2,
    borderTopColor: C.green,
  },
  footerText: {
    fontSize: 7,
    color: C.gray400,
    fontWeight: 400,
    textTransform: 'uppercase',
    letterSpacing: 0.8,
  },
  footerBrand: {
    fontSize: 9,
    fontWeight: 700,
    color: C.navyDeep,
    textTransform: 'uppercase',
    letterSpacing: 1.5,
  },

  kvGrid: { width: '100%', borderWidth: 1, borderColor: C.gray200 },
  kvRow: { flexDirection: 'row', borderBottomWidth: 1, borderBottomColor: C.gray200 },
  kvRowAlt: { backgroundColor: C.offWhite },
  kvRowLast: { borderBottomWidth: 0 },
  kvCell: { paddingVertical: 6, paddingHorizontal: 8 },
  kvMidDivider: { borderRightWidth: 1, borderRightColor: C.gray200 },
  kvLabelText: { fontSize: 8.5, fontWeight: 700, color: C.gray600 },
  kvValueText: { fontSize: 9.5, color: C.gray900 },

  tableWrap: { width: '100%', borderWidth: 1, borderColor: C.gray200, marginBottom: 14 },
  tableHeader: {
    width: '100%',
    flexDirection: 'row',
    backgroundColor: C.white,
    borderBottomWidth: 1,
    borderBottomColor: C.gray200,
  },
  tableHeaderCell: {
    paddingVertical: 5,
    paddingHorizontal: 4,
    fontSize: 6.6,
    fontWeight: 700,
    color: C.navyDeep,
  },
  tableHeaderCellCfg: { paddingHorizontal: 6 },
  tableHeaderCellDivider: { borderRightWidth: 1, borderRightColor: C.gray200 },
  tableRow: {
    width: '100%',
    flexDirection: 'row',
    borderBottomWidth: 1,
    borderBottomColor: C.gray200,
  },
  tableRowAlt: { backgroundColor: C.offWhite },
  tableCell: { paddingVertical: 4, paddingHorizontal: 4, fontSize: 6.6, color: C.gray900 },
  tableCellCfg: { paddingHorizontal: 6 },
  tableCellDivider: { borderRightWidth: 1, borderRightColor: C.gray200 },
});

interface ProductData {
  id: number;
  name: string;
  sku: string;
  categoriesLine?: string;
  descriptionText?: string;
  heroSrc?: string | null;
  productUrl?: string;
  shortDescriptionHtml?: string;
  descriptionHtml?: string;
  applicationHtml?: string;
  images?: string[];
  featuredImage?: string | null;
  categories?: Array<{ name: string }>;
  attributes?: Array<{ name: string; options: string[] }>;
}

export interface PDFDatasheetProps {
  product: ProductData;
  locale: 'en' | 'de';
  logoUrl?: string;
  technicalItems?: KeyValueItem[];
  voltageTables?: DatasheetVoltageTable[];
  legendItems?: KeyValueItem[];
}

const stripHtml = (html: string): string => html.replace(/<[^>]*>/g, '');

const getLabels = (locale: 'en' | 'de') =>
  ({
    en: {
      productDatasheet: 'Technical Datasheet',
      description: 'APPLICATION',
      specifications: 'TECHNICAL DATA',
      categories: 'CATEGORIES',
      sku: 'SKU',
      noImage: 'No image available',
      crossSection: 'Configurations',
      slug_cs: 'Cores & CS',
      abbreviations: 'ABBREVIATIONS',
    },
    de: {
      productDatasheet: 'Technisches Datenblatt',
      description: 'ANWENDUNG',
      specifications: 'TECHNISCHE DATEN',
      categories: 'KATEGORIEN',
      sku: 'ARTIKELNUMMER',
      noImage: 'Kein Bild verfügbar',
      crossSection: 'Konfigurationen',
      slug_cs: 'Adern & QS',
      abbreviations: 'ABKÜRZUNGEN',
    },
  })[locale];

function clamp(n: number, min: number, max: number) {
  return Math.max(min, Math.min(max, n));
}
function normTextForMeasure(v: unknown) {
  return String(v ?? '')
    .replace(/\s+/g, ' ')
    .trim();
}
function textLen(v: unknown) {
  return normTextForMeasure(v).length;
}

function distributeWithMinMax(
  weights: number[],
  total: number,
  minEach: number,
  maxEach: number,
): number[] {
  const n = weights.length;
  if (!n) return [];
  const mins = Array.from({ length: n }, () => minEach);
  const maxs = Array.from({ length: n }, () => maxEach);
  const minSum = mins.reduce((a, b) => a + b, 0);
  if (minSum > total) return mins.map((m) => m * (total / minSum));

  const result = mins.slice();
  let remaining = total - minSum;
  let remainingIdx = Array.from({ length: n }, (_, i) => i);

  while (remaining > 1e-9 && remainingIdx.length) {
    const wSum = remainingIdx.reduce((acc, i) => acc + Math.max(0, weights[i] || 0), 0);
    if (wSum <= 1e-9) {
      const even = remaining / remainingIdx.length;
      for (const i of remainingIdx) result[i] += even;
      remaining = 0;
      break;
    }
    const nextIdx: number[] = [];
    for (const i of remainingIdx) {
      const w = Math.max(0, weights[i] || 0);
      const add = (w / wSum) * remaining;
      const capped = Math.min(result[i] + add, maxs[i]);
      const used = capped - result[i];
      result[i] = capped;
      remaining -= used;
      if (result[i] + 1e-9 < maxs[i]) nextIdx.push(i);
    }
    remainingIdx = nextIdx;
  }
  const sum = result.reduce((a, b) => a + b, 0);
  const drift = total - sum;
  if (Math.abs(drift) > 1e-9) result[result.length - 1] += drift;
  return result;
}

function KeyValueGrid({ items }: { items: KeyValueItem[] }) {
  const filtered = (items || []).filter((i) => i.label && i.value);
  if (!filtered.length) return null;
  const rows: Array<[KeyValueItem, KeyValueItem | null]> = [];
  for (let i = 0; i < filtered.length; i += 2) rows.push([filtered[i], filtered[i + 1] || null]);

  return (
    <View style={styles.kvGrid}>
      {rows.map(([left, right], rowIndex) => {
        const isLast = rowIndex === rows.length - 1;
        const leftValue = left.unit ? `${left.value} ${left.unit}` : left.value;
        const rightValue = right ? (right.unit ? `${right.value} ${right.unit}` : right.value) : '';
        return (
          <View
            key={`${left.label}-${rowIndex}`}
            style={[
              styles.kvRow,
              rowIndex % 2 === 0 ? styles.kvRowAlt : null,
              isLast ? styles.kvRowLast : null,
            ]}
            wrap={false}
          >
            <View style={[styles.kvCell, { width: '23%' }]}>
              <Text style={styles.kvLabelText}>{left.label}</Text>
            </View>
            <View style={[styles.kvCell, styles.kvMidDivider, { width: '27%' }]}>
              <Text style={styles.kvValueText}>{leftValue}</Text>
            </View>
            <View style={[styles.kvCell, { width: '23%' }]}>
              <Text style={styles.kvLabelText}>{right?.label || ''}</Text>
            </View>
            <View style={[styles.kvCell, { width: '27%' }]}>
              <Text style={styles.kvValueText}>{rightValue}</Text>
            </View>
          </View>
        );
      })}
    </View>
  );
}

function DenseTable({
  table,
  firstColLabel,
}: {
  table: Pick<DatasheetVoltageTable, 'columns' | 'rows'>;
  firstColLabel: string;
}) {
  const cols = table.columns;
  const rows = table.rows;
  const headerText = (label: string) =>
    String(label || '')
      .replace(/\s+/g, '\u00A0')
      .trim();

  const cfgMin = 0.14,
    cfgMax = 0.23;
  const cfgContentLen = Math.max(
    textLen(firstColLabel),
    ...rows.map((r) => textLen(r.configuration)),
    8,
  );
  const dataContentLens = cols.map((c, ci) => {
    const headerL = textLen(c.label);
    let cellMax = 0;
    for (const r of rows) cellMax = Math.max(cellMax, textLen(r.cells[ci]));
    return Math.max(headerL * 1.15, cellMax, 3);
  });

  const cfgWeight = cfgContentLen * 1.05;
  const dataWeights = dataContentLens.map((l) => l);
  const dataWeightSum = dataWeights.reduce((a, b) => a + b, 0);
  const rawCfgPct = dataWeightSum > 0 ? cfgWeight / (cfgWeight + dataWeightSum) : 0.28;
  let cfgPct = clamp(rawCfgPct, cfgMin, cfgMax);

  const minDataPct =
    cols.length >= 14 ? 0.045 : cols.length >= 12 ? 0.05 : cols.length >= 10 ? 0.055 : 0.06;
  const cfgPctMaxForMinData = 1 - cols.length * minDataPct;
  if (Number.isFinite(cfgPctMaxForMinData)) cfgPct = Math.min(cfgPct, cfgPctMaxForMinData);
  cfgPct = clamp(cfgPct, cfgMin, cfgMax);

  const dataTotal = Math.max(0, 1 - cfgPct);
  const maxDataPct = Math.min(0.24, Math.max(minDataPct * 2.8, dataTotal * 0.55));
  const dataPcts = distributeWithMinMax(dataWeights, dataTotal, minDataPct, maxDataPct);

  const cfgW = `${(cfgPct * 100).toFixed(4)}%`;
  const dataWs = dataPcts.map((p, idx) => {
    if (idx === dataPcts.length - 1) {
      const used = dataPcts.slice(0, -1).reduce((a, b) => a + b, 0);
      const remainder = Math.max(0, dataTotal - used);
      return `${(remainder * 100).toFixed(4)}%`;
    }
    return `${(p * 100).toFixed(4)}%`;
  });

  const headerFontSize =
    cols.length >= 14 ? 5.7 : cols.length >= 12 ? 5.9 : cols.length >= 10 ? 6.2 : 6.6;

  return (
    <View style={styles.tableWrap} break={false}>
      <View style={styles.tableHeader} wrap={false}>
        <View style={{ width: cfgW }}>
          <Text
            style={[
              styles.tableHeaderCell,
              styles.tableHeaderCellCfg,
              { fontSize: headerFontSize, paddingHorizontal: 3 },
              cols.length ? styles.tableHeaderCellDivider : null,
            ]}
            wrap={false}
          >
            {headerText(firstColLabel)}
          </Text>
        </View>
        {cols.map((c, idx) => {
          const isLast = idx === cols.length - 1;
          return (
            <View key={c.key} style={{ width: dataWs[idx] }}>
              <Text
                style={[
                  styles.tableHeaderCell,
                  { fontSize: headerFontSize, paddingHorizontal: 3 },
                  !isLast ? styles.tableHeaderCellDivider : null,
                ]}
                wrap={false}
              >
                {headerText(c.label)}
              </Text>
            </View>
          );
        })}
      </View>
      {rows.map((r, ri) => (
        <View
          key={`${r.configuration}-${ri}`}
          style={[styles.tableRow, ri % 2 === 0 ? styles.tableRowAlt : null]}
          wrap={false}
          minPresenceAhead={16}
        >
          <View style={{ width: cfgW }} wrap={false}>
            <Text
              style={[
                styles.tableCell,
                styles.tableCellCfg,
                { fontSize: 6.2, paddingHorizontal: 3 },
                cols.length ? styles.tableCellDivider : null,
              ]}
              wrap={false}
            >
              {r.configuration}
            </Text>
          </View>
          {r.cells.map((cell, ci) => (
            <View key={`${cols[ci]?.key || ci}`} style={{ width: dataWs[ci] }} wrap={false}>
              <Text
                style={[
                  styles.tableCell,
                  ci !== r.cells.length - 1 ? styles.tableCellDivider : null,
                ]}
                wrap={false}
              >
                {cell}
              </Text>
            </View>
          ))}
        </View>
      ))}
    </View>
  );
}

export const PDFDatasheet: React.FC<PDFDatasheetProps> = ({
  product,
  locale,
  technicalItems = [],
  voltageTables = [],
  legendItems = [],
}) => {
  const labels = getLabels(locale);
  const description = stripHtml(
    product.applicationHtml ||
      product.shortDescriptionHtml ||
      product.descriptionHtml ||
      product.descriptionText ||
      '',
  );

  return (
    <Document>
      <Page size="A4" style={styles.page}>
        <View style={styles.hero}>
          <View style={styles.header}>
            <View>
              <Text style={styles.logoText}>KLZ</Text>
            </View>
            <Text style={styles.docTitle}>{labels.productDatasheet}</Text>
          </View>
          <View style={styles.productRow}>
            <View style={styles.productInfoCol}>
              <Text style={styles.productMeta}>
                {product.categoriesLine ||
                  (product.categories || []).map((c) => c.name).join(' • ')}
              </Text>
              <Text style={styles.productName}>{product.name}</Text>
            </View>
            <View style={styles.productImageCol}>
              {product.featuredImage ? (
                <Image src={product.featuredImage} style={styles.heroImage} />
              ) : (
                <Text style={styles.noImage}>{labels.noImage}</Text>
              )}
            </View>
          </View>
        </View>

        <View style={styles.content}>
          {description && (
            <View style={styles.section}>
              <Text style={styles.sectionTitle}>{labels.description}</Text>
              <View style={styles.sectionAccent} />
              <Text style={styles.description}>{description}</Text>
            </View>
          )}

          {technicalItems.length > 0 && (
            <View style={styles.section}>
              <Text style={styles.sectionTitle}>{labels.specifications}</Text>
              <View style={styles.sectionAccent} />
              <KeyValueGrid items={technicalItems} />
            </View>
          )}

          {voltageTables.map((table, idx) => (
            <View key={idx} style={styles.section} break={false}>
              <Text
                style={styles.sectionTitle}
              >{`${labels.crossSection} — ${table.voltageLabel}`}</Text>
              <View style={styles.sectionAccent} />
              <DenseTable table={table} firstColLabel={labels.slug_cs} />
            </View>
          ))}

          {legendItems.length > 0 && (
            <View style={styles.section} break={false}>
              <Text style={styles.sectionTitle}>{labels.abbreviations}</Text>
              <View style={styles.sectionAccent} />
              <KeyValueGrid items={legendItems} />
            </View>
          )}

          {!technicalItems.length &&
            !voltageTables.length &&
            product.attributes &&
            product.attributes.length > 0 && (
              <View style={styles.section}>
                <Text style={styles.sectionTitle}>{labels.specifications}</Text>
                <View style={styles.sectionAccent} />
                <View style={{ borderWidth: 1, borderColor: C.gray200 }}>
                  {product.attributes.map((attr, index) => (
                    <View
                      key={index}
                      style={{
                        flexDirection: 'row',
                        borderBottomWidth: index === product.attributes!.length - 1 ? 0 : 1,
                        borderBottomColor: C.gray200,
                        backgroundColor: index % 2 === 0 ? C.offWhite : C.white,
                      }}
                    >
                      <View
                        style={{
                          flex: 1,
                          padding: 6,
                          borderRightWidth: 1,
                          borderRightColor: C.gray200,
                        }}
                      >
                        <Text style={{ fontSize: 8.5, fontWeight: 700, color: C.gray600 }}>
                          {attr.name}
                        </Text>
                      </View>
                      <View style={{ flex: 1, padding: 6 }}>
                        <Text style={{ fontSize: 9.5, color: C.gray900 }}>
                          {attr.options.join(', ')}
                        </Text>
                      </View>
                    </View>
                  ))}
                </View>
              </View>
            )}
        </View>

        <View style={styles.footer} fixed>
          <Text style={styles.footerBrand}>KLZ CABLES</Text>
          <Text style={styles.footerText}>
            {new Date().toLocaleDateString(locale === 'en' ? 'en-US' : 'de-DE', {
              year: 'numeric',
              month: 'long',
              day: 'numeric',
            })}
          </Text>
        </View>
      </Page>
    </Document>
  );
};
