"use client"

import Link from "next/link"
import { useMemo, useState } from "react"
import { Save, Send, Settings } from "lucide-react"

import { ListPageCard } from "@/app/dashboard/_components"
import { SettingsCard } from "@/components/settings/ui/settings-card"
import { Button } from "@/components/ui/button"
import { Checkbox } from "@/components/ui/checkbox"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { XmlApiErrorBanner } from "@/components/xml-apis/shared/xml-api-error-banner"
import type {
  BankFetchFailureSettings,
  IdLabelMap,
} from "@/components/xml-apis/bank-fetch-failures/types"
import { FRONTEND_ROUTES } from "@/config/frontend-routes"
import { dashboardCsrfHeader } from "@/lib/csrf.client"

type Props = {
  initialSettings: BankFetchFailureSettings
  bankApiOptions: IdLabelMap
  typeOptions: IdLabelMap
  initialErrorMessage?: string | null
}

const DEFAULT_TYPE_OPTIONS: IdLabelMap = {
  fetch: "Fetch fail",
  insert: "Insert fail",
}

export function BankFetchFailuresSettingsPage({
  initialSettings,
  bankApiOptions,
  typeOptions = {},
  initialErrorMessage = null,
}: Props) {
  const [settings, setSettings] = useState(initialSettings)
  const [selectedBankIds, setSelectedBankIds] = useState<number[]>(
    () => initialSettings.bank_api_ids || []
  )
  const [message, setMessage] = useState<string | null>(null)
  const [error, setError] = useState(initialErrorMessage)
  const [busy, setBusy] = useState(false)

  const bankRows = useMemo(() => {
    return Object.entries(bankApiOptions)
      .map(([id, label]) => ({ id: Number(id), label }))
      .filter((row) => row.id > 0)
      .sort((a, b) => a.label.localeCompare(b.label))
  }, [bankApiOptions])

  const failureTypeOptions = useMemo(() => {
    return Object.keys(typeOptions).length > 0 ? typeOptions : DEFAULT_TYPE_OPTIONS
  }, [typeOptions])

  async function persist(sendTest: boolean) {
    setBusy(true)
    setError(null)
    setMessage(null)
    try {
      const res = await fetch(FRONTEND_ROUTES.xmlApis.bankFetchFailures.settingsSubmit, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          ...dashboardCsrfHeader(),
        },
        body: JSON.stringify({
          save: 1,
          send_test: sendTest ? 1 : 0,
          bank_api_ids: selectedBankIds,
          notify_enabled: settings.notify_enabled,
          rocketchat_webhook_url: settings.rocketchat_webhook_url,
          notify_failure_types: settings.notify_failure_types,
        }),
      })
      const json = await res.json().catch(() => ({}))
      if (!res.ok || json.status === "error") {
        setError(json.message || "Save failed.")
        return
      }
      if (json?.data?.settings) {
        const next = json.data.settings as BankFetchFailureSettings
        setSettings((prev) => ({
          ...prev,
          ...next,
          notify_failure_types: Array.isArray(next.notify_failure_types)
            ? next.notify_failure_types
            : prev.notify_failure_types,
        }))
        if (Array.isArray(next.bank_api_ids)) {
          setSelectedBankIds(next.bank_api_ids.map((id) => Number(id)).filter(Boolean))
        }
      }
      setMessage(json.message || "Settings saved.")
    } finally {
      setBusy(false)
    }
  }

  return (
    <ListPageCard
      icon={Settings}
      title="Bank fetch & insert failures settings"
      description="Rocket.Chat alerts and monitored banks for daily fetch/insert accountability."
      breadcrumb={[
        { label: "XML API" },
        { label: "Bank fetch & insert failures", href: "/dashboard/xml-apis/bank-fetch-failures" },
        { label: "Settings" },
      ]}
      actions={
        <Link
          href="/dashboard/xml-apis/bank-fetch-failures"
          className="text-sm text-muted-foreground hover:text-foreground"
        >
          Back to calendar
        </Link>
      }
    >
      <XmlApiErrorBanner message={error} />
      {message ? (
        <p className="mb-4 rounded-md border border-emerald-200 bg-emerald-50 px-3 py-2 text-sm text-emerald-800">
          {message}
        </p>
      ) : null}

      <div className="grid w-full gap-6">
        <SettingsCard
          title="Notifications"
          description="Rocket.Chat alerts when the daily scan opens new fetch or insert failures."
        >
          <div className="space-y-5">
            <label className="flex items-start gap-2.5 rounded-md border px-3 py-2.5">
              <Checkbox
                checked={Boolean(settings.notify_enabled)}
                onCheckedChange={(checked) =>
                  setSettings((s) => ({ ...s, notify_enabled: checked === true ? 1 : 0 }))
                }
                className="mt-0.5"
              />
              <span className="text-sm leading-snug">
                <span className="font-medium">Enable notifications</span>
                <span className="mt-0.5 block text-xs text-muted-foreground">
                  Send Rocket.Chat messages when new failure rows are opened by scan
                </span>
              </span>
            </label>

            <div className="space-y-2">
              <Label htmlFor="bff-webhook">Rocket.Chat webhook URL</Label>
              <Input
                id="bff-webhook"
                type="url"
                placeholder="https://… (leave blank to use system.common.rocketchat_webhook_url)"
                value={settings.rocketchat_webhook_url}
                onChange={(e) =>
                  setSettings((s) => ({ ...s, rocketchat_webhook_url: e.target.value }))
                }
              />
              <p className="text-xs text-muted-foreground">
                Optional override. If empty, the global Rocket.Chat webhook is used.
              </p>
            </div>

            <div className="space-y-2">
              <Label>Notify for failure types</Label>
              <div className="grid gap-2 sm:grid-cols-2">
                {Object.entries(failureTypeOptions).map(([value, label]) => {
                  const id = `bff-type-${value}`
                  const checked = settings.notify_failure_types.includes(value)
                  return (
                    <label
                      key={value}
                      htmlFor={id}
                      className="flex cursor-pointer items-start gap-2.5 rounded-md border px-3 py-2.5"
                    >
                      <Checkbox
                        id={id}
                        checked={checked}
                        onCheckedChange={(on) =>
                          setSettings((s) => ({
                            ...s,
                            notify_failure_types:
                              on === true
                                ? s.notify_failure_types.includes(value)
                                  ? s.notify_failure_types
                                  : [...s.notify_failure_types, value]
                                : s.notify_failure_types.filter((t) => t !== value),
                          }))
                        }
                        className="mt-0.5"
                      />
                      <span className="text-sm">{label}</span>
                    </label>
                  )
                })}
              </div>
            </div>

            <div className="flex flex-wrap gap-2">
              <Button type="button" disabled={busy} onClick={() => void persist(false)}>
                <Save className="mr-1 h-4 w-4" />
                Save settings
              </Button>
              <Button
                type="button"
                variant="outline"
                disabled={busy}
                onClick={() => void persist(true)}
              >
                <Send className="mr-1 h-4 w-4" />
                Save & send test
              </Button>
            </div>
          </div>
        </SettingsCard>

        <SettingsCard
          title="Monitored banks"
          description="Which bank_api_id values the daily scan expects. Empty selection disables monitoring."
        >
          <div className="grid gap-2 sm:grid-cols-2 lg:grid-cols-3">
            {bankRows.map((row) => {
              const id = `bff-bank-${row.id}`
              const checked = selectedBankIds.includes(row.id)
              return (
                <label
                  key={row.id}
                  htmlFor={id}
                  className="flex cursor-pointer items-start gap-2.5 rounded-md border px-3 py-2.5"
                >
                  <Checkbox
                    id={id}
                    checked={checked}
                    onCheckedChange={(on) =>
                      setSelectedBankIds((prev) =>
                        on === true
                          ? prev.includes(row.id)
                            ? prev
                            : [...prev, row.id]
                          : prev.filter((x) => x !== row.id)
                      )
                    }
                    className="mt-0.5"
                  />
                  <span className="text-sm leading-snug">
                    <span className="font-medium">{row.label}</span>
                    <span className="mt-0.5 block text-xs text-muted-foreground">
                      ID {row.id}
                    </span>
                  </span>
                </label>
              )
            })}
          </div>
          <div className="mt-4 flex flex-wrap gap-2">
            <Button
              type="button"
              variant="outline"
              size="sm"
              disabled={busy}
              onClick={() => setSelectedBankIds(settings.default_bank_api_ids || [])}
            >
              Use defaults
            </Button>
            <Button
              type="button"
              variant="outline"
              size="sm"
              disabled={busy}
              onClick={() => setSelectedBankIds([])}
            >
              Clear all
            </Button>
            <Button type="button" size="sm" disabled={busy} onClick={() => void persist(false)}>
              <Save className="mr-1 h-4 w-4" />
              Save
            </Button>
          </div>
        </SettingsCard>
      </div>
    </ListPageCard>
  )
}
