'use client';

import { useEffect, useState } from 'react';
import { Edit, Plus, Save, Trash2 } from 'lucide-react';
import DataTable from '@/components/ui/DataTable';
import ActionButton from '@/components/ui/ActionButton';
import Modal from '@/components/ui/Modal';
import ConfirmDialog from '@/components/ui/ConfirmDialog';
import {
  upgradePolicyApi,
  type UpgradePolicyCoachType,
  type UpgradePolicyRow,
  type UpgradePolicyValues,
} from '@/lib/api';

const EMPTY_POLICY: UpgradePolicyValues = {
  rank: 0,
  feePercent: 0,
  feeMinMinor: 0,
  feeWaived: false,
  isUpgradable: true,
  isTargetable: true,
  isActive: true,
};

// Money is entered in ETB and stored in minor units.
const etb = (minor: number) => String(minor / 100);
const toMinor = (value: string) => Math.round(Number(value || 0) * 100);
const feeLabel = (p: UpgradePolicyRow) =>
  p.feeWaived
    ? 'Waived'
    : p.feePercent > 0 || p.feeMinMinor > 0
      ? `${p.feePercent}% · min ETB ${etb(p.feeMinMinor)}`
      : 'Free';

/**
 * Policy US-17 — one upgrade policy per fare class (coach type), listed as a table and edited in
 * a dialog, the same shape as Reschedule Policies and Coach Management.
 */
export default function UpgradePolicyManager() {
  const [rows, setRows] = useState<UpgradePolicyRow[]>([]);
  const [available, setAvailable] = useState<UpgradePolicyCoachType[]>([]);
  const [loading, setLoading] = useState(true);
  const [message, setMessage] = useState('');

  const [showModal, setShowModal] = useState(false);
  const [editing, setEditing] = useState<UpgradePolicyRow | null>(null);
  const [coachTypeId, setCoachTypeId] = useState('');
  const [form, setForm] = useState<UpgradePolicyValues>(EMPTY_POLICY);
  const [saving, setSaving] = useState(false);
  const [formError, setFormError] = useState('');

  const [deleting, setDeleting] = useState<UpgradePolicyRow | null>(null);
  const [deleteBusy, setDeleteBusy] = useState(false);

  const load = async () => {
    setLoading(true);
    try {
      const [policies, coachTypes] = await Promise.all([
        upgradePolicyApi.list(),
        upgradePolicyApi.availableCoachTypes(),
      ]);
      setRows(Array.isArray(policies) ? policies : []);
      setAvailable(Array.isArray(coachTypes) ? coachTypes : []);
    } catch {
      setMessage('Failed to load upgrade policies.');
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    void load();
  }, []);

  const openCreate = () => {
    setEditing(null);
    setCoachTypeId('');
    // Suggest the next free rung rather than 0, which would clash with an existing policy.
    setForm({ ...EMPTY_POLICY, rank: Math.max(0, ...rows.map((r) => r.rank)) + 1 });
    setFormError('');
    setShowModal(true);
  };

  const openEdit = (row: UpgradePolicyRow) => {
    setEditing(row);
    setCoachTypeId(row.coachTypeId);
    setForm({
      rank: row.rank,
      feePercent: row.feePercent,
      feeMinMinor: row.feeMinMinor,
      feeWaived: row.feeWaived,
      isUpgradable: row.isUpgradable,
      isTargetable: row.isTargetable,
      isActive: row.isActive,
    });
    setFormError('');
    setShowModal(true);
  };

  const setField = (patch: Partial<UpgradePolicyValues>) => setForm((f) => ({ ...f, ...patch }));

  const submit = async () => {
    if (!editing && !coachTypeId) {
      setFormError('Pick a fare class.');
      return;
    }
    setSaving(true);
    setFormError('');
    try {
      if (editing) await upgradePolicyApi.update(editing.coachTypeId, form);
      else await upgradePolicyApi.create({ coachTypeId, ...form });
      setShowModal(false);
      setMessage(editing ? 'Policy updated.' : 'Policy created.');
      await load();
    } catch (err: any) {
      setFormError(err?.response?.data?.message || err?.message || 'Failed to save the policy.');
    } finally {
      setSaving(false);
    }
  };

  const confirmDelete = async () => {
    if (!deleting) return;
    setDeleteBusy(true);
    try {
      await upgradePolicyApi.remove(deleting.coachTypeId);
      setDeleting(null);
      setMessage('Policy deleted.');
      await load();
    } catch {
      setMessage('Failed to delete the policy.');
    } finally {
      setDeleteBusy(false);
    }
  };

  const columns = [
    {
      key: 'coachType',
      label: 'Fare class',
      render: (row: UpgradePolicyRow) => (
        <div>
          <span className="font-semibold text-foreground">{row.coachType?.code}</span>
          <span className="text-muted-foreground"> — {row.coachType?.name}</span>
        </div>
      ),
    },
    {
      key: 'rank',
      label: 'Rank',
      render: (row: UpgradePolicyRow) => <span className="font-mono text-sm">{row.rank}</span>,
    },
    {
      key: 'fee',
      label: 'Change fee',
      render: (row: UpgradePolicyRow) => <span className="text-sm">{feeLabel(row)}</span>,
    },
    {
      key: 'isUpgradable',
      label: 'Upgrade from',
      render: (row: UpgradePolicyRow) => (
        <span className={`edr-badge ${row.isUpgradable ? 'edr-badge-success' : 'edr-badge-warning'}`}>
          {row.isUpgradable ? 'Allowed' : 'No'}
        </span>
      ),
    },
    {
      key: 'isTargetable',
      label: 'Upgrade to',
      render: (row: UpgradePolicyRow) => (
        <span className={`edr-badge ${row.isTargetable ? 'edr-badge-success' : 'edr-badge-warning'}`}>
          {row.isTargetable ? 'Allowed' : 'No'}
        </span>
      ),
    },
    {
      key: 'isActive',
      label: 'Status',
      render: (row: UpgradePolicyRow) => (
        <span className={`edr-badge ${row.isActive ? 'edr-badge-success' : 'edr-badge-warning'}`}>
          {row.isActive ? 'Active' : 'Disabled'}
        </span>
      ),
    },
  ];

  const actions = [
    { label: 'Edit', onClick: openEdit, variant: 'secondary' as const, icon: Edit },
    {
      label: 'Delete',
      onClick: (row: UpgradePolicyRow) => setDeleting(row),
      variant: 'danger' as const,
      icon: Trash2,
    },
  ];

  return (
    <div className="space-y-4">
      <div className="flex items-start justify-between gap-4">
        <p className="text-xs text-muted-foreground max-w-3xl">
          Rank orders the ladder — a passenger may only move to a class with a higher rank, on the same train.
          Fee = max(fee % × the passenger&apos;s original fare, minimum), read from the class being upgraded
          <em> to</em> and charged per upgraded passenger. A fare class with no policy here can be neither
          upgraded from nor to.
        </p>
        <ActionButton icon={Plus} onClick={openCreate} disabled={available.length === 0}>
          Add Upgrade Policy
        </ActionButton>
      </div>

      {!loading && available.length === 0 && (
        <p className="text-xs text-muted-foreground">Every fare class already has a policy.</p>
      )}
      {message && <p className="text-sm text-muted-foreground">{message}</p>}

      <DataTable
        data={rows}
        columns={columns}
        actions={actions}
        loading={loading}
        emptyMessage="No upgrade policies yet — add one to allow fare-class upgrades."
      />

      <Modal
        isOpen={showModal}
        onClose={() => setShowModal(false)}
        title={editing ? `Edit Upgrade Policy — ${editing.coachType?.code}` : 'Add Upgrade Policy'}
        size="lg"
      >
        <div className="space-y-4">
          <div className="space-y-1">
            <label className="label">Fare class</label>
            {editing ? (
              <>
                <input
                  className="input"
                  value={`${editing.coachType?.code} — ${editing.coachType?.name}`}
                  disabled
                />
                <p className="text-xs text-muted-foreground">A policy stays attached to its fare class.</p>
              </>
            ) : (
              <select className="input" value={coachTypeId} onChange={(e) => setCoachTypeId(e.target.value)}>
                <option value="">Select a fare class...</option>
                {available.map((ct) => (
                  <option key={ct.id} value={ct.id}>
                    {ct.code} — {ct.name}
                  </option>
                ))}
              </select>
            )}
          </div>

          <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            <div className="space-y-1">
              <label className="label">Rank</label>
              <input
                type="number"
                min="0"
                className="input"
                value={form.rank}
                onChange={(e) => setField({ rank: Number(e.target.value) })}
              />
              <p className="text-xs text-muted-foreground">Higher beats lower. Must be unique among active policies.</p>
            </div>
            <div className="space-y-1">
              <label className="label">Change fee</label>
              <label className="flex items-center gap-2 text-sm h-10">
                <input
                  type="checkbox"
                  checked={form.feeWaived}
                  onChange={(e) => setField({ feeWaived: e.target.checked })}
                />
                Waived — charge only the fare difference
              </label>
            </div>
            <div className="space-y-1">
              <label className="label">Fee (% of original fare)</label>
              <input
                type="number"
                min="0"
                max="100"
                className="input"
                disabled={form.feeWaived}
                value={form.feePercent}
                onChange={(e) => setField({ feePercent: Number(e.target.value) })}
              />
            </div>
            <div className="space-y-1">
              <label className="label">Minimum fee (ETB)</label>
              <input
                type="number"
                min="0"
                step="0.01"
                className="input"
                disabled={form.feeWaived}
                value={etb(form.feeMinMinor)}
                onChange={(e) => setField({ feeMinMinor: toMinor(e.target.value) })}
              />
            </div>
            <div className="space-y-1">
              <label className="label">Upgrade from this class</label>
              <label className="flex items-center gap-2 text-sm h-10">
                <input
                  type="checkbox"
                  checked={form.isUpgradable}
                  onChange={(e) => setField({ isUpgradable: e.target.checked })}
                />
                Allowed
              </label>
            </div>
            <div className="space-y-1">
              <label className="label">Upgrade to this class</label>
              <label className="flex items-center gap-2 text-sm h-10">
                <input
                  type="checkbox"
                  checked={form.isTargetable}
                  onChange={(e) => setField({ isTargetable: e.target.checked })}
                />
                Allowed
              </label>
            </div>
            <div className="space-y-1">
              <label className="label">Status</label>
              <label className="flex items-center gap-2 text-sm h-10">
                <input
                  type="checkbox"
                  checked={form.isActive}
                  onChange={(e) => setField({ isActive: e.target.checked })}
                />
                Active
              </label>
            </div>
          </div>

          {formError && <p className="text-sm text-red-600 dark:text-red-400">{formError}</p>}

          <div className="flex justify-end gap-2 pt-2">
            <ActionButton variant="secondary" onClick={() => setShowModal(false)}>
              Cancel
            </ActionButton>
            <ActionButton icon={Save} onClick={submit} loading={saving}>
              {editing ? 'Update Policy' : 'Create Policy'}
            </ActionButton>
          </div>
        </div>
      </Modal>

      <ConfirmDialog
        isOpen={!!deleting}
        onClose={() => setDeleting(null)}
        onConfirm={confirmDelete}
        title="Delete upgrade policy"
        message={`Delete the upgrade policy for ${deleting?.coachType?.code ?? ''}?`}
        warning="Passengers will no longer be able to upgrade out of or into this fare class. Upgrades already applied are unaffected."
        confirmText="Delete"
        isDanger
        isLoading={deleteBusy}
      />
    </div>
  );
}
