import { useEffect, useState } from "react";
import axios from "axios";
import {
  Card,
  CardHeader,
  CardBody,
  Divider,
  Accordion,
  AccordionItem,
} from "@heroui/react";
import { useTranslation } from "react-i18next";
import { useContestStore } from "@/stores/contestStore";
import { useLanguageStore } from "@/stores/languageStore";
import LogQsoTable from "@/components/LogQsoTable";

type LogDetailData = {
  id: number;
  round_id: number;
  pcall?: string | null;
  rcall?: string | null;
  tname?: string | null;
  tdate?: string | null;
  pwwlo?: string | null;
  pexch?: string | null;
  psect?: string | null;
  pband?: string | null;
  pclub?: string | null;
  locator?: string | null;
  raw_header?: string | null;
  remarks?: string | null;
  remarks_eval?: string | null;
  claimed_qso_count?: number | null;
  claimed_score?: number | null;
  claimed_wwl?: string | null;
  claimed_dxcc?: string | null;
  round?: {
    id: number;
    contest_id: number;
    name: string;
    start_time?: string | null;
    end_time?: string | null;
    logs_deadline?: string | null;
  } | null;
  padr1?: string | null;
  padr2?: string | null;
  radr1?: string | null;
  radr2?: string | null;
  rpoco?: string | null;
  rcity?: string | null;
  rphon?: string | null;
  rhbbs?: string | null;
  rname?: string | null;
  rcoun?: string | null;
  mope1?: string | null;
  mope2?: string | null;
  stxeq?: string | null;
  srxeq?: string | null;
  sante?: string | null;
  santh?: string | null;
  power_watt?: number | null;
  rx_wwl?: string | null;
  rx_exchange?: string | null;
  mode_code?: string | null;
  new_exchange?: boolean | null;
  new_wwl?: boolean | null;
  new_dxcc?: boolean | null;
  duplicate_qso?: boolean | null;
  qsos?: {
    id: number;
    qso_index?: number | null;
    time_on?: string | null;
    dx_call?: string | null;
    my_rst?: string | null;
    my_serial?: string | null;
    dx_rst?: string | null;
    dx_serial?: string | null;
    rx_wwl?: string | null;
    rx_exchange?: string | null;
    mode_code?: string | null;
    new_exchange?: boolean | null;
    new_wwl?: boolean | null;
    new_dxcc?: boolean | null;
    duplicate_qso?: boolean | null;
    points?: number | null;
    remarks?: string | null;
  }[];
};

function formatDateTime(value: string | null | undefined, locale: string): string {
  if (!value) return "—";
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return value;
  return new Intl.DateTimeFormat(locale, {
    day: "2-digit",
    month: "2-digit",
    year: "numeric",
    hour: "2-digit",
    minute: "2-digit",
    hour12: false,
  }).format(date);
}

type LogDetailProps = {
  logId: number | null;
};

type LogResultItem = {
  id: number;
  log_id: number;
  official_score?: number | null;
  penalty_score?: number | null;
  base_score?: number | null;
  multiplier_count?: number | null;
  valid_qso_count?: number | null;
  dupe_qso_count?: number | null;
  busted_qso_count?: number | null;
  other_error_qso_count?: number | null;
};

type LogResultsResponse = {
  data: LogResultItem[];
};

type QsoResultItem = {
  log_qso_id: number;
  points?: number | null;
  penalty_points?: number | null;
  error_code?: string | null;
  error_side?: string | null;
  match_confidence?: string | null;
  match_type?: string | null;
  error_flags?: string[] | null;
  is_valid?: boolean | null;
  is_duplicate?: boolean | null;
  is_nil?: boolean | null;
  is_busted_call?: boolean | null;
  is_busted_rst?: boolean | null;
  is_busted_exchange?: boolean | null;
  is_time_out_of_window?: boolean | null;
};

type LogOverrideItem = {
  id: number;
  log_id: number;
  reason?: string | null;
};

type LogOverridesResponse = {
  data: LogOverrideItem[];
};

type QsoOverrideItem = {
  id: number;
  log_qso_id: number;
  forced_status?: string | null;
  forced_matched_log_qso_id?: number | null;
  forced_points?: number | null;
  forced_penalty?: number | null;
  reason?: string | null;
};

type LogQsoTableRow = {
  id: number;
  qso_index?: number | null;
  time_on?: string | null;
  dx_call?: string | null;
  my_rst?: string | null;
  my_serial?: string | null;
  dx_rst?: string | null;
  dx_serial?: string | null;
  rx_wwl?: string | null;
  rx_exchange?: string | null;
  mode_code?: string | null;
  new_exchange?: boolean | null;
  new_wwl?: boolean | null;
  new_dxcc?: boolean | null;
  duplicate_qso?: boolean | null;
  points?: number | null;
  remarks?: string | null;
  result?: QsoResultItem | null;
  override?: QsoOverrideItem | null;
};

type QsoTableResponse = {
  evaluation_run_id: number | null;
  data: LogQsoTableRow[];
};

export default function LogDetail({ logId }: LogDetailProps) {
  const { t } = useTranslation("common");
  const locale = useLanguageStore((s) => s.locale) || navigator.language || "cs-CZ";
  const setSelectedRound = useContestStore((s) => s.setSelectedRound);

  const [detail, setDetail] = useState<LogDetailData | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [officialResult, setOfficialResult] = useState<LogResultItem | null>(null);
  const [officialQsoResults, setOfficialQsoResults] = useState<Record<number, QsoResultItem>>({});
  const [officialLoading, setOfficialLoading] = useState(false);
  const [officialError, setOfficialError] = useState<string | null>(null);
  const [logOverrideReason, setLogOverrideReason] = useState<string | null>(null);
  const [qsoOverrides, setQsoOverrides] = useState<Record<number, QsoOverrideItem>>({});
  const [qsoTableRows, setQsoTableRows] = useState<LogQsoTableRow[]>([]);

  useEffect(() => {
    if (!logId) return;
    let active = true;
    (async () => {
      try {
        setLoading(true);
        setError(null);
        const res = await axios.get<LogDetailData>(`/api/logs/${logId}`, {
          params: { include_qsos: 0 },
          headers: { Accept: "application/json" },
          withCredentials: true,
        });
        if (!active) return;
        setDetail(res.data);
        if (res.data.round) {
          setSelectedRound({
            id: res.data.round.id,
            contest_id: res.data.round.contest_id,
            name: res.data.round.name,
            description: null,
            is_active: true,
            is_test: false,
            is_sixhr: false,
            start_time: res.data.round.start_time ?? null,
            end_time: res.data.round.end_time ?? null,
            logs_deadline: res.data.round.logs_deadline ?? null,
          });
        }
      } catch {
        if (!active) return;
        setError(t("unable_to_load_log") ?? "Nepodařilo se načíst log.");
      } finally {
        if (active) setLoading(false);
      }
    })();
    return () => {
      active = false;
    };
  }, [logId, t, setSelectedRound]);

  useEffect(() => {
    if (!detail?.id) return;
    let active = true;

    (async () => {
      try {
        setOfficialLoading(true);
        setOfficialError(null);
        const qsoTableRes = await axios.get<QsoTableResponse>(`/api/logs/${detail.id}/qso-table`, {
          headers: { Accept: "application/json" },
          withCredentials: true,
        });
        if (!active) return;

        const rows = qsoTableRes.data.data ?? [];
        setQsoTableRows(rows);

        const qsoMap: Record<number, QsoResultItem> = {};
        const overrideMap: Record<number, QsoOverrideItem> = {};
        rows.forEach((row) => {
          if (row.result) {
            qsoMap[row.id] = row.result;
          }
          if (row.override) {
            overrideMap[row.id] = row.override;
          }
        });
        setOfficialQsoResults(qsoMap);
        setQsoOverrides(overrideMap);

        const effectiveRunId = qsoTableRes.data.evaluation_run_id ?? null;
        if (!effectiveRunId) {
          setOfficialResult(null);
          setLogOverrideReason(null);
          return;
        }

        const resultRes = await axios.get<LogResultsResponse>("/api/log-results", {
          params: {
            evaluation_run_id: effectiveRunId,
            log_id: detail.id,
            per_page: 1,
          },
          headers: { Accept: "application/json" },
          withCredentials: true,
        });
        if (!active) return;
        setOfficialResult(resultRes.data.data?.[0] ?? null);

        const overrideRes = await axios.get<LogOverridesResponse>("/api/log-overrides", {
          params: {
            evaluation_run_id: effectiveRunId,
            log_id: detail.id,
            per_page: 1,
          },
          headers: { Accept: "application/json" },
          withCredentials: true,
        });
        if (!active) return;
        setLogOverrideReason(overrideRes.data.data?.[0]?.reason ?? null);
      } catch (e: any) {
        if (!active) return;
        const msg = e?.response?.data?.message || "Nepodařilo se načíst zkontrolované výsledky.";
        setOfficialError(msg);
        setOfficialResult(null);
        setOfficialQsoResults({});
        setLogOverrideReason(null);
        setQsoOverrides({});
        setQsoTableRows([]);
      } finally {
        if (active) setOfficialLoading(false);
      }
    })();

    return () => {
      active = false;
    };
  }, [detail?.id]);

  const title = (() => {
    const pcall = detail?.pcall ?? "";
    const rcall = detail?.rcall ?? "";
    if (pcall && rcall && pcall !== rcall) {
      return `${pcall}-${rcall}`;
    }
    return pcall || rcall || (t("log") ?? "Log");
  })();

  const renderRemarksEval = (raw: string | null | undefined) => {
    if (!raw) return "—";

    try {
      const parsed = JSON.parse(raw);
      if (Array.isArray(parsed)) {
        const lines = parsed
          .filter((item) => typeof item === "string" && item.trim() !== "")
          .map((item, idx) => <div key={idx}>{item}</div>);
        if (lines.length > 0) return lines;
      }
    } catch {
      // fallback to raw string
    }

    return <div>{raw}</div>;
  };

  return (
    <div className="space-y-4">
      <Card>
        <CardHeader>
          <div className="flex flex-col">
            <span className="text-lg font-semibold">{title}</span>
            {detail?.tname && (
              <span className="text-sm text-foreground-500">{detail.tname}</span>
            )}
            {detail?.tdate && (
              <span className="text-sm text-foreground-500">{detail.tdate}</span>
            )}
          </div>
        </CardHeader>
        <Divider />
        <CardBody>
          {error && <div className="text-sm text-red-600">{error}</div>}
          {loading && <div>{t("loading") ?? "Načítám..."}</div>}
          {detail && !loading && (
            <div className="space-y-4 text-sm">
              <div className="grid gap-4 md:grid-cols-2">
                <div className="space-y-2">
                  <div className="flex gap-2">
                    <span className="font-semibold" title={t("edi_pcall_hint") ?? "Call used during contest"}>
                      PCall:
                    </span>
                    <span>
                      {detail.pcall || "—"}
                      {detail.pclub ? ` (${detail.pclub})` : ""}
                    </span>
                  </div>
                  {detail.pband && (
                    <div className="flex gap-2">
                      <span className="font-semibold" title={t("edi_pband_hint") ?? "Band"}>PBand:</span>
                      <span>{detail.pband}</span>
                    </div>
                  )}
                  {detail.psect && (
                    <div className="flex gap-2">
                      <span className="font-semibold" title={t("edi_psect_hint") ?? "Section / category"}>PSect:</span>
                      <span>{detail.psect}</span>
                    </div>
                  )}
                  {detail.padr1 && (
                    <div className="flex gap-2">
                      <span className="font-semibold" title={t("edi_padr1_hint") ?? "Address line 1 (QTH)"}>PAdr1:</span>
                      <span>{detail.padr1}</span>
                    </div>
                  )}
                  {detail.padr2 && (
                    <div className="flex gap-2">
                      <span className="font-semibold" title={t("edi_padr2_hint") ?? "Address line 2 (QTH)"}>PAdr2:</span>
                      <span>{detail.padr2}</span>
                    </div>
                  )}
                  {detail.mope1 && (
                    <div className="flex gap-2">
                      <span className="font-semibold" title={t("edi_mope1_hint") ?? "Multi operator line 1"}>MOpe1:</span>
                      <span>{detail.mope1}</span>
                    </div>
                  )}
                  {detail.mope2 && (
                    <div className="flex gap-2">
                      <span className="font-semibold" title={t("edi_mope2_hint") ?? "Multi operator line 2"}>MOpe2:</span>
                      <span>{detail.mope2}</span>
                    </div>
                  )}
                  <div className="flex gap-2">
                    <span className="font-semibold" title={t("edi_rcall_hint") ?? "Responsible operator callsign"}>RCall:</span>
                    <span>{detail.rcall || "—"}</span>
                  </div>
                  {detail.radr1 && (
                    <div className="flex gap-2">
                      <span className="font-semibold" title={t("edi_radr1_hint") ?? "Address line 1 of responsible operator"}>RAdr1:</span>
                      <span>{detail.radr1}</span>
                    </div>
                  )}
                  {detail.radr2 && (
                    <div className="flex gap-2">
                      <span className="font-semibold" title={t("edi_radr2_hint") ?? "Address line 2 of responsible operator"}>RAdr2:</span>
                      <span>{detail.radr2}</span>
                    </div>
                  )}
                  {(detail.rpoco || detail.rcity) && (
                    <div className="flex gap-2">
                      <span className="font-semibold" title={t("edi_rpoco_rcity_hint") ?? "Postal code / city of responsible operator"}>RPoCo/RCity:</span>
                      <span>
                        {detail.rpoco ?? ""} {detail.rcity ?? ""}
                      </span>
                    </div>
                  )}
                  {detail.rcoun && (
                    <div className="flex gap-2">
                      <span className="font-semibold" title={t("edi_rcoun_hint") ?? "Country of responsible operator"}>RCoun:</span>
                      <span>{detail.rcoun}</span>
                    </div>
                  )}
                  {detail.rphon && (
                    <div className="flex gap-2">
                      <span className="font-semibold" title={t("edi_rphon_hint") ?? "Phone of responsible operator"}>RPhon:</span>
                      <span>{detail.rphon}</span>
                    </div>
                  )}
                  {detail.rhbbs && (
                    <div className="flex gap-2">
                      <span className="font-semibold" title={t("edi_rhbbs_hint") ?? "Home BBS of responsible operator"}>RHBBS:</span>
                      <span>{detail.rhbbs}</span>
                    </div>
                  )}
                </div>

                <div className="space-y-2">
                  {detail.stxeq && (
                    <div className="flex gap-2">
                      <span className="font-semibold" title={t("edi_stxeq_hint") ?? "TX equipment"}>STXEq:</span>
                      <span>{detail.stxeq}</span>
                    </div>
                  )}
                  {detail.srxeq && (
                    <div className="flex gap-2">
                      <span className="font-semibold" title={t("edi_srxeq_hint") ?? "RX equipment"}>SRXEq:</span>
                      <span>{detail.srxeq}</span>
                    </div>
                  )}
                {detail.power_watt && (
                  <div className="flex gap-2">
                    <span className="font-semibold" title={t("edi_spowe_hint") ?? "TX power [W]"}>SPowe:</span>
                    <span>{detail.power_watt}</span>
                  </div>
                )}
                {detail.sante && (
                  <div className="flex gap-2">
                    <span className="font-semibold" title={t("edi_sante_hint") ?? "Antenna"}>SAntenna:</span>
                    <span>{detail.sante}</span>
                  </div>
                  )}
                  {detail.santh && (
                    <div className="flex gap-2">
                      <span className="font-semibold" title={t("edi_santh_hint") ?? "Antenna height [m] / ASL [m]"}>SAntH:</span>
                      <span>{detail.santh}</span>
                    </div>
                  )}
                </div>
              </div>
              <Divider />
              <Divider />
              <div className="space-y-3">
                <div className="grid gap-4 md:grid-cols-2 text-sm">
                  <div className="space-y-1">
                    <h4 className="font-semibold">Deklarované výsledky</h4>
                    <div className="flex gap-2">
                      <span className="font-semibold">Počet QSO:</span>
                      <span>{detail.claimed_qso_count ?? "—"}</span>
                    </div>
                    <div className="flex gap-2">
                      <span className="font-semibold">Body:</span>
                      <span>{detail.claimed_score ?? "—"}</span>
                    </div>
                    <div className="flex gap-2">
                      <span className="font-semibold">Unikátních WWL:</span>
                      <span>{detail.claimed_wwl ?? "—"}</span>
                    </div>
                    <div className="flex gap-2">
                      <span className="font-semibold">Počet DXCC:</span>
                      <span>{detail.claimed_dxcc ?? "—"}</span>
                    </div>
                  </div>
                  <div className="space-y-1">
                    <h4 className="font-semibold">Zkontrolované výsledky</h4>
                    <div className="flex gap-2">
                      <span className="font-semibold">Počet QSO:</span>
                      <span>
                        {officialLoading ? "…" : officialResult?.valid_qso_count ?? "—"}
                      </span>
                    </div>
                    <div className="flex gap-2">
                      <span className="font-semibold">Body:</span>
                      <span>
                        {officialLoading ? "…" : officialResult?.official_score ?? "—"}
                      </span>
                    </div>
                    <div className="flex gap-2">
                      <span className="font-semibold">Unikátních WWL:</span>
                      <span>
                        {officialLoading ? "…" : officialResult?.multiplier_count ?? "—"}
                      </span>
                    </div>
                    <div className="flex gap-2">
                      <span className="font-semibold">Penalizace:</span>
                      <span>
                        {officialLoading ? "…" : officialResult?.penalty_score ?? "—"}
                      </span>
                    </div>
                    {officialError && (
                      <div className="text-xs text-red-600">{officialError}</div>
                    )}
                  </div>
                </div>
                {detail.remarks_eval && (
                  <div className="text-sm text-red-600">
                    {renderRemarksEval(detail.remarks_eval)}
                  </div>
                )}
                {detail.raw_header && (
                  <Accordion>
                    <AccordionItem
                      key="raw"
                      aria-label="RAW header"
                      title={<span className="cursor-pointer text-primary-600 hover:underline">RAW header</span>}
                    >
                      <pre className="bg-default-50 p-2 rounded text-xs whitespace-pre-wrap">
                        {detail.raw_header}
                      </pre>
                    </AccordionItem>
                  </Accordion>
                )}
              </div>
            </div>
          )}
        </CardBody>
      </Card>

      {(logOverrideReason || Object.keys(qsoOverrides).length > 0) && (
        <Card>
          <CardHeader>
            <span className="text-md font-semibold">Zásahy rozhodčího</span>
          </CardHeader>
          <Divider />
          <CardBody>
            <div className="text-sm text-foreground-600 space-y-2">
              {logOverrideReason && (
                <div>Log: {logOverrideReason}</div>
              )}
              {Object.keys(qsoOverrides).length > 0 && (
                <div className="space-y-1">
                  {qsoTableRows
                    .filter((qso) => qsoOverrides[qso.id]?.reason)
                    .map((qso) => (
                      <div key={qso.id}>
                        QSO #{qso.qso_index ?? qso.id}: {qso.dx_call ?? "—"} —{" "}
                        {qsoOverrides[qso.id]?.reason}
                      </div>
                    ))}
                </div>
              )}
            </div>
          </CardBody>
        </Card>
      )}

      <Card>
        <CardHeader>
          <span className="text-md font-semibold">QSO</span>
        </CardHeader>
        <Divider />
        <CardBody>
          <LogQsoTable
            key={`${detail?.id ?? "log"}-${qsoTableRows.length}-${Object.keys(qsoOverrides).length}-${Object.keys(officialQsoResults).length}`}
            qsos={qsoTableRows}
            locale={locale}
            formatDateTime={formatDateTime}
            officialQsoResults={officialQsoResults}
            qsoOverrides={qsoOverrides}
            emptyLabel={t("logs_empty") ?? "Žádné QSO záznamy."}
            callsign={title}
          />
        </CardBody>
      </Card>
    </div>
  );
}
